Chapter 02無料公開

自分のツイートを取得してみよう

/bin/zsh
/bin/zsh
2020.10.03に更新

エンドポイントの確認

特定のユーザーのツイート一覧を取得するエンドポイントは/statuses/user_timelineです。

公式ドキュメント: Get Tweet timelines

ユーザーの指定はuser_id(整数値)またはscreen_name(@の後ろの名前)で行います。
今回はscreen_nameを使ってみます。

他にいくつかパラメータはありますが、まずはシンプルにこちらで確認してみましょう。
試しにトランプ大統領 (@realdonaldtrump) のツイートを取得できる以下のエンドポイントをブラウザで開いてみてください。

https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=realDonaldTrump

以下のようなエラーメッセージが表示されたかと思います。

{"errors":[{"code":215,"message":"Bad Authentication data."}]}

そうです、認証が必要です。
対象がパブリックなアカウントであっても、Twitter API を利用する際は必ず認証をしなければいけません。

APIキーの取得

すでに開発者登録が済んでいる方はこのまま読み進めてください。
まだの方は、Chapter3に申請フローをまとめましたので、そちらに従って登録を済ませてAPIキーの取得をお願いします。

認証

Twitter API の認証方法は3種類あります。

  • OAuth 1.0
  • OAuth 2.0 Bearer Token
  • Basic Authentication

Basic 認証は覚えなくていいです。
OAuth 1.0 と 2.0 の使い分けですが、エンドポイントごとに利用できる認証方法が異なります。

基本的には 1.0 の方を使えばよく、対応しているエンドポイントでは手軽な 2.0 を使う、という考え方で良いかと思います。(この辺りの違いは後のチャプターで説明します)

今回はPull user timelinesの API になるので、OAuth 2.0 で認証を試みます。
開発者登録時に3つのクレデンシャルが発行されたかと思いますが、使用するのは [Bearer Token] のみです。

実装

使用するライブラリをCargo.tomlに追加しておきます。

# Cargo.toml

[dependencies]
reqwest = "0.10.8"
url = "2.1.1"
tokio = { version = "0.2.22", features = ["full"] }
// main.rs

extern crate reqwest;
use reqwest::Client;

const SCREEN_NAME: &str = "bin_zsh";

#[tokio::main]
async fn main() {
    let url = format!("https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name={}", SCREEN_NAME);
    let client = Client::new().get(&url);
    let res = client.send().await.unwrap().text().await.unwrap();
    println!("{}", res);
}

SCREEN_NAMEには自分のアカウントのスクリーンネームを入れてみてください。

reqwest はデフォルトで非同期なので、ランタイムとして tokio を使います。

少々雑ですがあとでリファクタリングするとして、シンプルなリクエストを送るにはこれだけです。

cargo runで実行してみましょう。

{"errors":[{"code":215,"message":"Bad Authentication data."}]}

まだ認証を組み込んでいないので、ブラウザで確認した時と同じエラーが出たかと思います。

では、OAuth2.0 の認証を追加していきましょう。

// main.rs

let token = std::env::var("TOKEN").unwrap();
let token = format!("Bearer {}", token);
let client = Client::new().get(&url).header("authorization", token);

先ほどの [Bearer Token] を環境変数から入力する形にします。
authorization: Bearer xxxxxxxxxという形式でHTTPヘッダーを付与します。

トークンを環境変数として与えて実行してみてください。

TOKEN=AAAAAxxxxxxx cargo run

ずらずらとレスポンスが出力されたかと思います。
読みにくいですがとりあえず動作確認は取れました。

[{"created_at":"Thu Sep 24 12:39:05 +0000 2020","id":1309110101815500801,"id_str":"1309110101815500801","text":"\u3010\u4eba\u751f\u30b2\u30fc\u30e0\u3067\u6b62\u307e\u3063\u305f\u3089\u30d8\u30b3\u3080\u30de\u30b9\u7b2c1\u4f4d\u3011\n\n\u8a18\u4e8b\u3092\u66f8\u3044\u3066\u308b\u9014\u4e2d\u3067\u30b3\u30f3\u30bd\u30fc\u30eb\u306e\u898b\u305f\u76ee\u304c\u5909\u308f\u308b\u3002\u632f\u308a\u51fa\u3057\u306b\u623b\u308b\uff08\u30ad\u30e3\u30d7\u30c1\u30e3\u304b\u3089\u3084\u308a\u76f4\u3057\uff09\u3002\u2190\u30a4\u30de\u30b3\u30b3","truncated":false,"entities":{"hashtags":[],"symbols":[],"user_mentions":[],"urls":[]},"source":"\u003ca href="https://mobile.twitter.com" rel="nofollow"\u003eTwitter Web App\u003c/a\u003e","in_reply_to_status_id":null,"in_reply_to_status_id_str":null,"in_reply_to_user_id":null,"in_reply_to_user_id_str":null,"in_reply_to_screen_name":null,"user":{"id":1291928874285060099,"id_str":"1291928874285060099",
(以下略)

それでは次のチャプターから、扱いやすいようにリファクタリングを施しながら、さらに進んだ使い方を試していきたいと思います。