LINEによるAI顧客サポートチャットボット~LINEで質問⇒GAS⇒質問からAI回答⇒GAS⇒LINEで回答⇒スプレッドシートに保存~

ステップ項目作業内容のポイント所要時間
全体フローシステム概要顧客のLINE質問をGASで受信し、Gemini APIで回答生成。結果をLINE返信&スプレッドシート記録
1. LINE準備Messaging API設定LINE Developersでチャネル作成。チャネルID・シークレット・アクセストークンの3点をメモ。15分
2. GAS準備器の作成スプレッドシートを作成しシートIDをコピー。拡張機能からApps Scriptを起動。10分
3. Gemini準備APIキー取得Google AI StudioでAPIキーを発行・コピーする。5分
4. セキュリティスクリプトプロパティGASの「プロジェクト設定」にて、取得した4つの機密情報(キーと値)を安全に保存。5分
5. 実装コードの貼り付け提供されたセキュア版コードをエディタへ。APIキーを直接書かずプロパティから呼び出す構造。5分
6. 公開デプロイ設定GASを「ウェブアプリ」としてデプロイ。発行されたWebhook URLをLINE側の管理画面に登録。10分
7. 運用テスト・確認実機LINEから質問し、自動返信とシートへの記録が正常に行われるかチェック。5分

プロンプト

AI顧客サポートチャットボット LINE経由で顧客からの問い合わせを受け取り、Geminiが自動で回答。社員が対応できない時間帯や複雑な質問もAIが処理します。対応内容はスプレッドシートに記録され、パターン分析も可能です。 役立つ点:24時間対応で顧客満足度UP、営業時間外の対応工数を削減 作成したいです、ステップごとに教えてください

    全体フロー図

    顧客がLINEで質問
        ↓
    GAS が Webhook で受信
        ↓
    スクリプトプロパティから API キーなどを取得(安全)
        ↓
    Gemini API に質問を送信
        ↓
    Gemini が回答を生成
        ↓
    LINE で顧客に自動返信
        ↓
    スプレッドシートに記録(分析用)
    

    ステップ1:LINEの準備(15分)

    1-1. LINE公式アカウント(ビジネス向け)を作成

    • LINE Developers にアクセス
    • 「新規作成」から 「Messaging API」 を選択
    • チャネル名:例「〇〇カスタマーサポート」

    1-2. 重要な情報をメモしておく

    LINEの管理画面で、以下の 3つの情報をコピーします(次のステップで使います)

    ❶ チャネルID:(数字のみ)
    ❷ チャネルシークレット:(英数字混在)
    ❸ チャネルアクセストークン:(長い英数字)
    

    どこにあるか: LINE Developers → あなたのチャネル → 「基本設定」タブ


    ステップ2:Google GAS の準備(10分)

    2-1. Googleスプレッドシートを作成

    • Google Drive を開く
    • 新規 → スプレッシート
    • シート名を「問い合わせ記録」に変更

    2-2. スプレッドシートのIDをコピー

    • URLの以下の部分がID です
    https://docs.google.com/spreadsheets/d/【ここがID】/edit
    

    このID は次のステップで使います

    2-3. Google Apps Script を開く

    • スプレッドシート内で「拡張機能」→ 「Apps Script」
    • 新しいタブで Google Apps Script エディタ が開きます

    ステップ3:Gemini API の準備(5分)

    3-1. API キーを取得

    • Google AI Studio にアクセス
    • 「Create API Key」をクリック
    • API キーをコピー(次のステップで使います)

    ステップ4:機密情報をスクリプトプロパティに保存(重要)

    4-1. GAS の「プロジェクト設定」を開く

    GAS エディタの 左側メニュー から「⚙️ プロジェクト設定」をクリック

    4-2. スクリプトプロパティに保存

    1. 「スクリプトプロパティを編集」をクリック
    2. 4つの行 を以下のように入力します
    キー
    GEMINI_API_KEYさっき取得した Gemini API キー
    SHEET_IDスプレッドシートのID
    LINE_CHANNEL_SECRETLINE チャネルシークレット
    LINE_ACCESS_TOKENLINE チャネルアクセストークン

    例:

    キー:GEMINI_API_KEY
    値:AIzaSyDp5HK-...(実際のキー)
    
    キー:SHEET_ID
    値:1a2b3c4d5e6f7g...(実際のID)
    
    キー:LINE_CHANNEL_SECRET
    値:abcdef123456...
    
    キー:LINE_ACCESS_TOKEN
    値:Channel access token ...
    
    1. 「保存」をクリック

    重要: ここで保存した情報は、スクリプト内には見えません。GAS が安全に管理します。


    ステップ5:GAS にコードを書く(セキュア版)

    Google Apps Script エディタの コード.gs に、以下のコードを すべて貼り付けます

    // ===== スクリプトプロパティから機密情報を安全に取得 =====
    function getProperties() {
      const props = PropertiesService.getScriptProperties();
      return {
        geminiApiKey: props.getProperty('GEMINI_API_KEY'),
        sheetId: props.getProperty('SHEET_ID'),
        lineChannelSecret: props.getProperty('LINE_CHANNEL_SECRET'),
        lineAccessToken: props.getProperty('LINE_ACCESS_TOKEN')
      };
    }
    
    // ===== LINE Webhook 受け取り =====
    function doPost(e) {
      const props = getProperties();
    
      if (!props.geminiApiKey || !props.sheetId || !props.lineAccessToken) {
        Logger.log("エラー:スクリプトプロパティが未設定です");
        return ContentService.createTextOutput("ERROR: Properties not configured");
      }
    
      const body = JSON.parse(e.postData.contents);
      const events = body.events;
    
      for (const event of events) {
        if (event.type === "message" && event.message.type === "text") {
          const userId = event.source.userId;
          const userMessage = event.message.text;
          const timestamp = new Date();
    
          const aiResponse = getGeminiResponse(userMessage, props.geminiApiKey);
          sendLineMessage(userId, aiResponse, props.lineAccessToken);
          logToSheet(userMessage, aiResponse, timestamp, props.sheetId);
        }
      }
    
      return ContentService.createTextOutput("OK");
    }
    
    // ===== Gemini API を呼び出す =====
    function getGeminiResponse(userMessage, apiKey) {
      const url = "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent";
    
      const payload = {
        contents: [
          {
            parts: [
              {
                text: userMessage
              }
            ]
          }
        ]
      };
    
      const options = {
        method: "post",
        contentType: "application/json",
        payload: JSON.stringify(payload),
        muteHttpExceptions: true
      };
    
      try {
        const response = UrlFetchApp.fetch(url + "?key=" + apiKey, options);
        const result = JSON.parse(response.getContentText());
    
        if (result.candidates && result.candidates.length > 0) {
          return result.candidates[0].content.parts[0].text;
        } else {
          return "申し訳ございません。回答を生成できませんでした。";
        }
      } catch (error) {
        Logger.log("Gemini API エラー: " + error);
        return "システムエラーが発生しました。しばらくしてからお試しください。";
      }
    }
    
    // ===== LINE に返信 =====
    function sendLineMessage(userId, message, accessToken) {
      const url = "https://api.line.me/v2/bot/message/push";
    
      const payload = {
        to: userId,
        messages: [
          {
            type: "text",
            text: message
          }
        ]
      };
    
      const options = {
        method: "post",
        headers: {
          "Authorization": "Bearer " + accessToken,
          "Content-Type": "application/json"
        },
        payload: JSON.stringify(payload),
        muteHttpExceptions: true
      };
    
      try {
        UrlFetchApp.fetch(url, options);
      } catch (error) {
        Logger.log("LINE 送信エラー: " + error);
      }
    }
    
    // ===== スプレッドシートに記録 =====
    function logToSheet(question, response, timestamp, sheetId) {
      try {
        const sheet = SpreadsheetApp.openById(sheetId).getActiveSheet();
        sheet.appendRow([
          timestamp,
          question,
          response,
          "自動回答"
        ]);
      } catch (error) {
        Logger.log("スプレッドシート記録エラー: " + error);
      }
    }
    // ★★★ 権限承認用テスト関数 ★★★
    function testAuthorizeSpreadsheet() {
      const spreadsheetId = "1h1IR6I6bC2VYXQ7aQnkcOTPfehgMBKFweUmVWtR_5pw";  // ← これでOK!
      
      const ss = SpreadsheetApp.openById(spreadsheetId);
      const sheet = ss.getActiveSheet();
      
      sheet.appendRow(["テスト承認成功", new Date()]);
      console.log("✅ 承認成功!スプレッドシート名: " + ss.getName());
    }

    コードの説明

    • 1~11行目:スクリプトプロパティから機密情報を安全に取得
    • 13~36行目:LINE の Webhook を受け取る
    • 38~68行目:Gemini API を呼び出す
    • 70~92行目:LINE に返信する
    • 94~103行目:スプレッドシートに記録する

    スクリプトに直接キーを書いていません。すべてプロパティから取得しています。


    ステップ6:Webhook URL を設定(10分)

    6-1. Google Apps Script をデプロイ

    1. GAS エディタで「デプロイ」をクリック
    2. 「新しいデプロイ」→ 種類:「ウェブアプリ」
    3. 「実行者」:自分のアカウント
    4. 「アクセス」:「全員」 を選択
    5. 「デプロイ」をクリック

    6-2. Webhook URL をコピー

    • デプロイ完了後、表示される デプロイID をコピー
    • 以下の形式の URL を作成します
    https://script.google.com/macros/d/{デプロイID}/usercontent/publish
    

    6-3. LINE Developer で Webhook URL を登録

    1. LINE Developers を開く
    2. あなたのチャネル → 「Messaging API設定」タブ
    3. 「Webhook URL」の欄に、さっき作った URL を貼り付け
    4. 「保存」をクリック

    ステップ7:テスト&運用(5分)

    7-1. 実際に動作確認

    1. LINE で自分の公式アカウントを友だち追加
    2. テスト質問を送ってみる(例:「営業時間は何時から?」)
    3. AI が自動で返信するか確認

    7-2. スプレッドシートで記録確認

    • 「問い合わせ記録」シートに、質問と回答が記録されているか確認

    7-3. ログで問題をデバッグ(必要な場合)

    GAS エディタで「実行ログ」をクリックすると、エラーメッセージが見られます


    よくある問題と対策

    問題原因解決策
    LINEから返信がないスクリプトプロパティが未設定ステップ4を再確認
    「システムエラー」と返ってくるGemini API キーが無効API キーを再取得し、プロパティを更新
    スプレッドシートに記録されないSHEET_ID が間違っているステップ4 のプロパティを確認

    セキュリティのポイント

    このやり方のメリット

    • API キーがスクリプト内に見えない
    • 複数人で共有しても機密情報が漏れない
    • キーを変更するときは、プロパティを変更するだけ

    顧客からの想定質問への回答をスプレッドシートに保管し、参照させることで24時間対応の独自のLINEチャットボット(Q&A)が完成します。
    例えば、営業時間、料金、おすすめ、参考情報・・・・
    回答内容は随時追加することがポイントです。