Open15

GlideとAirtableでデータ連携

ひろあきひろあき

すごい!連携した後にバッチ的な処理を組み込む必要があると思ってたけど、勝手に同期される。
ざっくりテストしてみたけど、だいたい10分ぐらい。

これ、やばいな。

ひろあきひろあき

どうやったらバッチ出来るんだろうと調べているうちに同期されててびっくりした。

ひろあきひろあき

ここから更に踏み込んで画像生成までチャレンジしてみる。

ひろあきひろあき

とりあえずスプレッドシートに情報を飛ばす。

改めて記載(メール送信はこれで出来る)
Create Automation>(トリガー)When record created>Tableは対象テーブル>(アクションの追加)GoogleSheet>Descriptionはこの操作のタイトル>アカウント等登録>シートの設定(ヘッダー必須)>飛ばすカラムの設定。

出来た!

【修正】
(トリガー)When record created
では、レコードが出来た瞬間にスプレッドシートと同期されるので、空欄が入ってしまう様子。
トリガーをWhen a record matches conditions
にすれば、任意のセルが埋まったときにスプレッドシートと更新出来る。

ひろあきひろあき

function requestImages() {
  // スクリプトプロパティに設定したOpenAIのAPIキーを取得
  const apiKey = PropertiesService.getScriptProperties().getProperty('YOUR_API_KEY'); // 'YOUR_API_KEY'の部分を、実際のAPIキーのプロパティ名に置き換えてください
  // 画像生成AIのAPIのエンドポイントを設定
  const apiUrl = 'https://api.openai.com/v1/images/generations';
  // 画像生成AIに投げるテキスト(プロンプト)を定義
  const prompt = '窓際で日向ぼっこして眠るネコ';
  // OpenAIのAPIリクエストに必要なヘッダー情報を設定
  let headers = {
    'Authorization': 'Bearer ' + apiKey,
    'Content-type': 'application/json',
    'X-Slack-No-Retry': 1
  };
  // 画像生成の枚数とサイズ、プロンプトをオプションに設定
  let options = {
    'muteHttpExceptions': true,
    'headers': headers,
    'method': 'POST',
    'payload': JSON.stringify({
      'n': 1,
      'size': '1024x1024',
      'prompt': prompt
    })
  };
  // OpenAIの画像生成(Images)にAPIリクエストを送り、結果を変数に格納
  const response = JSON.parse(UrlFetchApp.fetch(apiUrl, options).getContentText());
  console.log(JSON.stringify(response)); // レスポンスをログに表示
  // 生成された画像のURLにフェッチして画像データを取得して、名前をつける
  const image = UrlFetchApp.fetch(response.data[0].url).getAs('image/png').setName('DALL-E生成画像');
  // Googleドライブに画像を保存し、画像の保存先URLをログ出力
  const driveUrl = DriveApp.createFile(image).getUrl();
  console.log('Googleドライブ格納先:' + driveUrl);
}

何度やってもうまくいかない。
新しくAPIキー発行してやってみたところどうもAPIを叩けていない様子。

ひろあきひろあき

出来た!


const GPT_TOKEN = 'API_KEY';
const GPT_ENDPOINT = 'https://api.openai.com/v1/images/generations';
const FOLDER_ID = 'FOLDER_ID';

function myFunction() {
  createImage('セミの画像');
}

function createImage(prompt) {
  const headers = {
    'Authorization': 'Bearer ' + GPT_TOKEN,
    'Content-type': 'application/json',
  };
  // リクエストオプション
  const options = {
    'method': 'POST',
    'headers': headers,
    'payload': JSON.stringify({
      "prompt": prompt,
      "n": 4, // 画像を生成する枚数を設定(1~10)
      "size": "1024x1024"
    })
  };
  // HTTPリクエストでChatGPTのAPIを呼び出す
  const res = JSON.parse(UrlFetchApp.fetch(GPT_ENDPOINT, options).getContentText());
  let image_url = '';

  for (i = 0; i < res['data'].length; i++) {

    image_url = res['data'][i]['url'];

    let blob = UrlFetchApp.fetch(image_url).getBlob();
    let fileBlob = blob.setName(prompt + '_' + i);

    let folder = DriveApp.getFolderById(FOLDER_ID)
    folder.createFile(fileBlob)
  }
}

ひろあきひろあき

ドライブに格納された画像のURLはそのままGlideでも表示できるので、そこのURLをAirtableの任意の場所に持っていきたい。

まずは画像URLをB列の最終行に入れたい。

これで出来た

const GPT_TOKEN = 'API_KEY';
const GPT_ENDPOINT = 'https://api.openai.com/v1/images/generations';
const FOLDER_ID = 'FOLDER_ID';

function myFunction() {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  const promptCellAddress = sheet.getRange("C1").getValue(); // C1セルの値を取得(例: "A7")
  const prompt = sheet.getRange(promptCellAddress).getValue(); // C1セルに記載されたセルの値(例: A7セルの値)を取得
  const destinationCellAddress = sheet.getRange("D1").getValue(); // D1セルの値を取得(例: "B15")
  createImage(prompt, destinationCellAddress, sheet); // セルの値をプロンプトとして渡す
}

function createImage(prompt, destinationCellAddress, sheet) {
  const headers = {
    'Authorization': 'Bearer ' + GPT_TOKEN,
    'Content-type': 'application/json',
  };
  // リクエストオプション
  const options = {
    'method': 'POST',
    'headers': headers,
    'payload': JSON.stringify({
      "prompt": prompt,
      "n": 1, // 画像を生成する枚数を設定(1~10)
      "size": "1024x1024"
    })
  };
  // HTTPリクエストでChatGPTのAPIを呼び出す
  const res = JSON.parse(UrlFetchApp.fetch(GPT_ENDPOINT, options).getContentText());
  let image_url = '';

  for (i = 0; i < res['data'].length; i++) {
    image_url = res['data'][i]['url'];

    let blob = UrlFetchApp.fetch(image_url).getBlob();
    let fileBlob = blob.setName(prompt + '_' + i);

    let folder = DriveApp.getFolderById(FOLDER_ID)
    const imageFile = folder.createFile(fileBlob);

    // 保存された画像のURLを指定されたセルに記録する
    const imageUrlCell = sheet.getRange(destinationCellAddress);
    imageUrlCell.setValue(imageFile.getUrl());
  }
}
ひろあきひろあき

A列が更新されたときに動くようにトリガーを設定

後はB列のURLをAirtableに転記出来ればOK
Zapierでいけそうだからとりあえずやってみる。

同期は出来たけど、MAX15分かかるみたい。これはあまりつかえないなー。
他の方法ないかな。

ひろあきひろあき

色々調べたけど、うまくいかない。

URLは取得出来てるけどthumbnailカラムの一番最初の空白に入力する。というところがうまく動かない。
なぜか毎回15行目が上書きされる。