【C#】Twitter API v2 をHttpClientで直接叩いてみる

TwitterAPIをC#で利用する場合に、v1の際はCoreTweetライブラリを利用していましたが、v2ではエラーが発生してしまいました(v2には対応していない?)

【C#】CoreTweet でプログラムからTwitter にツイートしてみる
CoreTweetというライブラリを使うとC#でbotが簡単に作れるらしいので使ってみました。TwitterのAPIを利用するため、必…

そのため、ライブラリを使わずHttpClientでエンドポイントを指定して直接APIを叩いてみます。

【検証環境】.NET 6 / Twitter API v2

Bearer認証

v2のエンドポイントを利用する際にBearer認証を利用します。

申請後にポータルでBearerトークンを取得できるので、それを使います。トークンは取得済みの前提です。

https://developer.twitter.com/ja/docs/authentication/oauth-2-0/application-only

Twitter API を叩く

まずはベースとなるクラスを作成します。共通で使用するHttpClientとBearerトークンを保持します。

エンドポイントのベースとなるURLを定義します。また、Bearer認証のためヘッダにAuthorizationを追加します。

以降の各エンドポイントごとにクラスを作成し、継承させます。

public class TwitterBase
{
    private static HttpClient _httpClient;
    private static readonly string _beareToken = "【BEARER TOKEN】";

    protected static HttpClient Clinet 
    { 
        get
        {
            if (_httpClient == null)
            {
                _httpClient = new HttpClient()
                {
                    BaseAddress = new Uri("https://api.twitter.com"),
                };
                _httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {_beareToken}");
            }
            return _httpClient;
        } 
    }
}

レスポンス情報について

各エンドポイントごとに、公式ドキュメントにResponse fieldsが定義されています。

DEFAULTであるものは必ず返ります。他の項目はリクエスト時に指定しなければ返却されません。

指定の仕方はDictionaryを定義し、HttpClientのクエリパラメータに渡します(GETの場合)

Dictionary<string, string> _params = new Dictionary<string, string>()
{
        //{"expansions", "pinned_tweet_id" }, // 固定ツイートフラグ
        //{"tweet.fields", "created_at" },         // 固定ツイート情報
        {"user.fields", "created_at,profile_image_url" },   // 複数指定した場合は、「,」で区切る
};

複数指定した場合は、「,」で区切りますが、ブランクがあるとパラメータが不正になるため、正しく取得できなくなります

エンドポイントごとに公式ドキュメントを確認し、欲しい情報に合わせてパラメータを定義するようにしましょう。

また、パラメータの定義に合わせてデシリアライズ用のクラスを定義します。上記の例の場合は下記のように返却されるJSONの合わせたものになります。

public class Data
{
    public DateTime created_at { get; set; }
    public string name { get; set; }
    public string id { get; set; }
    public string username { get; set; }
    public string profile_image_url { get; set; }
}

public class RootData
{
    public Data data { get; set; }
}

Users(ユーザ名orユーザIDからユーザ情報を取得)

ユーザ名orユーザIDからユーザ情報を取得するエンドポイントです。

ユーザ名とユーザIDの違いについて

https://followcheck.itby.net/twittertips/p/4

ユーザ名を指定した方が分かりやすいですが、取得したいアカウントのユーザ名が変わることを想定した場合はIDを指定するようにした方がよさそうです。

GET /2/users/by/username/:username

公式ドキュメント https://developer.twitter.com/en/docs/twitter-api/users/lookup/api-reference/get-users-by-username-username

ユーザ名からユーザ情報を取得します。

こちらのエンドポイントで取得できる情報のオプション情報は下記のように定義されています。

expnasions

固定ツイート情報を取得する場合使います

tweet.fields

固定ツイートに関する詳細を取得します

user.fields

ユーザに関する詳細を取得します(作成日、ユーザID …など)
(必須情報のid,name,usernameは指定しなくても大丈夫でした)

コードはこちらです。

JSON文字列で返ってきたデータをレスポンス用のクラスを作成して、デシリアライズします。RootDataクラスのデータを受け取ることができます。

ちなみに存在しないユーザ名を指定した場合はデシリアライズに失敗するため、nullが返ります。

public class Users : TwitterBase
{
    private Dictionary<string, string> _params = new Dictionary<string, string>()
    {
        //{"expansions", "pinned_tweet_id" }, // 固定ツイート
        {"user.fields", "created_at,profile_image_url" },   // 複数指定した場合は、「,」で区切る
        //{"tweet.fields", "created_at" }, 
    };

    public async Task<RootData> GetUserByUserName(string userName)
    {
        // https://developer.twitter.com/en/docs/twitter-api/users/lookup/api-reference/get-users-by-username-username

        // パスパラメータ
        var uri = $"/2/users/by/username/{userName}";
        // クエリパラメータ
        uri += $"?{await new FormUrlEncodedContent(_params).ReadAsStringAsync()}";
        
        var res = await Clinet.GetAsync(uri);
        var data = System.Text.Json.JsonSerializer.Deserialize<RootData>(await res.Content.ReadAsStringAsync());
        return data;
    }

    public class Data
	{
	    public DateTime created_at { get; set; }
	    public string name { get; set; }
	    public string id { get; set; }
	    public string username { get; set; }
	    public string profile_image_url {get; set;}
	}
	public class RootData
	{
	    public Data data { get; set; }
	}
}

実際に使ってみたところ、idの出力が確認できました。

var users = new Users();
var res = await users.GetUserByUserName("TwitterDev");
Console.WriteLine(res.data.id);

ちなみにTwitterDevは公式のアカウントです

Tweets by TwitterDev

その他エンドポイントについて

順次更新予定・・

Twitter API のアクセスレベル

TwitterAPIのアクセスレベルは種類があり、Elevatedであればv1とv2のエンドポイントを利用できます。

今のところ、v1でなければ利用できない機能があったりします(画像付きツイートなど)

今からv1を利用するには、申請してElevatedに昇格させる必要があります。

以下は私が以前申請した際に参考にしたサイトです。

https://tensei-shinai.com/2022/04/27/twitter-api-elevated/

Leave a Reply

Your email address will not be published. Required fields are marked *