概要
- Google Spreadsheet + Google Apps ScriptだけでFacebook Messenger botを作ります。
- サーバーを立てる必要はありません。しかも運用費用はゼロ円です。
- とりあえずコピペで動きます。操作するのはスプレッドシートだけなので、非エンジニアでもできます(たぶん)
はじめに
Google Spreadsheet/Google Apps Scriptとは
Google Spreadsheet(スプレッドシート)は、Google Drive上で使えるExcelみたいなものです。スプレッドシートにはGoogle Apps Script(通称GAS)というものがついていて、JavaScriptでいろいろと自動化できたり何かと便利です。
それに加えて、APIとして解放することで簡易サーバーのような動きもできます。今回はこの機能を利用して、SpreadsheetをFB Messenger botのバックエンドとして使い、botを構築してみます。
注意
**Google Apps for Workのアカウントだとできません。**個人アカウントを使いましょう。
後述するdoGet
/doPost
が呼べないようです。
GASを使うメリット
まず、無料です。これが一番。
あと、前回Facebook Messenger Botの作り方 〜AWS Lambda(Serverless)での構築〜という記事を書いたのですが、これはハードルが高いよと思う方にオススメです。本格的に運用するならAWSなりherokuなりをバックエンドとして使うべきですが、本格的なビジネス用途でなければスプレッドシート/GASで十分かなと思います。
そして、GASからはスプレッドシートのシートを簡単に操作できるので、例えばシートに「このテキストが来たら、これを返す」という定義を列挙できます。これはただのExcel的なものなので、エンジニアでなくても簡単に編集できます。
導入方法
1. Facebook Developerの設定
まず、こちらの記事を参考に、「1.Facebookページの作成・アプリの登録」の手順を行って下さい。そこまでの手順はバックエンドを何にしようが同じです。
発行されるページアクセストークンは後で使うので、忘れずにメモしておきましょう(ブログなど人が見える所に公開しないように気をつけて下さい!)
2. GASの編集
まず、使用するスプレッドシートに、以下の画像のように行を追加します。 今回はA列に書いた単語にヒットしたとき、B列の単語を返すようにプログラムを組みました。つまりユーザーが「test」とメッセージを送ると、「てすとです」と返します。
次のステップで使うので、スプレッドシートのIDをメモしておきましょう。URLのランダム文字列になっている部分がIDです。
次に、[ツール] => [スクリプトエディタ]でGASの編集画面に移ります。
するとスクリプトの編集画面が出てくるので、そこに下記のコードをコピペします。変更する箇所は3つだけで、
-
PAGE_ACCESS_TOKEN
の値にFacebookDeveloperから取得したページアクセストークンを設定 -
SHEET_ID
に先ほどメモしたスプレッドシートのIDを設定 -
SHEET_NAME
に最初に行を追加したシートの名前(デフォルトならシート1
)を設定
var PAGE_ACCESS_TOKEN = 'ここにFacebook Developerから取得したページアクセストークンを貼り付け';
var SHEET_ID = 'ここにスプレッドシートのIDを貼り付け';
var SHEET_NAME = 'シート1';
function doGet(e) {
var validRequest = e.parameter['hub.verify_token'] === PAGE_ACCESS_TOKEN;
var res = validRequest ? e.parameter['hub.challenge'] : 'Invalid Request';
return ContentService.createTextOutput(res).setMimeType(ContentService.MimeType.TEXT);
}
function doPost(e) {
var params = JSON.parse(e.postData.contents);
var messagingEvents = params.entry[0].messaging;
messagingEvents.forEach(function(event) {
if (event.message && event.message.text) {
sendHttpPost(event.sender.id, findResponse(event.message.text));
}
});
return ContentService.createTextOutput("OK").setMimeType(ContentService.MimeType.TEXT);
}
function findResponse(word) {
debug(word);
return getData().reduce(function(memo, row) { return memo || (row.key === word && row.value); }, false) || undefined;
}
function getData() {
var sheet = SpreadsheetApp.openById(SHEET_ID).getSheetByName(SHEET_NAME);
var data = sheet.getDataRange().getValues();
return data.map(function(row) { return {key: row[0], value: row[1]}; });
}
function sendHttpPost(sender, text) {
UrlFetchApp.fetch('https://graph.facebook.com/v2.6/me/messages?access_token=' + PAGE_ACCESS_TOKEN, {
method : 'POST',
contentType : 'application/json',
payload : JSON.stringify({
recipient: {
id: sender
},
message: {
text: text || '見つかりませんでした'
}
})
});
}
function debug(text) {
var sheet = SpreadsheetApp.openById(SHEET_ID).getSheetByName('debug');
sheet.appendRow([text]);
}
function test() {
Logger.log(findResponse("hoge"));
}
ここまで出来たら保存しましょう。
3. APIの公開
APIとして公開する前に、test
関数を一度実行しておきましょう。その時に認証画面が表示されますが、**これを一度パスしておかないとAPIを実行しても謎のエラーになります。**気をつけましょう。
このような承認画面が出てくるので、[許可を確認]をクリックし、その後出てくる認証画面でもOKを選択します。
次はAPIとして公開する手順です。[公開] => [ウェブアプリケーションとして導入]を選択します。
下記のような画面が出てくるので、[次のユーザーとしてアプリケーションを実行]を自分、[アプリケーションにアクセスできるユーザー]を**全員(匿名ユーザーを含む)**にして、[導入]をクリックします。
これにてスプレッドシート側の設定は終わりです。URLが発行されるので、これをメモしておきましょう。
4.Messengerの設定
またFacebook Developersのページに戻り、Webhooksの設定画面から[Setup Webhooks]を選択します。
[コールバックURL]の欄に先ほど発行されたスプレッドシートのAPIのURLを、[トークンを確認]の欄には最初に作ったページアクセストークンを設定します。[mesages]にのみチェックを入れて、[確認して保存]です。とくにエラーが出ずに終了したら完璧です。
あとはFacebookページに対してメッセージを送れば、設定したものが返ってきます!!!
Tips
doGet/doPost
GASの最初に書いてあるdoGet()
とdoPost()
という関数が、APIとして外から呼ばれる関数です。引数のe
にパラメータやら色々入ってきて、ContentService.createTextOutput()
でレスポンスを返します。今回はFacebook Messenger Botの仕様上、テキストレスポンスを使用していますが、ContentService.MimeType.JSON
を指定することでJSONを返すことも可能です。
デバッグ関数
GASにはLogger.log()
というロギング関数がありますが、どうやらこれはdoGet()などが外部から呼ばれたときは記録されないようです(たぶん)。そのため、下記のようなデバッグ関数を作成して、ログを別シートに書きだして検証しました。
function debug(text) {
var sheet = SpreadsheetApp.openById(SHEET_ID).getSheetByName('debug');
sheet.appendRow([text]);
}
何でもできます
言ってもJavaScriptなので、割りとなんでもできます。UrlFetchApp.fetch
でAjaxRequestも飛ばせますので外部サービスとの連携も可能です(こいつ同期で結果が返ってくるのですが...)。あとはGoogle CalenderとかGoogle系のサービスとの連携もGASのAPIを使うと簡単ですね。botで自分のカレンダーの予定を公開するとかも簡単だと思います(誰得)。
注意
- GASを更新したら、再度[ウェブアプリケーションとして導入]でプロジェクトバージョンを新規作成して公開してください。
- パフォーマンスは期待しないでください。遅めです。
- GASは実行制限(1日当たり何回まで実行可能、というやつ)あったはずです。詳細は忘れましたが...
参考
- Messenger Platform - Getting Started
- Google Apps Scriptを使って簡易APIをサクッと作る
- Facebook Messenger Botの作り方 〜AWS Lambda(Serverless)での構築〜
レポジトリ