LinqToTwitter を使う

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

手順としては、

  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 にコールバックを登録させます。

	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 データは自前で解析するというのを試してみました。この話しは別の記事で。

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