• 投稿カテゴリー:GAS / 技術 / 開発
  • 投稿の最終変更日:12月 25, 2024

GASからGeminiにプロンプトを送信して回答を得てみる。

GAS側

メインコード

const API_ENDPOINT = "YOUR_API_ENDPOINT";
const PROJECT_ID = "YOUR_PROJECT_ID";
const GEMINI_MODEL_ID = "YOUR_GEMINI_MODEL_ID";
const LOCATION_ID = "YOUR_LOCATION_ID";

// GEMINIのエンドポイント
const GEMINI_ENDPOINT = `https://${API_ENDPOINT}/v1/projects/${PROJECT_ID}/locations/${LOCATION_ID}/publishers/google/models/${GEMINI_MODEL_ID}:streamGenerateContent`;

/**
 * プロンプトをセットする関数
 * @param {string} prompt - ユーザーからのプロンプト
 * @returns {object} リクエストペイロード
 */
function setPrompt(prompt) {
  return {
    "contents": [
      {
        "role": "user",
        "parts": [
          {
            "text": prompt
          }
        ]
      }
    ],
    "systemInstruction": {
      "parts": [
        {
          "text": "あなたは日本語話者のユーモアあふれるウェブライターです。プロンプトから与えられるお題から記事を作成してください。マークダウン形式で出力。適切に見出しをつけること。閲覧者が読みやすいように文体や、段落、テーブルなどを必要に応じて工夫すること。画像挿入推奨位置に画像タグを挿入すること(画像は人間が後ほど置き換える。また、出典を明示するキャプションをつける。)。20代がターゲット、若者に親しみやすい文章だが幼稚さがないように感嘆符や疑問符は多用しないこと。軽いネットスラングを用いても良い。"
        }
      ]
    },
    "generation_config": {
      "maxOutputTokens": 8192,
      "temperature": 1,
      "topP": 0.95,
      "seed": 0
    },
    "safetySettings": [
      {
        "category": "HARM_CATEGORY_HATE_SPEECH",
        "threshold": "OFF"
      },
      {
        "category": "HARM_CATEGORY_DANGEROUS_CONTENT",
        "threshold": "OFF"
      },
      {
        "category": "HARM_CATEGORY_SEXUALLY_EXPLICIT",
        "threshold": "OFF"
      },
      {
        "category": "HARM_CATEGORY_HARASSMENT",
        "threshold": "OFF"
      }
    ]
  };
}

/**
 * OAuth トークンを取得する関数
 * @returns {string} OAuth トークン
 */
function getToken() {
  return ScriptApp.getOAuthToken();
}

/**
 * Vertex AI の GEMINI モデルを呼び出してテキスト生成を行う関数
 * @param {string} text - ユーザーからのプロンプト
 * @returns {object} Vertex AI からのレスポンスデータ
 */
function callGemini(text) {
  const token = getToken();
  const headers = {
    "Authorization": `Bearer ${token}`,
    "Content-Type": "application/json"
  };

  const payload = setPrompt(text);

  const options = {
    "method": "POST",
    "headers": headers,
    "payload": JSON.stringify(payload),
    "muteHttpExceptions": true
  };

  const response = UrlFetchApp.fetch(GEMINI_ENDPOINT, options);
  const responseData = JSON.parse(response.getContentText());

  return responseData;
}

/**
 * Vertex AI からのレスポンスデータを抽出する関数
 * @param {object} data - Vertex AI からのレスポンスデータ
 * @returns {string} 抽出されたテキスト
 */
function extractResponseData(data) {
  return data.map(item => item.candidates[0].content.parts[0].text).join("");
}

/**
 * メイン関数:プロンプトを送信してレスポンスを取得し、結果をログに出力する
 */
function run() {
  const text = "皆既日食について600文字程度で記事を書いてください。"; // ここに実際のプロンプトを入力します
  const response = callGemini(text);
  const responseContent = extractResponseData(response);
  Logger.log(responseContent);
}

appsscript.jsonにoauthScopesを追記してください。

{
  "timeZone": "Asia/Tokyo",
  "dependencies": {},
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8",
  "oauthScopes": [
    "https://www.googleapis.com/auth/cloud-platform",
    "https://www.googleapis.com/auth/cloud-platform.read-only",
    "https://www.googleapis.com/auth/script.external_request"
  ]
}