BOT Framework とか使えよw というものですが、 Twitter の自動応答BOTをWebAPI化してみたかったんですね。
https://xxxx.azurewebsites.net/api/myfunc1?text=明日の天気は?
晴れのちくもり
を参考に Javascript で作りました。 (C# で作ろうと思ったんだけど、作成直後にエラーが出たもので。そっちは MSDNフォーラムに投げたら速攻で回答してもらえた のでありがたかったけどね。)
module.exports = function (context, req) {
// https://apps.twitter.com から得るやつ
var oauth = {
consumer_key: 'xxxx',
consumer_secret: 'xxxx',
token: 'xxxx',
token_secret: 'xxxx'
};
var botTwitterName = "@hoge"; // メンション投げるTwitterアカウント名
var botTwitterId = 999999999; // メンション投げるTwitterアカウントID
var senderTwitterName = "@my_twitter_account "; // 自分のTwitterアカウント名
var noComment = ['…', 'Nothing', 'EMPTY']; // リプライが得られなかった時の代替テキスト(ランダムで選ばれる)
var waitForReply = 1000; // メンション投げてリプライを取得するまでの待ち時間
if (!(req.query.text || (req.body && req.body.text))) {
context.error('error! text no found');
var res = {
status: 200,
body: noComment[0]
};
context.log("reply message:" + JSON.stringify(res));
context.done(null, res);
return;
}
var request = require('request');
var rp = require('request-promise');
// 会話相手との会話が以前にあったら、その続きにするために過去のツイートを取得する。
var getLatestReplyUrl = 'https://api.twitter.com/1.1/statuses/mentions_timeline.json?count=10';
rp({url:getLatestReplyUrl, oauth:oauth, json:true})
.then(mentions => {
// 自分の mention 群に会話相手からの投稿があったら、そのツイートIDを得る
var latestRepId = null;
for (var i = 0; i < mentions.length; i++) {
var men = mentions[i];
if (men.user.id == botTwitterId) {
latestRepId = men.id_str;
break;
}
}
var formData = {"status":botTwitterName + " " + req.query.text};
if (latestRepId != null) {
formData["in_reply_to_status_id"] = latestRepId;
}
var options = {
url: 'https://api.twitter.com/1.1/statuses/update.json',
method: 'POST',
headers: { 'Content-Type':'application/json' },
json: true,
oauth: oauth,
include_rts: false,
form: formData
};
return rp(options); // tweet
})
.then(r => {
context.log("tweeted.res:" + JSON.stringify(r));
return sleep(waitForReply).then(_ => r);
}) // wait
.then(r => { // get reply
var getRepUrl = 'https://api.twitter.com/1.1/statuses/mentions_timeline.json?count=5&since_id=' + r.id;
// var getRepUrl = 'https://api.twitter.com/1.1/statuses/mentions_timeline.json?count=10';
return rp({url:getRepUrl, oauth:oauth, json:true})
.then(mentsions => {
context.log("get mentions." + JSON.stringify(r));
var reply = {text:getNoComment()};
mentsions.forEach(function(men) {
if (men.in_reply_to_status_id == r.id) {
reply = men;
}
}, this);
context.log("get reply." + JSON.stringify(reply));
var res = {
status: 200,
body: reply.text.replace(senderTwitterName, "")
};
context.log("reply message:" + JSON.stringify(res));
context.done(null, res);
})
})
.catch(err => {
context.error('error!:' + err);
var res = {
status: 200,
body: noComment[0]
};
context.log("reply message:" + JSON.stringify(res));
context.done(null, res);
});
function sleep (time) {
return new Promise((resolve) => setTimeout(resolve, time));
}
function getNoComment() {
return noComment[Math.floor( Math.random() * noComment.length )];
}
};
in_reply_to_status_id
に設定する)。投稿したツイートの ID を得ておく。in_reply_to_status_id
に持つツイートを検索する。text
を返す。node.js でまともなプログラムを作るのは初めてでした。 次の npm モジュールにお世話になりました。
特に request
を使用した Twitter API の使い方は、
を参考にさせてもらいました。
の手順に沿うと、ブラウザ上で Terminal が使えるので、そこで npm install request-promise
などとできます。package.json
?、まだよく知らないです。
Mac と Visual Studio Code を使いました。
がとても参考になりました(インテリセンスを使うための設定はしませんでした)。
はじめは C# でやろうと思ったけど、こういうのは Javascript の方がちゃちゃっと作れてよいですね。お互い適材適所だなーと思いました。
(今のところトライアルだけど Azure Functions の課金ってどうなるのかな?)