5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

GASでLINE WorksのAI Botを動かす【2025/12/03時点】

5
Posted at

はじめに

最近自由研究でLINE WorksのBotを作ってみたのですが、情報が乱立していて、情報の探索に手間取ったので備忘的に残しておきます。
あくまでAIを経由してのBotとの会話ができるようになるまでの基本的なものです。
また、詳細な手順を書いておきます。エンジニアでない方がLINE WorksのAI Botを作る際、わかりやすいものになっているといいなと思います。

技術要素

  • Google AI Studio
  • LineWorks Developer Console
  • LineWorks Admin
  • GAS

完成イメージ

GASコード

動作させるまでの手順

Developer Console

1. Bot画面を表示

image.png

2. 画面右上部の「登録」ボタンを押下し、新規作成画面を表示する

image.png

3. Botを作成

適当な内容でBotを一旦保存、作成します。

image.png

作成されたBotの詳細画面では、Bot Id、Bot Secretの確認が可能です。

4. APIアプリの作成

image.png

API > ClientAppから、適当なアプリを作成してください。

image.png

ここでの、Client ID、Client Secret、Service Account(作成が必要です)、Private Keyは後程必要となります。必要となります。

Google AI Studio

API Keyを作成する

API Keysの画面から、GeminiをAPI経由で使えるキーを発行できます。

image.png

PJ名、Key名などは自分が分かるものであれば適当で構いません。
作成したAPI Keyをコピーしておいてください。

GAS

1. GASのホームにアクセス

2. 新しいプロジェクトを作成

image.png

こんな感じのエディタ画面に遷移します。ここがワークスペースとなります。

3. コードを貼り付け

以下のコードをコード.gsの内容に貼り付けてください。
GPTから生成したものになります。

/**
 * LINE WORKS AI Chat Bot (Gemini)
 *
 * セットアップ:
 * 1. Script Properties に以下を登録:
 *    CLIENT_ID, CLIENT_SECRET, SERVICE_ACCOUNT, PRIVATE_KEY,
 *    SCOPES, BOT_ID, DOMAIN_ID, ADMIN_ID, GEMINI_API_KEY
 *
 * 2. LINE WORKS Console で Callback URL を設定:
 *    https://script.google.com/macros/s/{SCRIPT_ID}/usercontent/doPost
 *
 * 3. Bot の動作:
 *    - ユーザーから送られてきたテキストを Gemini に投げて、
 *      返ってきたテキストをそのまま返信する「AIチャットボット」
 */

// ===== Script Properties から認証情報を取得 =====
function getEnv() {
  var props = PropertiesService.getScriptProperties()
  var privateKey = props.getProperty('PRIVATE_KEY')

  // 改行を正規化(\n 文字列 → 実改行)
  if (privateKey && privateKey.indexOf('\\n') !== -1) {
    privateKey = privateKey.replace(/\\n/g, '\n')
  }

  var env = {
    CLIENT_ID: props.getProperty('CLIENT_ID'),
    CLIENT_SECRET: props.getProperty('CLIENT_SECRET'),
    SERVICE_ACCOUNT: props.getProperty('SERVICE_ACCOUNT'),
    PRIVATE_KEY: privateKey,
    DOMAIN_ID: props.getProperty('DOMAIN_ID'),
    ADMIN_ID: props.getProperty('ADMIN_ID'),
    BOT_ID: props.getProperty('BOT_ID'),
    SCOPES: props.getProperty('SCOPES'),
    GEMINI_API_KEY: props.getProperty('GEMINI_API_KEY'),
  }

  // バリデーション
  var missing = []
  for (var key in env) {
    if (!env[key]) missing.push(key)
  }

  if (missing.length > 0) {
    throw new Error('Script Properties 不足: ' + missing.join(', '))
  }

  return env
}

/**
 * Gemini API を呼び出してテキスト返信を取得
 *
 * @param {string} userText ユーザーから届いたテキスト
 * @param {Object} env      getEnv() で取得した環境変数
 * @returns {string} Gemini からの返信テキスト
 */
function callGemini(userText, env) {
  if (!env.GEMINI_API_KEY) {
    return '❌ GEMINI_API_KEY が設定されていません。管理者に確認してください。'
  }

  var url =
    'https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent'

  // 単純な1ターン会話
  var payload = {
    contents: [
      {
        parts: [
          {
            text: userText,
          },
        ],
      },
    ],
    // 好きならここで systemInstruction を付けてもOK
    // systemInstruction: {
    //   parts: [{ text: 'You are a helpful assistant for LINE WORKS order bot.' }],
    // },
  }

  var options = {
    method: 'post',
    contentType: 'application/json',
    headers: {
      'x-goog-api-key': env.GEMINI_API_KEY, // 公式サンプルと同じやり方 
    },
    payload: JSON.stringify(payload),
    muteHttpExceptions: true,
  }

  try {
    var response = UrlFetchApp.fetch(url, options)
    var text = response.getContentText()
    var data = JSON.parse(text)

    if (data.error) {
      Logger.log('Gemini API error: ' + JSON.stringify(data.error))
      return (
        '❌ AIからの応答取得中にエラーが発生しました: ' +
        (data.error.message || '不明なエラー')
      )
    }

    if (data.candidates && data.candidates.length > 0) {
      var parts = (data.candidates[0].content && data.candidates[0].content.parts) || []
      var texts = []

      for (var i = 0; i < parts.length; i++) {
        if (parts[i].text) {
          texts.push(parts[i].text)
        }
      }

      if (texts.length > 0) {
        return texts.join('\n')
      }
    }

    return '❌ AIからの応答を取得できませんでした。'
  } catch (e) {
    Logger.log('Gemini API exception: ' + e)
    return '❌ AIとの通信中にエラーが発生しまし

また、認証については、以下の記事の方の作られたライブラリを使用しています。
下記の章の手順が必須となりますので、忘れずお願いいたします。

4. 環境変数を設定

先のコードのこの部分です。

 * セットアップ:
 * 1. Script Properties に以下を登録:
 *    CLIENT_ID, CLIENT_SECRET, SERVICE_ACCOUNT, PRIVATE_KEY,
 *    SCOPES, BOT_ID, DOMAIN_ID, ADMIN_ID, GEMINI_API_KEY

GEMINI_API_KEYに先ほどコピーしたAPI Keyを設定しておきます。

image.png

image.png

ほかの値も同様です。

5. デプロイ

image.png

画面右上のデプロイボタンからデプロイを実行します。
種類、設定は画像のように行います。

image.png

デプロイが完了すると、ウェブアプリのURLが表示されるのでコピーしてください。

再度、Developer Console

先ほど作成したBotのCallback URLに、コピーしたウェブアプリのURLを設定し保存してください。

image.png

Line Works Admin

image.png

image.png

Botの追加から、先ほど作ったBotをチェックします。

image.png

使用権限、公開の設定の変更を忘れずに。

動作の確認

image.png

トーク先の選択に作成したBotが表示されています。

image.png

5
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?