TwitterのAPIライブラリ、Twitterizer Ver 2.3.1を使ってUserStreamを利用しようと以下のコードを書いたんです。
using System;
using System.Net;
using System.Reflection;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string consumerKey = "hoge";
string consumerSecret = "hogehoge";
Twitterizer.OAuthTokenResponse reqToken = Twitterizer.OAuthUtility.GetRequestToken(consumerKey, consumerSecret, "oob");
Uri uri = Twitterizer.OAuthUtility.BuildAuthorizationUri(reqToken.Token);
System.Diagnostics.Process.Start(uri.ToString());
Console.WriteLine("Pinコードを入力しる");
string pinCode = Console.ReadLine();
Twitterizer.OAuthTokenResponse accToken = Twitterizer.OAuthUtility.GetAccessToken(consumerKey, consumerSecret, reqToken.Token, pinCode);
Twitterizer.OAuthTokens token = new Twitterizer.OAuthTokens
{
ConsumerKey = consumerKey,
ConsumerSecret = consumerSecret,
AccessToken = accToken.Token,
AccessTokenSecret = accToken.TokenSecret
};
using (var twitterStream = new Twitterizer.Streaming.TwitterStream(token))
{
twitterStream.OnStatusReceived += (Twitterizer.TwitterStatus status) =>
{
Console.WriteLine(string.Format("{0}/({1})\r\n\t{2}",
status.User.Name,
status.User.ScreenName,
status.Text));
};
twitterStream.StartUserStream();
while (true) { }
}
}
}
}
何度試しても404が返ってくる。実はこれ、ベータ版のアドレスにアクセスしてるんですよ。これがソースコード
no title
がっつりとハードコーディングされちゃっててどうにもなりません。自家ビルドして使う?嫌ですよ、そんなの。面倒じゃないですか。幸い、このStartUserStreamメソッドは短いです。じゃあStartUserStreamメソッドを呼び出してる部分のコードをURLだけ置き換えた同じ内容のコードに書き換えればいいじゃない!
以下の3行までは問題ないです。
WebRequestBuilder builder = new WebRequestBuilder(new Uri("http://betastream.twitter.com/2b/user.json"), HTTPVerb.GET, this.Tokens);
HttpWebRequest request = builder.PrepareRequest();
request.KeepAlive = true;
URLを置き換えるだけです。WebRequestBuilderクラスはpublicなので問題なく利用出来ます。引数に渡しているthis.Tokensはコンストラクタに渡したインスタンスそのものなので、こちらのスコープで保持しているものに置き換えればいいです。
問題は最後の行ですね
request.BeginGetResponse(StreamCallback, request);
引数に渡しているStreamCallbackっての、これprivateなメソッドなんですよ。これはリフレクションで取ってくることにしました。
MethodInfo method = twitterStream.GetType().GetMethod("StreamCallback",
BindingFlags.Instance |
BindingFlags.NonPublic);
AsyncCallback callback = (_) =>
{
method.Invoke(twitterStream, new[] { _ });
};
リフレクションで取ってきたメソッドをInvokeするコードをAsyncCallbackデリゲートで包んであげればOKじゃんって寸法です。
で、最終的なコードがこんな感じ
using System;
using System.Net;
using System.Reflection;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string consumerKey = "hoge";
string consumerSecret = "hogehoge";
Twitterizer.OAuthTokenResponse reqToken = Twitterizer.OAuthUtility.GetRequestToken(consumerKey, consumerSecret, "oob");
Uri uri = Twitterizer.OAuthUtility.BuildAuthorizationUri(reqToken.Token);
System.Diagnostics.Process.Start(uri.ToString());
Console.WriteLine("Pinコードを入力しる");
string pinCode = Console.ReadLine();
Twitterizer.OAuthTokenResponse accToken =Twitterizer.OAuthUtility.GetAccessToken(consumerKey, consumerSecret, reqToken.Token, pinCode);
Twitterizer.OAuthTokens token = new Twitterizer.OAuthTokens
{
ConsumerKey = consumerKey,
ConsumerSecret = consumerSecret,
AccessToken = accToken.Token,
AccessTokenSecret = accToken.TokenSecret
};
using (var twitterStream = new Twitterizer.Streaming.TwitterStream(token))
{
twitterStream.OnStatusReceived += (Twitterizer.TwitterStatus status) =>
{
Console.WriteLine(string.Format("{0}/({1})\r\n\t{2}",
status.User.Name,
status.User.ScreenName,
status.Text));
};
//twitterStream.StartUserStream();
//StartUserStreamメソッドがベータ版のURLに繋いでエラーになるから
//下記ソースの動作をURLだけ変えて実行
//http://pm.twitterizer.net/projects/twitterizer/repository/entry/tags/twitterizer-2.3.1/Twitterizer2.Streaming/TwitterStream.cs#L138
var builder = new Twitterizer.WebRequestBuilder(new Uri("https://userstream.twitter.com/2/user.json"), Twitterizer.HTTPVerb.GET, twitterStream.Tokens);
HttpWebRequest request = builder.PrepareRequest();
request.KeepAlive = true;
MethodInfo method = twitterStream.GetType().GetMethod("StreamCallback",
BindingFlags.Instance |
BindingFlags.NonPublic);
AsyncCallback callback = (_) =>
{
method.Invoke(twitterStream, new[] { _ });
};
request.BeginGetResponse(callback, request);
while (true) { }
}
}
}
}
これでめでたくUserStreamが使えるようになりました。ちなみにtrunkの最新のソースコードでもURLはベータ版のものがベタ書きのままでした。中の人忙しいのかな…。