ツイートキャッチ★★★を LINQ to Twitter を使うように書き換え中…と言いますか、なんか、LINQ to Twitter って、内部で Invoke をしているらしく、サーバーエラー時の挙動がおかしいんですよね。なので、Twitter が不安定な時の対処が難しい、というのが前置きなのですが。
とは云え、使い方は結構簡単です。LINQ を使って検索するので、検索系はOKかと。更新系はどうなのかいまいち確認してないのでツイート専用のほうは、TwiLib を使ったままなんですが。
例えば、ログインしている人のツイート数を取得するのは、こんなに簡単に書けます。twitter が返してくる xml の要素名と、linq to twitter で定義しているプロパティ名との「ずれ」が、いまいち分かりづらいのですが、慣れればなんとか。
1 2 3 4 5 6 7 8 | // ツイート数を取得 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 認証をどうするかというと、ツイートキャッチでは次のようにしています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | 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 にコールバックを登録させます。
1 2 3 4 5 6 | auth.GetPin = () => { FormAuth frm = new FormAuth(); frm.ShowDialog(); return frm.PinCode; }; |
どうしようかと悩んだのですが、ツイートキャッチ★★★では、別のダイアログを出して対処をするようにしました。
linq は検索のほうを得意とするので、直近のツイートを取得なんてのは、こんな風に書けます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | /// <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 データは自前で解析するというのを試してみました。この話しは別の記事で。