Help us understand the problem. What is going on with this article?

Googleスプレッドシートだけで作るFB messenger bot

More than 3 years have passed since last update.

概要

  • 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ページの作成・アプリの登録」の手順を行って下さい。そこまでの手順はバックエンドを何にしようが同じです。

発行されるページアクセストークンは後で使うので、忘れずにメモしておきましょう(ブログなど人が見える所に公開しないように気をつけて下さい!)

ページアクセストークン - Facebook Developer

2. GASの編集

まず、使用するスプレッドシートに、以下の画像のように行を追加します。 今回はA列に書いた単語にヒットしたとき、B列の単語を返すようにプログラムを組みました。つまりユーザーが「test」とメッセージを送ると、「てすとです」と返します。

スプレッドーシートに行を追加

次のステップで使うので、スプレッドシートのIDをメモしておきましょう。URLのランダム文字列になっている部分がIDです。

スプレッドシートの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を実行しても謎のエラーになります。気をつけましょう。

test関数の実行 - スクリプトエディタ

このような承認画面が出てくるので、[許可を確認]をクリックし、その後出てくる認証画面でもOKを選択します。

承認画面 - スクリプトエディタ

次はAPIとして公開する手順です。[公開] => [ウェブアプリケーションとして導入]を選択します。

ウェブアプリケーションとして導入 - スクリプトエディタ

下記のような画面が出てくるので、[次のユーザーとしてアプリケーションを実行]を自分、[アプリケーションにアクセスできるユーザー]を全員(匿名ユーザーを含む)にして、[導入]をクリックします。

ウェブアプリケーションの設定 - スクリプトエディタ

これにてスプレッドシート側の設定は終わりです。URLが発行されるので、これをメモしておきましょう。

ウェブアプリケーションのURL - スクリプトエディタ

4.Messengerの設定

またFacebook Developersのページに戻り、Webhooksの設定画面から[Setup Webhooks]を選択します。

Setup Webhooks - Facebook Developers

[コールバックURL]の欄に先ほど発行されたスプレッドシートのAPIのURLを、[トークンを確認]の欄には最初に作ったページアクセストークンを設定します。[mesages]にのみチェックを入れて、[確認して保存]です。とくにエラーが出ずに終了したら完璧です。

コールバックURLの設定 - Setup Webhooks

あとはFacebookページに対してメッセージを送れば、設定したものが返ってきます!!!

Botのテスト

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日当たり何回まで実行可能、というやつ)あったはずです。詳細は忘れましたが...

参考

レポジトリ

https://github.com/KeitaMoromizato/facebook-messenger-bot-on-google-spreadsheet

folio-sec
誰もがかんたんに資産運用することができるサービス「フォリオ」を作っているFinTech系スタートアップ
https://corp.folio-sec.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした