Dartでhttpライブラリのみを利用してTwitter API v2を使う
必要なもの
- APIキー
- APIシークレットキー
手順としては
- APIキーとAPIシークレットキーBase64化する
- OAuth 2.0 Bearer Tokenを取得する
- 取得したBearer Tokenの情報を付与してAPIアクセス
※現地点でユーザに紐づくAPIのv2は存在しないようです。
※デベロッパーサイトでOAuth 2.0 Bearer Tokenを直接取得することもできます。
APIキーとAPIシークレットキーBase64化する
final base64encoded = base64.encode(latin1.encode('${API_KEY}:${API_KEY_SECRET}'));
Tokenを取得するためのAPIはBasic認証が掛けられていますので、APIキーとAPIシークレットキーを:で結合してBase64化します。
base64化コードはhttp_authライブラリを参考にしました。
OAuth 2.0 Bearer Tokenを取得する
投げる内容は、リクエストヘッダーに「Authorization」とリクエストボディに「grant_type」を指定します。
final response = await http.post(
'https://api.twitter.com/oauth2/token',
headers: {'Authorization': 'Basic $base64encoded'},
body: {'grant_type': 'client_credentials'},
);
レスポンスが以下(例)のように返ってきて、AAAA%2FAAA%3DAAAAAAAAがBearer Tokenになります。
{"token_type":"bearer","access_token":"AAAA%2FAAA%3DAAAAAAAA"}
取得したBearer Tokenの情報を付与してAPIアクセス
ここでは、例として、
/2/users/by/username/:username
にアクセスしてみます。
投げる内容は、「:username」に組み込みパラメータとしてLuecy1(私のtwitterアカウントです)リクエストヘッダーに「Authorization」を指定します。
final result = await http.get(
'https://api.twitter.com/2/users/by/username/Luecy1',
headers: {'Authorization': 'Bearer ${oauthToken.accessToken}'},
);
Bearerとtokenの間はスペース1つ分です!(一回はまった)
これで以下のレスポンスが返却されます。
従来のAPIよりレスポンス量が物足りないですが、Twitter API v2では欲しい情報を指定する方針となったようです。
{"data":{"id":"285498667","name":"youhei@( ˘ω˘)スヤァ…☃️","username":"Luecy1"}}
完成版コード
いままで紹介したコードとは少しことなる箇所があります。
import 'dart:convert';
import 'package:http/http.dart' as http;
void main() async {
final base64encoded =
base64.encode(latin1.encode('${API_KEY}:${API_KEY_SECRET}'));
final response = await http.post(
'https://api.twitter.com/oauth2/token',
headers: {'Authorization': 'Basic $base64encoded'},
body: {'grant_type': 'client_credentials'},
);
print(response.body);
final oauthToken = OauthToken.fromJson(jsonDecode(response.body));
// Map<String,List<String>>
final queryParameters = {
'expansions': ['pinned_tweet_id'],
'user.fields': [
'name',
'created_at',
'description',
],
};
// join request queryParameters
final params = queryParameters.entries.map((paramEntry) {
final value = paramEntry.value.join(',');
return '${paramEntry.key}=$value';
}).reduce((param1, param2) {
return '${param1}&${param2}';
});
final result = await http.get(
'https://api.twitter.com/2/users/by/username/Luecy1?$params',
headers: {'Authorization': 'Bearer ${oauthToken.accessToken}'},
);
print(result.body);
}
class OauthToken {
final String tokenType;
final String accessToken;
OauthToken(this.tokenType, this.accessToken);
OauthToken.fromJson(Map<String, dynamic> json)
: tokenType = json['token_type'],
accessToken = json['access_token'];
}
まとめ
従来のOauth1.0aのときはoauthライブラリを使わないとhmac-sha1というアルゴリズムで署名する必要があり、かなりハードルが高かった印象がありました。
今回のv2ではヘッダーやボディにbase64やあるいはそのまま指定するだけで利用でき、かなり簡単に使えました☺️
参考
APIキーやAPIキーシークレットを取得するのは若干ハードルが高いです。
有料書籍ですがその流れが記載されているので、おすすめです。
Discussion