前回まででTwitterのAccount Activity APIおよびwebhookが使用可能になったので、DMに対して自動で返信するBotを作成してみます。あくまでもサンプルということで、ここでは「あいう」などとDMを受信したら「『あいう』は理解できません。」と、ほぼそのまま返信するBotを作成します。前回はwebhook受け取り先としてglitchのWebアプリを登録したので、glitchでのスクリプトの例を示します。
Botのスクリプト
webhookが使用できるようになるまでの手順が大変だったのに比べて、DMの送受信は拍子抜けするほど簡単です。webhookにはイベントに関するさまざまな情報がJSONで付加されてきますので、そこから必要な情報を取り出すだけです。ここでは、さまざまなイベントのうち(詳細は公式ドキュメント参照)、DMのイベント(direct_message_events
)のみを処理しています。
なお、client.js
やindex.html
などのファイルはwebhookの処理とは関係ないので初期状態のまま放置です。package.json
のdependencies:
に必要なパッケージを記載し(この例ではrequest
)、.env
にコンシューマーキーなどの秘密情報を定義しておきます。下の例では、OAuth用の4つのキー(CONSUMER_KEY
, CONSUMER_SECRET
, ACCESS_TOKEN
, ACCESS_SECRET
)と、自分自身のtwitter ID(MYSELF
)を定義しています。webhookでDMを受け取るだけなら認証は必要ありません。認証情報はDMの送信用です。
以下、server.js
ファイルのサンプルです。
// init project
var express = require('express');
var request = require('request');
const crypto = require('crypto');
var bodyParser = require('body-parser');
var app = express();
// OAuth1.0認証に必要なキーを.envから読み込んで設定
var twitter = {};
twitter.oauth = {
consumer_key: process.env.CONSUMER_KEY,
consumer_secret: process.env.CONSUMER_SECRET,
token: process.env.ACCESS_TOKEN,
token_secret: process.env.ACCESS_SECRET
}
app.use(express.static('public'));
// webhookの処理には関係ないので、ルートの処理は初期状態のまま放置
app.get("/", function (request, response) {
response.sendFile(__dirname + '/views/index.html');
});
// TwitterのCRCテストにパスするための処理。作成したHMACをJSONで返す
// CRCテストはGETで行われる
app.get("/webhook", function (request,response) {
var hmac = crypto.createHmac('sha256', process.env.CONSUMER_SECRET).update(request.query.crc_token).digest('base64');
response.send('{"response_token":"sha256='+hmac+'"}');
});
// POSTされたデータをパースして使用する
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
// Twitterからのwebhookを受け取る
// webhookはPOSTで行われる
app.post("/webhook", function (request, response) {
response.setHeader('Content-Type', 'text/plain');
// webhookされたイベントがDMの送受信の場合だけ処理する
if (request.body.direct_message_events) {
// DMの送信者のIDを取得
var sender = request.body.direct_message_events[0].message_create.sender_id;
// DMのメッセージ本文を取得
var message_txt = request.body.direct_message_events[0].message_create.message_data.text;
// 送信者が自分自身でない場合のみ自動返信
// 自分のユーザーIDは.envで「MYSELF」として定義済
if (sender !=process.env.MYSELF){
autoReply(sender, '「'+ message_txt +'」は理解できません。');
}
}
response.sendStatus(200);
});
// listen for requests :) ← この部分も初期状態のまま
var listener = app.listen(process.env.PORT, function () {
console.log('Your app is listening on port ' + listener.address().port);
});
// 自動応答
function autoReply(userid, message){
// まずはDM返信用のオブジェクトを作成
var message_obj =new Object();
message_obj = {
"event": {
"type": "message_create",
"message_create": {
"target": {
"recipient_id":userid
},
"message_data": {
"text": message
}
}
}
}
// DMをPOSTするための認証情報その他を設定
var request_options = {
url: 'https://api.twitter.com/1.1/direct_messages/events/new.json',
oauth: twitter.oauth,
json: true,
headers: {
'content-type': 'application/json'
},
body: message_obj
}
// POSTで送信
request.post(request_options, function (error, response, body) {
})
}