いまどきはHello WorldならぬツイッターのTL表示がサンプルとしてよく見かけるように思います。お勉強の題材でも色々触っててふと思ったのですがStreamingのある今って@に反応するようなBotがタイムラグなしに実現できるんじゃなかろうか?と。というわけでやってみました。
まずは認証のための登録をhttp://twitter.com/appsで済ませておきます。(作るアプリのタイプによっては不要です)
で認証部分ですがReactiveOAuthを使わせていただきました。(@neueさん感謝です)
まぁゴテゴテかいてもあれなのでソースをば
static void Main(string[] args)
{
var client = new OAuthClient(consumerKey, consumerSecret, accessToken)
{
Url = "https://userstream.twitter.com/2/user.json"
};
var us = client.GetResponseLines()
.Where(s => !string.IsNullOrWhiteSpace(s)) // filter invalid data
.Select(s => // 文字列JSONからXElementへ変換
{
using (var jsonReader = JsonReaderWriterFactory.CreateJsonReader(Encoding.Default.GetBytes(s), XmlDictionaryReaderQuotas.Max))
return XElement.Load(jsonReader);
})
.Where(d => d.Element("entities") != null
&& d.Element("entities").Elements("user_mentions").Count(_ => _.Element("item") != null && _.Element("item").Element("screen_name").Value == "LinqFe") > 0)
//.ObserveOnDispatcher()
.Subscribe(
d => ParseAndAction(d),
ex => Console.Error.WriteLine(ReadWebException(ex)));
Console.ReadKey();
us.Dispose();
}
使い方のサンプルそのままな感じですが一応開設するとLinqTojson(JsonReaderWriterFactory経由によるLinqToXML)な感じで読み取ってWhereのところでLinqFe宛のツイートをフィルタリングして中身を処理するParseAndAction()にXMLを渡す。ただそれだけです。
Whereの中身がうるさい感じですがこういったWebのものはデシリアライズしてクラスに起しちゃうよりXMLで文字列で読み取ってるのが正解。。とおもいます。無関係な定義の変更なんかに煩わされずに済むので。いるとこだけ定義したクラスへのデシリアライズでもいいんですがさっと思いついた機能をさっと足すぐらいのほうが楽でいいです。
で、作ってみたのがこちら。おうむ返しのBotでもいいんですがこないだからいじってたHotPepperからの検索をしてくれるBotにしてみました。実行結果はこちらになります。


ReactiveOAuth、Rxのお手軽さとStreaming APIの強力さがよくわかる題材でした。こういったエージェントっぽい反応をするBotは以前はラグがあっていまいちだったんですが今はStreamingでリアルタイムに反応できるので面白いと思います。