C# + DotNetOpenAuthでTwitter API のSingle-user Auth認証を行い、タイムラインのJSONを取得する

以前、.NETでTwitterAPIを扱うために、Linq2Twitterライブラリを使いました。
C# + LINQtoTwitter を使ってツイートしたりタイムラインを取得してみる - メモ的な思考的な

ただ、今度はTwitterAPIのGET statuses/home_timelineの結果のJSONが必要になりました。
GET statuses/home_timeline | Twitter Developers

そのJSONを得るには、TwitterAPIのSingle-user Auth (AccessTokenやAccessSecretを事前に取得しておくタイプ)*1OAuth認証をする必要がありそうでした。

 
そこで、OAuthまわりのライブラリをOAuthのサイト(Code — OAuth)から探してみたところ、その中の一番上にあげられていたDotNetOpenAuthが、

という感じで、良さそうなライブラリでした。

また、GitHubにサンプルプロジェクトもあり(DotNetOpenAuth/DotNetOpenAuth.Samples - GitHub)*3、またBlogなどを探すとTwitterASP.NETと組み合わせて使う方法がたくさん出てきました。

 
ただ、Single-user Authで使っているものが見当たらなかったため、以下を参考にコンソールアプリを作ってみることにしました。

 

環境

  • Windows7
  • NET Framework 4.5
  • DotNetOpenAuth OAuth 1.0(a) Consumer 4.3.4
  • DynamicJson 1.2.0.0

 

流れ

Twitterまわりの設定

コードを書く前に、今回で使うためのアプリの設定をTwitterに登録しておく必要があります。
Twitter Application Management

今回の設定では、

  • CallbackURL: 空欄
  • Permission: Read only

にしておくくらいで、あとはいつも通りに登録します。

ちなみに、TwitterAPIの認証のためのエンドポイントは、アプリを登録後、アプリのDetailsタブのApplication settings欄、 Authorize URLに表示されています。

 

JSONのパース

.NETのライブラリはいくつかありましたが、扱いやすそうなDynamicJsonを選びました。

 

NuGetパッケージのインストール

TwitterはOAuth 1.0(a)を使用しているため、以下のNuGetパッケージをインストールします。

  • DotNetOpenAuth OAuth 1.0(a) Consumer (by Andrew Amott) *5
  • DynamicJson (by neuecc)

同時に、依存しているパッケージなどもインストールされます。

 

実装

今回使用するクラスは以下の通りです。

クラス名 内容
Program エントリポイントのクラス
TwitterConsumer Twitter APIへの認証とリクエストを行うクラス
TwitterTokenManager TwitterのTokenを扱うクラス

 

Programクラス

コンソールアプリのエントリポイントです。

Twitterhome_timelineAPIにGETリクエストを出して、返ってきたJSONをパースして表示しています。

class Program
{
    static void Main(string[] args)
    {
        var timeline = new MessageReceivingEndpoint("https://api.twitter.com/1.1/statuses/home_timeline.json",
                                                    HttpDeliveryMethods.GetRequest);

        using (var r = timeline.Get())
        using (var s = r.GetResponseReader())
        {
            var json = DynamicJson.Parse(s.ReadToEnd());

            foreach (var item in json)
            {
                Console.WriteLine(item.text);
            }
        }

        Console.ReadLine();
    }
}

 

TwitterConsumer

他のサンプルではいろいろと実装されていました。

ただ、今回はSingle-user Authを使うためにトークンの更新などは発生しないことから、かなり簡単な流れになりました。

consumerさえできれば、あとはPrepareAuthorizedRequestAndSendメソッドがよろしくやってくれます。

public static IncomingWebResponse Get(this MessageReceivingEndpoint endpoint)
{
    // OAuthの認証設定
    var serviceProviderDescription = new ServiceProviderDescription
    {
        UserAuthorizationEndpoint = new MessageReceivingEndpoint("https://api.twitter.com/oauth/authorize", HttpDeliveryMethods.GetRequest),
        TamperProtectionElements = new ITamperProtectionChannelBindingElement[] { new HmacSha1SigningBindingElement() },
        ProtocolVersion = ProtocolVersion.V10a,
    };

    // 各種APIキーをセットしたTokenManagerを生成
    var tokenManager = new InMemoryTokenManager(ApiKey, ApiSecret, new Dictionary<string, string>() { { AccessToken, AccessSecret } });

   // 認証設定とTokenManagerからconsumerを生成
    var consumer = new DesktopConsumer(serviceProviderDescription, tokenManager);

    // endpointに認証とリクエストを投げる
    return consumer.PrepareAuthorizedRequestAndSend(endpoint, AccessToken);
}

 

TwitterTokenManager

IConsumerTokenManagerインタフェースを実装します。なお、左記のインタフェースではITokenManagerインタフェースの実装も必要になります。

インタフェースのメンバのうち、GetTokenSecret()メソッドTwitterのAccessSecretを返すところだけが必要なので、他のメソッドやプロパティは空っぽで大丈夫です。

public class TwitterTokenManager : IConsumerTokenManager
{
...
    public string GetTokenSecret(string token)
        {
            return _accessKey[token];
        }
...
}

 

実行結果

以前、各社電子書籍ののDeal of the DayのBot(@)を作成したことがありました。
各社のDeal of the Day用のbotを作ってみた - メモ的な思考的な

そのBotのタイムラインを取得してみましたが、問題なく動作しているようです。

 

Twitterのタイムライン

f:id:thinkAmi:20140719055446p:plain

 

実行時のコンソール

f:id:thinkAmi:20140719055507p:plain

 

ソースコード

Gistに上げました。
Twitter Single-user Auth sample: Using DotNetOpenAuth and DynamicJson

 

その他

OAuthライブラリ
OAuthBase.cs

Linq2TwitterのOAuthはどうしているかをソースコードで見たところ、OAuthBase.csを使っていそうなことが分かりました。
oauth - API needz authorized? - Google Project Hosting

そこでOAuthBase.csについて調べてみましたが、

  • ライブラリの更新がなさそう
  • ライブラリを扱うのが面倒という記事がちらほら
  • 自分で拡張している方々もいて、どれを使えばいいのか分かりづらい
  • バグがあるっぽい *6

と扱いがなかなか難しそうでしたので、今回はやめておきました。

なお、PINコード入力でOAuthBaseを使って実装している記事はありました。
【C#でTwitter】OAuth認証を行う[デスクトップクライアント版] | Black Everyday Company )

 

JSONからC#のクラスを生成してくれるサービス

JSONをコピペして使うと良さそうです。
json2csharp - generate c# classes from json

*1:Obtaining access tokens | Twitter Developers の中の「Just want to access the API from your own account...」にあたるもの

*2:OAuthWebSecurity クラス (Microsoft.Web.WebPages.OAuth) - MSDN

*3:ただ、DotNetOpenAuth本体のsampleディレクトリにもサンプルがあり、ほぼ同じような時期に更新もされていることから、本当はどちらなんだろう。一応DotNetOpenAuthの公式ページからは、DotNetOpenAuth.Samplesへのリンクがあった。

*4:DotNetOpenAuth.Samples/src/OAuth/OAuthConsumerWpf/MainWindow.xaml.cs - DotNetOpenAuth/DotNetOpenAuth.Samples - GitHub

*5:DotNetOpenAuthパッケージにすると1.0aでは不要なものも入ってくるので、最低限のものだとこれになるかと

*6:neue cc - AsyncOAuth ver.0.7.0 - HttpClient正式版対応とバグ修正