8
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【0からGASを学ぶ】GAS × Gemini Pro API × LINE Messaging API によるあなただけの相談Botを作成する【決定版】

Last updated at Posted at 2023-12-28

はじめに

本シリーズでは、GASの始め方や便利な使い方、ビジネス活用まで幅広く解説します。シリーズをひと通り読んでいただければ、あなたもきっとGASマスターになれるはずです。

シリーズの対象者

  • そもそもGASってなんだかわからない
  • GASを学びたいけど何から始めればいいかわからない方
  • GASはわかり始めたけど、もっと活用ができないかと模索している方
  • とにかくGoogleが好き! という方

前回記事

Gemini Pro API をGASからアクセスする

では早速始めていきましょう。【0からGASを学ぶ】シリーズの第15回は「GAS × Gemini Pro API × LINE Messaging API によるあなただけの相談Botを作成する」です。前回は、GASからGemini Pro APIを呼び出すまでを行いました。今回はさらにLINEとつなぎ、LINEにメッセージを送るとGeminiが回答を返してくれるという夢のBotを作成していきましょう。LINE Messaging APIを使うための準備がそれなりにあるのですが、順々に説明しますのでご安心ください!最終的なイメージはこんな感じです。
015_032.PNG

今回やること

  1. LINE Messaging APIを使うための準備
  2. GAS上でLINE Messaging APIに値を返却
  3. LINE Messaging APIGASをつなぐ「Webhook設定」
  4. Gemini Pro APIの返答をLINE Messaging APIに返却

やることを見るとわかる通り、メインはLINE Messaging APIの使い方です。なぜなら、Gemini Pro APIからの返答は前回時点で受け取れてますから、あとはどうやってLINEに返すかだけです。

STEP.1 LINE Messaging APIを使うための準備

※以下はLINE Developersに未登録の方を前提に手順を示しています。そのため、すでにアカウントをお持ちの方は、それをお使いの上、手順No.8から実施してください。

手順 イメージ
1 以下のログイン用URLにアクセスして、「アカウントを作成」をクリックします。
https://account.line.biz/login?redirectUri=https%3A%2F%2Fdevelopers.line.biz%2Fconsole%2F
2 「メールアドレスで登録」をクリックします。
3 ご自身のメールアドレスを入力のうえ「登録用のリンクを送信」をクリックします。
4 No.3で入力したメールアドレス宛に登録用リンクが送られてくるため、メール内の「登録画面に進む」または「登録用リンク」をクリックします。
5 登録画面が開くため、[名前]と[パスワード]を入力し「登録」をクリックします。
6 「サービスに移動」をクリックします。
7 開発者情報の登録画面が開くため、[開発者名]と[メールアドレス]を入力し「アカウントを作成」をクリックします。
※この辺りからめちゃくちゃ登録させられるなとげんなりしてきます。
8 無事にDeveloper登録が完了しました。次にプロバイダー登録を行うため「新規プロバイダー作成」をクリックします。
9 [プロバイダー名]を入力し「作成」をクリックします。
10 プロバイダーの管理コンソールに遷移します。ここで「Messaging API」をクリックします。
11 新規チャネル作成画面に遷移するため、必要最低限の入力項目([所在地]、[チャネル名]、[チャネル説明]、[大業種]、[小業種])を入力し「作成」をクリックします。
※なお、ここで登録した内容もあとで変更することは可能であるため考えすぎずに。
12 内容を確認し「OK」をクリックします。
13 情報利用に関する同意事項を確認し「同意する」をクリックします。
14 個人規約に関する同意事項を確認し「同意する」をクリックします。
15 作成したチャネルの管理画面に遷移するため「Messaging API 設定」をクリックします。
16 [QRコード]欄にLINEの友だち追加用のQRコードがあるため、これをスマホで読み込みLINEで友だち追加しておきましょう。
※これはあとからでも構いませんが、先に作成したLINEボットにつなげてみましょう。

17 [チャネルアクセストークン]欄の「発行」をクリックします。
※このトークンがLINE Messaging APIにつなぐためのキーとなります。発行後はトークンをコピーしておいてください。

なお、あと(STEP.3)でLINE Developerには戻ってきますので、ページは閉じずに残しておいてください。

2023年12月時点での登録手順となるため、画面遷移等が若干異なる場合がございます。予めご了承ください。

STEP.2 GAS上でLINE Messaging APIに値を返却

今回もスタンドアロン型でGASを記述していきます。こちらを参考にGASエディタを起動してください。では、どんどんいきますよ、ついてきてください。少々長丁場となりますので、予めご了承ください。

STEP.2-1 まずは仕様を確認

LINE Messaging APIは仕様も日本語でばっちり公開されてますので、自分がやりたいことをうまく探し当てることができれば、比較的簡単に実装が可能です。例えば、今回の実装で必要なことは以下の2点です。

  1. ユーザからメッセージが送信された場合にGASでその情報を受け取る
  2. GASからユーザに対してメッセージを送信する

①ユーザからメッセージが送信された場合にGASでその情報を受け取る

これにはWebhookという仕組みを使います。

と、新しい言葉を登場させましたが、WebhookとAPIは目的としては同じです。いずれも異なるシステムやアプリケーション間で情報のやり取りを行う仕組みです。主たる違いは、Webhookは特定のイベント発生時(リクエストが不要なことも)に実行され、APIはリクエストすることで実行され応答を受け取ることができます。

この仕組みを用いることで、LINE上でユーザがメッセージを送信すると、LINEからWebhook先(これがGASでデプロイ時に発行されるURL)にPOSTされ、GASで情報を受け取ることが可能になります。

WebhookによりGASが受け取る情報:イベントオブジェクトの中には、以下のような情報が含まれています。

イベントオブジェクトの中身抜粋
{
  "destination": "xxxxxxxxxx",
  "events": [
    {
      "type": "message",
      "message": {
        "type": "text",
        "id": "14353798921116",
        "text": "Hello, world"
      },
      "source": {
        "type": "user",
        "userId": "U80696558e1aa831..."
      },
      "replyToken": "757913772c4646b784d4b7ce46d12671",
    }
  ]
}

この中で、今回使用するのは、events->messege->typeevents->messege->textevents->replyTokenの3つです。

②GASからユーザに対してメッセージを送信する

これにはLINEの応答メッセージを使います。応答メッセージはその名の通りですが、ユーザからのメッセージに対して返信する際に使用します。

curlによる呼び出し
curl -v -X POST https://api.line.me/v2/bot/message/reply \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer {channel access token}' \
-d '{
    "replyToken":"nHuyWiB7yP5Zw52FIkcQobQuGDXCTA",
    "messages":[
        {
            "type":"text",
            "text":"Hello, user"
        },
        {
            "type":"text",
            "text":"May I help you?"
        }
    ]
}'

これを見ると、以下のことがわかります。

項目
Fetch先のURL https://api.line.me/v2/bot/message/reply
method種別 POST
データ種別 application/json
認証 Bearer {channel access token}
データ本体 {
  "replyToken":"nHuyWiB7yP5Zw52FIkcQobQuGDXCTA",
  "messages":[
    {
      "type":"text",
      "text":"Hello, user"
    }
  ]
}

"replyToken":"nHuyWiB7yP5Zw52FIkcQobQuGDXCTA"の箇所はサンプルで記載されているものであり、実際はLINEから受信したイベントデータ内に入っているevents->.replyTokenを使います。

STEP.2-2 ではこの仕様を踏まえてGASで実装する

LINE Messaging APIのreplayメソッド部
const REPLY_URL     = 'https://api.line.me/v2/bot/message/reply';
const LINEAPI_TOKEN = '**STEP.1のNo.17で取得したチャネルアクセストークンを記載する**';

/**
 * LINEのトークでメッセージが送信された際に起動するメソッド
 * @param {EventObject} e - イベントオブジェクト
 */
function doPost(e){
  // イベントデータはJSON形式となっているため、parseして取得
  const eventData = JSON.parse(e.postData.contents).events[0]
        , repToken = eventData.replyToken;
  replyTxt(repToken, `LINEへの返信確認`);
}

/**
 * LINEのトークにメッセージを返却するメソッド
 * @param {String} token - メッセージ返却用のtoken
 * @param {String} text - 返却テキスト
 */
function replyTxt(token, txt){
  const message = {
                    'replyToken' : token,
                    'messages' : [{
                      'type': 'text',
                      'text': txt
                    }]
                  }
        , options = {
                    'method' : 'post',
                    'headers' : {
                      'Content-Type': 'application/json; charset=UTF-8',
                      'Authorization': 'Bearer ' + LINEAPI_TOKEN,
                    },
                    'payload' : JSON.stringify(message)
                  };
  UrlFetchApp.fetch(REPLY_URL, options);
}

いかがでしょうか。LINEのAPI仕様をもとにGASで表現しました。

  • doPostでイベントオブジェクトを受信し、応答メッセージに必要なreplyTokenを取得
  • replyTokenを用いて、https://api.line.me/v2/bot/message/replyにFetch

これでGAS側のプログラムはできました。次にLINE Messaging APIでWebhook登録するために、作成したプログラムをデプロイします。

doPostはGAS上でPOSTリクエストを受け取るための特殊な関数であるためメソッド名称固定になります。
お気づきの通り、doPostに対してdoGetももちろんありますが、これはGASでWebアプリケーションを作ろう編の際に詳しくお伝えします。

STEP.2-3 GASをデプロイ

GASでdoPostを記述したとしてもデプロイしたURLが払い出されないと誰もGASに対してPOSTリクエストを送ることができません。そのため、先ほど記載したプログラムをデプロイしましょう。

手順 イメージ
1 GASエディタから「デプロイ ▼」をクリックします。
2 「新しいデプロイ」をクリックします。
3 デプロイ管理ダイアログが表示されるため、やや左上の歯車をクリックします。
4 「ウェブアプリ」をクリックします。
5
  • [新しい説明文]:適当に記載
  • [次のユーザとして実行]:自分
  • [アクセスできるユーザ]:全員
と設定し「デプロイ」をクリックします。
6 「アクセスを承認」をクリックします。
※このあと、GASからGmail送信やスプレッドシートにアクセスする際にも出た権限設定が表示されます。ここでは割愛しますが、ご不明な点はこちらを確認してください。
7 デプロイが完了したら、[ウェブアプリ]欄に記載のURLをコピーします。

STEP.3 LINE Messaging APIとGASをつなぐ「Webhook設定」

ここからは再びLINE Developer側の設定です。

手順 イメージ
1 [Webhook設定]欄の「編集」をクリックします。
2 [Webhook URL]にSTEP.2-3 No.7で取得したURLを設定し「更新」をクリックします。
3 GASでデプロイしたURLが機能するかどうかを検証のため「検証」をクリックします。
※URLに誤りがなければ成功ダイアログが表示されます。

4 [Webhookの利用]欄の「ラジオボタン」をクリックして活性状態にします。
5 ページ下段の[応答メッセージ]欄の「編集」をクリックします。
6 LINE Official Account Managerで[応答メッセージ]欄および[応答時間]欄のラジオボタンをクリックして非活性状態にします。

お待たせしました【確認】

STEP.2-2から2-3、およびSTEP.3を行うことで、

  1. ユーザからメッセージが送信された場合にGASでその情報を受け取る
  2. GASからユーザに対してメッセージを送信する

が実現できるようになりました。それでは、改めてSTEP1のNo.16で友だちになったLINEアカウントに文字を送信してください。以下のように返ってくるはずです。

この「LINEへの返信確認」はまさに

function doPost(e){
  // イベントデータはJSON形式となっているため、parseして取得
  const eventData = JSON.parse(e.postData.contents).events[0]
        , repToken = eventData.replyToken;
  replyTxt(repToken, `LINEへの返信確認`);
}

ここで設定した値ですね。

もし思った通りの返信が来ない場合は、STEP.2-2から2-3、およびSTEP.3をもう一度見返して異なる箇所がないかを確認してください。

STEP.4 Gemini Pro APIの返答をLINE Messaging APIに返却

ここからはもうだいぶ簡単です。前回の記事でお伝えしたGemini Pro APIの呼び出しを組み合わせれば完成です。
要は、以下のreplyTxtで返却している「LINEへの返信確認」を固定文字列ではなく、Geminiからの返却値にすればいいだけです。

function doPost(e){
  // イベントデータはJSON形式となっているため、parseして取得
  const eventData = JSON.parse(e.postData.contents).events[0]
        , repToken = eventData.replyToken;
  replyTxt(repToken, `LINEへの返信確認`);
}

それではやってみましょう。

Qiita015
const GEMINI_API      = '**前回記事のSTEP.1のNo.5で取得したAPI keyを記載する**'
      , REPLY_URL     = 'https://api.line.me/v2/bot/message/reply'
      , LINEAPI_TOKEN = '**STEP.1のNo.17で取得したチャネルアクセストークンを記載する**';

/**
 * LINEのトークでメッセージが送信された際に起動するメソッド
 * @param {EventObject} e - イベントオブジェクト
 */
function doPost(e){
  // イベントデータはJSON形式となっているため、parseして取得
  const eventData = JSON.parse(e.postData.contents).events[0]
        , repToken = eventData.replyToken
        , msgType = eventData.message.type;
  // テキストメッセージのときのみ
  if (msgType=='text') {
    let uText = eventData.message.text
        , gemini = getGeminiProAnswerTxt(uText);
    replyTxt(repToken, gemini);
  }
}

/**
 * LINEのトークに送信されたメッセージをGemini Pro APIに渡して回答を得るメソッド
 * @param {String} txt - 送信されたメッセージ
 */
function getGeminiProAnswerTxt(txt) {
  const url = `https://generativelanguage.googleapis.com/v1beta/models/gemini-pro:generateContent?key=${GEMINI_API}`
        , payload = {
            'contents': [
              {
                'parts': [{
                  'text': txt
                }]
              }
            ]
          }
        , options = {
            'method': 'post',
            'contentType': 'application/json',
            'payload': JSON.stringify(payload)
          };

  const res = UrlFetchApp.fetch(url, options)
        , resJson = JSON.parse(res.getContentText());

  if (resJson && resJson.candidates && resJson.candidates.length > 0) {
    return resJson.candidates[0].content.parts[0].text;
  } else {
    return '回答を取得できませんでした。';
  }
}

/**
 * LINEのトークにメッセージを返却するメソッド
 * @param {String} token - メッセージ返却用のtoken
 * @param {String} text - 返却テキスト
 */
function replyTxt(token, txt){
  const message = {
                    'replyToken' : token,
                    'messages' : [{
                      'type': 'text',
                      'text': txt
                    }]
                  }
        , options = {
                    'method' : 'post',
                    'headers' : {
                      'Content-Type': 'application/json; charset=UTF-8',
                      'Authorization': 'Bearer ' + LINEAPI_TOKEN,
                    },
                    'payload' : JSON.stringify(message)
                  };
  UrlFetchApp.fetch(REPLY_URL, options);
}

ここでのポイントは以下の2つです。

  1. LINEからのメッセージ送信がテキストのときのみ、その入力テキストをGeminiに送る
    msgType = eventData.message.type;
    uText = eventData.message.text;
    // これもWebhookのイベントオブジェクトに記載の通りに取得しています。
    
  2. Geminiは入力されたテキストをパラメタに設定したうえでFetchし、返却値をLINEへ返す

メッセージタイプがテキスト以外(画像や位置情報)の場合はGeminiの入力パラメタを作成できないためこのようにしています。
※ただし、画像の場合はGemini Pro Visionもあるため、あくまでも今回はという前提です。

デプロイの更新

プログラムの修正が終わったら、再デプロイしましょう。

デプロイ方法を誤るとデプロイされたURLが変わってしまうので、必ず以下の手順に従ってください。
※URLが変わるとLINE Developer側の設定も変更しなければなりません。

手順 イメージ
1 「デプロイを管理」をクリックします。
2 デプロイ管理ダイアログが表示されるため、やや右上の鉛筆マークをクリックします。
3 [バージョン]に新バージョンを選択し「デプロイ」をクリックします。

確認

…は、ぜひお手持ちのスマホで実施してみてください。お楽しみに!

おわりに

お疲れ様でした。
第15回は「GAS × Gemini Pro API × LINE Messaging API によるあなただけの相談Botを作成する」ということで、LINE Messaging APIを利用するための準備から、GASとLINEをつなぐための手順、さらにそこにGemini Proを組み合わせるとかなり盛りだくさんにやってきました。GASはなんでもできる! と述べていたのがかなり実感してきたのでは!?引き続き、GASを楽しんでいきましょう!!
記事を読んで、「良いな」や「今後に期待できる!」と感じて頂けたらいいねフォローコメントいただけると幸いです。それではまた次回をお楽しみに!

ブログでより詳しく解説しています!

以下画像をクリックしてブログにアクセス!!

実はまだこれでおわりではない。

今回の相談Botのままでは、会話の継続が実現できていません。例えば、

  • 東京の魅力を教えて?

とBotに聞くと、Geminiはすごい量の情報を教えてくれます。そこで、続けて

  • すごいね、じゃあそれを200字程度で要約して?

とBotに聞くと、会話の継続ができていないため、東京の魅力を要約することはなく、まったく別の回答が返ってきます。

さぁこれをどうするか。次回を乞うご期待!!!!

8
9
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
8
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?