14
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

TwitterのAccount Activity APIとwebhookでDM自動応答Botを作成する

Posted at

前回まででTwitterのAccount Activity APIおよびwebhookが使用可能になったので、DMに対して自動で返信するBotを作成してみます。あくまでもサンプルということで、ここでは「あいう」などとDMを受信したら「『あいう』は理解できません。」と、ほぼそのまま返信するBotを作成します。前回はwebhook受け取り先としてglitchのWebアプリを登録したので、glitchでのスクリプトの例を示します。

Botのスクリプト

webhookが使用できるようになるまでの手順が大変だったのに比べて、DMの送受信は拍子抜けするほど簡単です。webhookにはイベントに関するさまざまな情報がJSONで付加されてきますので、そこから必要な情報を取り出すだけです。ここでは、さまざまなイベントのうち(詳細は公式ドキュメント参照)、DMのイベント(direct_message_events)のみを処理しています。

なお、client.jsindex.htmlなどのファイルはwebhookの処理とは関係ないので初期状態のまま放置です。package.jsondependencies:に必要なパッケージを記載し(この例では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) {
  })
}
14
11
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
14
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?