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が返ってくる。実はこれ、ベータ版のアドレスにアクセスしてるんですよ。これがソースコード
がっつりとハードコーディングされちゃっててどうにもなりません。自家ビルドして使う?嫌ですよ、そんなの。面倒じゃないですか。幸い、この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はベータ版のものがベタ書きのままでした。中の人忙しいのかな…。