ツイートキャッチ★★★を LINQ to Twitter を使うように書き換え中…と言いますか、なんか、LINQ to Twitter って、内部で Invoke をしているらしく、サーバーエラー時の挙動がおかしいんですよね。なので、Twitter が不安定な時の対処が難しい、というのが前置きなのですが。
とは云え、使い方は結構簡単です。LINQ を使って検索するので、検索系はOKかと。更新系はどうなのかいまいち確認してないのでツイート専用のほうは、TwiLib を使ったままなんですが。
例えば、ログインしている人のツイート数を取得するのは、こんなに簡単に書けます。twitter が返してくる xml の要素名と、linq to twitter で定義しているプロパティ名との「ずれ」が、いまいち分かりづらいのですが、慣れればなんとか。
// ツイート数を取得 var ctx = new TwitterContext(this.auth); var user = (from t in ctx.User where t.Type == UserType.Show && t.ScreenName == username select t).First(); this.profile_image_url = user.ProfileImageUrl; this.tweet_count = user.StatusesCount;
で、具体的に oauth 認証をどうするかというと、ツイートキャッチでは次のようにしています。
if (accessToken == "") { auth = new PinAuthorizer(); auth.Credentials = new InMemoryCredentials { ConsumerKey = this.consumerKey, ConsumerSecret = this.consumerSecret }; auth.UseCompression = false; auth.GoToTwitterAuthorization = link => { Process.Start(link); }; auth.GetPin = () => { FormAuth frm = new FormAuth(); frm.ShowDialog(); return frm.PinCode; }; auth.Authorize(); this.SavaAuth(); return; } auth = new PinAuthorizer(); auth.Credentials = new InMemoryCredentials { ConsumerKey = this.consumerKey, ConsumerSecret = this.consumerSecret }; auth.OAuthTwitter.OAuthToken = this.accessToken; auth.OAuthTwitter.OAuthTokenSecret = this.accessSecret;
oauth 認証を使う時のキーワードとして、
- アプリケーションが使う consumerKey
- アプリケーションが使う consumerSecret
のセットと
- 認証後に使う accessToken
- 認証後に使う accessSecret
の4つのキーワードがあります。
手順としては、
- アプリケーションを作るときに consumerKey と consumerSecret を取得(アプリに書き込む、app.configとか)
- ユーザーが初回実行時に consumerKey と consumerSecret を使って pincode を得る。
- pincode を使って、accessToken と accessSecret のセットを得る。
- 次回以降は、consumerKey, consumerSecret, accessToken, accessSecret の 4つがあれば ok
web ならば、ユーザー名と紐づけて保持、winodws アプリならばレジストリとかに保存
という具合です。
なので、ワンクッションだけユーザーに pincode を入力して貰う必要があるのです。まぁ、これが認証ということです。勿論、内部ブラウザで表示させたりして、pincode を自動入力させることも可能ですが、手入力でも対して手間じゃないのでそのまま。
で、linq to twitter はこの pincode を入力するとこがややこしくて、下記のように GetPin にコールバックを登録させます。
auth.GetPin = () => { FormAuth frm = new FormAuth(); frm.ShowDialog(); return frm.PinCode; };
どうしようかと悩んだのですが、ツイートキャッチ★★★では、別のダイアログを出して対処をするようにしました。
linq は検索のほうを得意とするので、直近のツイートを取得なんてのは、こんな風に書けます。
/// <summary> /// ツイートを取得 /// </summary> /// <param name="sname"></param> /// <param name="max_id"></param> /// <returns></returns> private List<Status> GetTweets(string sname, string max_id = "") { var ctx = new TwitterContext(this.auth); var items = from t in ctx.Status where t.Type == StatusType.User && t.ScreenName == username && t.Count == MAX_TWEET && t.MaxID == max_id select t; var lst = items.ToList<Status>(); return lst; }
# MaxID はクローリングのために使っているのですが、元のソースは int 型になっているのでエラーになります。ソースを string 型に適当に直しています。現在、twitter id は intの範囲を超えてしまっているので、string で保持するのがよいでしょう。
実は、最大の難関がサーバーエラーの対処なのですが、そのままではうまく動かないので諦めました。
なので、試しに oauth 認証の部分だけ linq to twitter のコードを使って、戻されてきた xml データは自前で解析するというのを試してみました。この話しは別の記事で。