2015年8月7日金曜日

LINQ to Twitter ver.3.1.2のUserStream

C#からTwitterするならLINQ to Twitterですが、今まで、これには不満点が1つありました。

それは、UserStreamの実装がだいぶ雑だったことです。

UserStreamはそもそもツイートだけでなく、例えばふぁぼ通知、フォロー通知、ツイ消し通知など、様々な情報が流れてきます。そのため、UserStreamは各種Rest APIのJSONとは違っていて、それこそ多種多様なデータが流れてきていました。そして、その多種多様なデータを適当に振り分けてくれるような機能が以前のLINQ to Twitterにはありませんでした。

なので、UserStreamの処理を書くときに限って、自前でJSONの処理をしなければいけませんでした。せっかくの.NET向けライブラリなのにとても残念なことになっていたわけですね。

無論、流れてくるツイートのみをパースしたければ、StatusクラスのコンストラクタにJsonData型を引き渡すことができるオーバーロードがありますから、それにぶち込んで、もしも例外等が吐かれたらツイート以外のデータだったんだなということで無視する、なんて方法はありました。私も以前からその方法をよく使っていましたし、それで事足りることもしばしばありました。

もしくは、UserStreamsParser for LinqToTwitterのような別のライブラリと組み合わせてパースさせることもできましたが、しばしば仕様変更で使えなくなってしまったり、いろいろと不都合なこともありました。

さて、ここまで勿体ぶったからには何が言いたいか見当が付いてきたかと思いますが、ついにLINQ to TwitterのほうでこのUserStreamのパース機能が実装されました。 (´◔౪◔)۶ヨッシャ!

現在のLINQ to Twitterの最新バージョンはver.3.1.2ですが、どうも3.1.0あたりから実装されたっぽいです(未検証)。

というわけで、さっそく使ってみました。

SingleUserAuthorizer auth = new SingleUserAuthorizer()
{
    CredentialStore = new SingleUserInMemoryCredentialStore()
    {
        ConsumerKey = "****",
        ConsumerSecret = "****",
        AccessToken = "****",
        AccessTokenSecret = "****"
    }
};

TwitterContext context = new TwitterContext(auth);

(from p in context.Streaming where p.Type == StreamingType.User select p).StartAsync(async s => {
    await Task.Run(() => {
        switch(s.EntityType) {
            case StreamEntityType.Unknown:    //Unknownはスルー
                break;
            case StreamEntityType.Status:    //ツイートが流れてきた
                ShowStatus((Status)s.Entity);
                Console.WriteLine();
                break;
        }                    
    });
});


こんな感じになります。
UserStreamで流れてくるStreamContentクラスにEntityTypeとEntityという2つのプロパティが追加されました。EntityTypeはStreamEntityType列挙体、Entityはobject型になっています。

例えば、ツイートが流れてくるときは、EntityTypeがStreamEntityType.Statusになっていて、EntityにStatus型のオブジェクトが入っています。なので、適宜キャストしてあげれば流れてきたツイートを適当に処理することができます。

ほかにも、例えばふぁぼられたときはStreamEntityType.Eventが流れてきます。この時のEntityはEventクラスのオブジェクトで、EventNameに"favorite"、SourceとTargetにそれぞれふぁぼった人とふぁぼられた人のUserデータが入っています。
ふぁぼられたツイートはTargetObjectだと思われますが、実際には"JsonData object"というテキストが入っているだけで、ふぁぼられたツイートはわかりません。これはおそらくLINQ to Twitterのバグでしょう。しっかり検証していませんが、おそらくフォロー通知などもEntityがEventとして流れてくると考えられるので、そのあたりで実装が不十分になっているのでしょう。これは是非とも今後のアップデートに期待したいですね。

ほかにもDeleteやDirectMessageなど、様々なUserStreamの情報に対応しているようですから、いろいろいじってみると面白いかもしれません。

 ちなみに、RetweetedみたいなEntityが無いなと思っていたら、どうもこれ、普通にStatusと一緒にやってくるみたいですね。要するに「リツイートされたツイートの投稿主が自分だったらリツイートされたってことでしょ 」という体みたいです。まあそれくらいの実装なら全然難しくはなさそうですよね。ハマらないように、念のため。

0 件のコメント:

コメントを投稿