IBM BluemixとNode.jsでお天気通知!―Facebook Messenger Bot(2) / Botのベースを作成

AWSやAzureを始めたとしたクラウドサービス全般を触っていく連載「クラウドサービス研究スタジオ」。この連載では、IaaS,PaaS,BaaS,SaaSなど幅広い形態のサービスを実際に使ってレポートしていきます!

今回作るもの

こんにちは、エンジニアのちゃんとくです。テクニカルライターとしてdotstudioに参加しています。

今回は、2016年に公開された話題のMessenger Platformを使ってFacebook Messenger Botを作りIBM Bluemixにホスティングしてみます。

下記のようにお天気を教えてくれるものを想定しています。

BotプログラムはNode.jsで作成し、IBM Bluemixで提供されているWeather Company Dataから天気情報を取得してIBM Bluemixにホスティングし運用します。

下記の構成で手順を紹介します。

  • IBM Bluemixの設定
  • Botのベースを作成
  • 天気情報を取得
  • Facebook Messenger Botをデプロイ

今回はBotプログラムのベース部分作成を説明していきます。

IBM Bluemixの設定とデプロイ方法については前回の記事をご覧ください。

筆者の環境

OS X El Capitan(v10.11.6)
Node.js v8.2.1

8,568通り、あなたはどのタイプ?

Facebook Messenger Botとは

「Bot」とはプログラムの制御による自動発言システムのことです。連載第1回ではLINEアプリ上で動く「LINE Bot」を作成しました。

Messenger PlatformというMessengerアプリ開発のプラットフォームを使い作成していきます。

Receive/Send APIを使ってやり取りする形式で、LINE Bot開発の経験がある方はスムーズに導入できると思います。詳細はAPIリファレンスを参照してください。

8,568通り、あなたはどのタイプ?

Facebookアプリを作成する

まずは開発を始めるためにFacebookの開発者登録をしましょう。

Facebook for Developers

スタートからアカウントとアプリの作成を進めます。

アプリ名は後から変更できるのでわかりやすい名前をつけましょう。

作成できると、ダッシュボードに移動します。左の「製品を追加」タブから「Messenger」を選択しましょう。

Messengerプラットフォームに移動し、各種設定が行えるようになります。

Facebookページを作成する

Facebook Messenger BotはFacebookページと連携します。既存の管理ページか、新規に作成したページを利用しましょう。

今回は私が運営しているNode女学園のページを連携させてみます(現在Botは稼働していません)。

ページが非公開状態の場合連携させることができないので注意してください。

Node.jsでWebhookを作成する

Messengerの開発にはエンドポイントURLの設定が必要です。Node.jsで作成していきましょう。

コマンドラインからプロジェクトディレクトリを作成して、その下にpackage.jsonを作成します。<your app name>は任意のアプリ名に置き換えてください。

$ mkdir <your app name>
$ cd <your app name>/
$ npm init --yes

実行すると下記のメッセージとともにpackage.jsonが作成されます。

{
  "name": "<your app name>",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

今回使うモジュールをnpmコマンドでインストールしてpackage.jsonに書き込みます。

$ npm install express request body-parser --save

次にプログラムのメインとなるapp.jsを作成します。

$ touch app.js

エディタでapp.jsを開き以下をコピー&ペーストします。

$ touch app.js

エディタでapp.jsを開き以下をコピー&ペーストします。

app.js
'use strict'

const express = require('express');
const bodyParser = require('body-parser');
const request = require('request');
const app = express();
const token = '<任意の文字列>';

app.set('port', (process.env.PORT || 3000));

app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());

app.get('/', function (req, res) {
    res.send('Hello, Facebook Messenger Bot.')
});

app.get('/webhook', function (req, res) {
    if (req.query['hub.verify_token'] === token) {
        res.send(req.query['hub.challenge'])
    }
    res.send('Error, wrong token')
  console.log(req.query['hub.challenge']);
});

app.listen(app.get('port'), function() {
    console.log('running on port', app.get('port'))
});

<任意の文字列>の部分にはご自身でtokenを設定してください。のちほどFacebook側の設定で使用します。

ngrokで試す

ホスティングする前に、ローカル環境からwebhookを試してみます。PCのlocalhostにグローバルからアクセスできるトンネリングツールを利用しましょう。

今回はngrokを利用します。

ngrockのサイトにいき、ダウンロードして解凍します。

ダウンロードフォルダで正しく動作するか確認しましょう。

次にngrokのユーザ登録をします。先ほどのページから登録し、登録後に表示されるコマンドを自身のコマンドラインで実行します。

$ ./ngrok authtoken xxxxxxxxxxxxxxxxxxx

ユーザとPCが紐づけられ、以後トンネリングが利用できるようになります。

./ngrok http <ポート番号>でトンネリングサーバが起動します。今回ポートは3000を指定しましょう。

$ ./ngrok http 3000

起動すると利用できるアドレスが表示されます。

SSL対応のエンドポイントが必要なので、https://の方のアドレスを利用しましょう。

ngrokは起動のたびにアドレスが変わるので、下記のようにngrokを起動したまま別のタブでNode.jsアプリケーションを実行します。

先ほど取得したローカルトンネルサーバのアドレスをFacebookアプリのwebhookに登録します。「Webhookの設定」を選択しましょう。

コールバックURLにローカルトンネルサーバのアドレス/webhookを記載します。トークンにはプログラム内で記載した任意のトークンを記述します。サブスクリプションは全て選択しておきましょう。

「確認して保存」を押すと、アドレスにアクセスし正常にレスポンスを返すと登録されます。ngrokの実行画面でアクセスが来ていることがわかります。

Facebookページを連携する

Facebookページを設定しアプリケーションのアクセストークンを発行します。

発行されたトークンをコピーし、curlコマンドを叩いてBotを起動させます。

curl -ik -X POST "https://graph.facebook.com/v2.6/me/subscribed_apps?access_token=<アクセストークン>"

正しく設定できるとFacebookページの更新を受け取ることができるようになります。

オウム返しBotを作成する

Botプログラムのベースとして、オウム返しBotを作成してみましょう。

`app.js`を以下のように変更します。

app.tjs
'use strict'

const express = require('express');
const bodyParser = require('body-parser');
const request = require('request');
const app = express();
const token = '';


const sendTextMessage = (sender, text) => {
  const messageData = {
    text:text
  }
  request({
    url: 'https://graph.facebook.com/v2.6/me/messages',
    qs: {access_token:token},
    method: 'POST',
    json: {
      recipient: {id:sender},
      message: messageData,
    }
  }, (error, response, body) => {
    if (error) {
      console.log('Error: ', error);
    } else if (response.body.error) {
      console.log('Error: ', response.body.error);
    }
  });
}

app.set('port', (process.env.PORT || 3000));

app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());

app.get('/', function (req, res) {
    res.send('Hello, Facebook Messenger Bot.');
});

app.get('/webhook', function (req, res) {
    if (req.query['hub.verify_token'] === token) {
    res.send(req.query['hub.challenge']);
    }
  res.send('Error, wrong validation token');
});

app.post('/webhook', function (req, res) {
  let messaging_events = req.body.entry[0].messaging
  for (let i = 0; i < messaging_events.length; i++) {
    let event = req.body.entry[0].messaging[i]
    let sender = event.sender.id
    if (event.message && event.message.text) {
      let text = event.message.text
      sendTextMessage(sender, text.substring(0, 200));
    }
  }
  res.sendStatus(200);
});

app.listen(app.get('port'), function() {
    console.log('running on port', app.get('port'));
});

冒頭の<アクセストークン>には、先ほど取得したアクセストークンを記載します。

試してみる

変更したら再度npm startでNode.jsアプリケーションを実行し、Facebook Messenger上で試してみます。

オウム返しができました!

まとめ

今回はBotのベースになるプログラムを作ってみました。

開発段階でエンドポイントURLが必要になることがネックでしたが、localhostにグローバルアクセスできるトンネリングツールを使うことで簡単に検証することができました。またSSL対応もしてくれているのでとても便利ですね。

次回はIBM BluemixのWeather Company Dataを使って天気情報の取得をしていきたいと思います。

それではまた!

取材・執筆:dotstudio, inc. ちゃんとく

大学までは文系で法学を学んでいたが「モノを作れる人」に憧れて知識ゼロからWebエンジニアの道へ。転職し現在はIoT中心のエンジニア・テクニカルライターとして活動。Node.jsユーザグループ内の女性コミュニティ「Node Girls」を主催。Twitter: @tokutoku393 / dotstudio, inc.

※本記事は「CodeIQ MAGAZINE」掲載の記事を転載しております。

PC_goodpoint_banner2

Pagetop