LinqToTwitter を使う

ツイートキャッチ★★★を 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つのキーワードがあります。

手順としては、

  1. アプリケーションを作るときに consumerKey と consumerSecret を取得(アプリに書き込む、app.configとか)
  2. ユーザーが初回実行時に consumerKey と consumerSecret を使って pincode を得る。
  3. pincode を使って、accessToken と accessSecret のセットを得る。
  4. web ならば、ユーザー名と紐づけて保持、winodws アプリならばレジストリとかに保存

  5. 次回以降は、consumerKey, consumerSecret, accessToken, accessSecret の 4つがあれば ok

という具合です。

なので、ワンクッションだけユーザーに 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 データは自前で解析するというのを試してみました。この話しは別の記事で。

カテゴリー: C# パーマリンク