34
Help us understand the problem. What are the problem?

posted at

updated at

Twitter Search API v1.1 と v2の 違いメモ

サマリ

Twitter の Search APIの仕様が、1.1 → 2 でかなり変わっていました。
仕様の全体像を掴むのに少し苦労したため、メモを残しておきます。

v1.1 と v2 の違い

ざっくり言うと

  • サービスレベルの変更
  • ツイート取得のメソッドの変更

の2つに分けられる。2つをそれぞれ把握しないと面食らう。

v2のサービスレベル

大きく分けて2レベル。

の2つに分かれる。しかし、「all」エンドポイント は、Academic Research Production のみ利用可能らしい。

v1.1 では「Standard」「Premium」など、契約によってSearchの範囲が変わったが、v2からは学術利用か、一般的な利用か、で検索可能なツイートの期間が変わるようだ。

v2エンドポイントを利用するための設定

Twitterの開発者画面から「Project」を設定し、そこに紐づく形で「App」を作成する必要がある。

下記のドキュメントに詳しく書かれている。

ツイートの取得方法

v1.1 までは、エンドポイントへのコールに対して全ての情報が含まれたJSONが返された。

v2では、基本的に「ツイート」「ツイートID」の二種類しか返ってこない。ツイートしたユーザーの詳細情報を取得するためには、オプションパラメータを設定する必要がある。

わかりづらいので、「Qiita公式アカウントのツイートを直近10件を取得」という条件で比較してみる。

v1.1 のリクエストとレスポンス

v1.1 のリクエスト

https://api.twitter.com/1.1/search/tweets.json?q=from:Qiita&count=10

v1.1のレスポンス

{
    "statuses": [
        {
            "created_at": "Thu Apr 29 06:30:07 +0000 2021",
            "id": 1387655418776899586,
            "id_str": "1387655418776899586",
            "text": "800LGTM! | 低レイヤーを学ぶための技術書をまとめてみる by @hareku908 https://t.co/KvnBiq6ihY",
            "truncated": false,
            "entities": {
                "hashtags": [],
                "symbols": [],
                "user_mentions": [
                    {
                        "screen_name": "hareku908",
                        "name": "hareku",
                        "id": 4765763846,
                        "id_str": "4765763846",
                        "indices": [
                            36,
                            46
                        ]
                    }
                ],
                "urls": [
                    {
                        "url": "https://t.co/KvnBiq6ihY",
                        "expanded_url": "https://bit.ly/3gMGLJt",
                        "display_url": "bit.ly/3gMGLJt",
                        "indices": [
                            47,
                            70
                        ]
                    }
                ]
            },
            "metadata": {
                "iso_language_code": "ja",
                "result_type": "recent"
            },
            "source": "<a href=\"https://buffer.com\" rel=\"nofollow\">Buffer</a>",
            "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": 341374118,
                "id_str": "341374118",
                "name": "Qiita (キータ) 公式",
                "screen_name": "Qiita",
                "location": "Tokyo, Japan",
                "description": "Qiita公式アカウントです。何かありましたら support@qiita.com までご連絡ください :) / Qiita Team @QiitaTeam / Qiita Jobs @QiitaJobs / 人気の投稿 @qiitapoi / Qiita Zine https://t.co/6dzvjAhEcx /",
                "url": "https://t.co/kT1Qi08l6z",
                "entities": {
                    "url": {
                        "urls": [
                            {
                                "url": "https://t.co/kT1Qi08l6z",
                                "expanded_url": "http://qiita.com",
                                "display_url": "qiita.com",
                                "indices": [
                                    0,
                                    23
                                ]
                            }
                        ]
                    },
                    "description": {
                        "urls": [
                            {
                                "url": "https://t.co/6dzvjAhEcx",
                                "expanded_url": "http://zine.qiita.com",
                                "display_url": "zine.qiita.com",
                                "indices": [
                                    134,
                                    157
                                ]
                            }
                        ]
                    }
                },
                "protected": false,
                "followers_count": 33742,
                "friends_count": 4,
                "listed_count": 787,
                "created_at": "Sun Jul 24 07:54:14 +0000 2011",
                "favourites_count": 800,
                "utc_offset": null,
                "time_zone": null,
                "geo_enabled": false,
                "verified": false,
                "statuses_count": 31376,
                "lang": null,
                "contributors_enabled": false,
                "is_translator": false,
                "is_translation_enabled": false,
                "profile_background_color": "FCFCFC",
                "profile_background_image_url": "http://abs.twimg.com/images/themes/theme1/bg.png",
                "profile_background_image_url_https": "https://abs.twimg.com/images/themes/theme1/bg.png",
                "profile_background_tile": false,
                "profile_image_url": "http://pbs.twimg.com/profile_images/1201406146822557696/ewFFvnAa_normal.jpg",
                "profile_image_url_https": "https://pbs.twimg.com/profile_images/1201406146822557696/ewFFvnAa_normal.jpg",
                "profile_banner_url": "https://pbs.twimg.com/profile_banners/341374118/1608287649",
                "profile_link_color": "55C500",
                "profile_sidebar_border_color": "BDDCAD",
                "profile_sidebar_fill_color": "DDFFCC",
                "profile_text_color": "272E23",
                "profile_use_background_image": false,
                "has_extended_profile": false,
                "default_profile": false,
                "default_profile_image": false,
                "following": null,
                "follow_request_sent": null,
                "notifications": null,
                "translator_type": "none",
                "withheld_in_countries": []
            },
            "geo": null,
            "coordinates": null,
            "place": null,
            "contributors": null,
            "is_quote_status": false,
            "retweet_count": 1,
            "favorite_count": 8,
            "favorited": false,
            "retweeted": false,
            "possibly_sensitive": false,
            "lang": "ja"
        },
        {
            "created_at": "Thu Apr 29 06:20:01 +0000 2021",
            "id": 1387652875547987969,
            "id_str": "1387652875547987969",
            "text": "100LGTM! | Hasuraで既存のPostgreSQLから爆速でGraphQL APIサーバーを構築する by @KawamataRyo https://t.co/2hSLn4XpxA",
            "truncated": false,
            "entities": {
                "hashtags": [],
                "symbols": [],
                "user_mentions": [
                    {
                        "screen_name": "KawamataRyo",
                        "name": "Kawamata Ryo",
                        "id": 927515451457806337,
                        "id_str": "927515451457806337",
                        "indices": [
                            60,
                            72
                        ]
                    }
                ],
                "urls": [
                    {
                        "url": "https://t.co/2hSLn4XpxA",
                        "expanded_url": "https://bit.ly/3nAgEqj",
                        "display_url": "bit.ly/3nAgEqj",
                        "indices": [
                            73,
                            96
                        ]
                    }
                ]
            },
            "metadata": {
                "iso_language_code": "ja",
                "result_type": "recent"
            },
            "source": "<a href=\"https://buffer.com\" rel=\"nofollow\">Buffer</a>",
            "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": 341374118,
                "id_str": "341374118",
                "name": "Qiita (キータ) 公式",
                "screen_name": "Qiita",
                "location": "Tokyo, Japan",
                "description": "Qiita公式アカウントです。何かありましたら support@qiita.com までご連絡ください :) / Qiita Team @QiitaTeam / Qiita Jobs @QiitaJobs / 人気の投稿 @qiitapoi / Qiita Zine https://t.co/6dzvjAhEcx /",
                "url": "https://t.co/kT1Qi08l6z",
                "entities": {
                    "url": {
                        "urls": [
                            {
                                "url": "https://t.co/kT1Qi08l6z",
                                "expanded_url": "http://qiita.com",
                                "display_url": "qiita.com",
                                "indices": [
                                    0,
                                    23
                                ]
                            }
                        ]
                    },
                    "description": {
                        "urls": [
                            {
                                "url": "https://t.co/6dzvjAhEcx",
                                "expanded_url": "http://zine.qiita.com",
                                "display_url": "zine.qiita.com",
                                "indices": [
                                    134,
                                    157
                                ]
                            }
                        ]
                    }
                },
                "protected": false,
                "followers_count": 33742,
                "friends_count": 4,
                "listed_count": 787,
                "created_at": "Sun Jul 24 07:54:14 +0000 2011",
                "favourites_count": 800,
                "utc_offset": null,
                "time_zone": null,
                "geo_enabled": false,
                "verified": false,
                "statuses_count": 31376,
                "lang": null,
                "contributors_enabled": false,
                "is_translator": false,
                "is_translation_enabled": false,
                "profile_background_color": "FCFCFC",
                "profile_background_image_url": "http://abs.twimg.com/images/themes/theme1/bg.png",
                "profile_background_image_url_https": "https://abs.twimg.com/images/themes/theme1/bg.png",
                "profile_background_tile": false,
                "profile_image_url": "http://pbs.twimg.com/profile_images/1201406146822557696/ewFFvnAa_normal.jpg",
                "profile_image_url_https": "https://pbs.twimg.com/profile_images/1201406146822557696/ewFFvnAa_normal.jpg",
                "profile_banner_url": "https://pbs.twimg.com/profile_banners/341374118/1608287649",
                "profile_link_color": "55C500",
                "profile_sidebar_border_color": "BDDCAD",
                "profile_sidebar_fill_color": "DDFFCC",
                "profile_text_color": "272E23",
                "profile_use_background_image": false,
                "has_extended_profile": false,
                "default_profile": false,
                "default_profile_image": false,
                "following": null,
                "follow_request_sent": null,
                "notifications": null,
                "translator_type": "none",
                "withheld_in_countries": []
            },
            "geo": null,
            "coordinates": null,
            "place": null,
            "contributors": null,
            "is_quote_status": false,
            "retweet_count": 0,
            "favorite_count": 4,
            "favorited": false,
            "retweeted": false,
            "possibly_sensitive": false,
            "lang": "ja"
        },

/*   以下、取得件数分のデータが表示される */


    ],
    "search_metadata": {
        "completed_in": 0.07,
        "max_id": 1387655418776899586,
        "max_id_str": "1387655418776899586",
        "next_results": "?max_id=1387547179829575679&q=from%3AQiita&count=10&include_entities=1",
        "query": "from%3AQiita",
        "refresh_url": "?since_id=1387655418776899586&q=from%3AQiita&include_entities=1",
        "count": 10,
        "since_id": 0,
        "since_id_str": "0"
    }
}

v2 のリクエストとレスポンス

v2のリクエスト

https://api.twitter.com/2/tweets/search/recent?max_results=10&query=from:Qiita

v2のレスポンス

{
    "data": [
        {
            "id": "1387652875547987969",
            "text": "100LGTM! | Hasuraで既存のPostgreSQLから爆速でGraphQL APIサーバーを構築する by @KawamataRyo https://t.co/2hSLn4XpxA"
        },
        {
            "id": "1387647837983412224",
            "text": "300LGTM! | 機械学習×投資の無料ツールまとめ ~Awesome Algorithmic Trading~ by @cryptrader2020 https://t.co/UO3ZA8mRkj"
        },
        {
            "id": "1387642808182452225",
            "text": "4000LGTM! | 使えるRSpec入門・その1「RSpecの基本的な構文や便利な機能を理解する」 by @jnchito https://t.co/3b255fR01l"
        },
        {
            "id": "1387637775919419393",
            "text": "50LGTM! | [Pythonによる科学・技術計算] やさしい分子動力学シミュレーション, 2次元系, NVEアンサンブル,熱・統計物理学 https://t.co/ELvBHrXVnx"
        },
        {
            "id": "1387627710198030337",
            "text": "50LGTM! | 【個人開発】ポモドーロテクニックとTodoリストを組み合わせた時間管理アプリを作りました by @miii01220 https://t.co/Y5u1rgHZAf"
        },
        {
            "id": "1387625188330704897",
            "text": "50LGTM! | ペアプロ・モブプロでメンバーが驚くほど成長した話 by @kojimadev https://t.co/aq8VwBL40h"
        },
        {
            "id": "1387607576032985094",
            "text": "1100LGTM! | SREやクラウドエンジニアが読むと良さげな本まとめ by @tmknom https://t.co/eihzWpp9H9"
        },
        {
            "id": "1387589960555974657",
            "text": "200LGTM! | iOS14でのIDFA取得 https://t.co/RD6dfMlbpZ"
        },
        {
            "id": "1387547179829575680",
            "text": "50LGTM! | ポストエフェクトクエスト - 波長方向の積分マジ大事という話 - https://t.co/v2CW7HqEhH"
        },
        {
            "id": "1387544662286733313",
            "text": "1600LGTM! | Linuxディレクトリ構造 https://t.co/xHjpczl4hd"
        }
    ],
    "meta": {
        "newest_id": "1387652875547987969",
        "oldest_id": "1387544662286733313",
        "result_count": 10,
        "next_token": "b26v89c19zqg8o3fosttqjg5j32790ogxv7mnb19xcghp"
    }
}

v2 のレスポンスはかなりスリムになっていることが分かる。
そして、ツイート以外のデータは含まれていない。

v2で、ユーザー情報や、そのほかのデータを取得する場合は以下のようにリクエストを行う。

https://api.twitter.com/2/tweets/search/recent?max_results=10&tweet.fields=created_at&expansions=author_id&user.fields=name,username,url,description&query=from:Qiita

レスポンスはこうなる

{
    "data": [
        {
            "text": "800LGTM! | 低レイヤーを学ぶための技術書をまとめてみる by @hareku908 https://t.co/KvnBiq6ihY",
            "author_id": "341374118",
            "created_at": "2021-04-29T06:30:07.000Z",
            "id": "1387655418776899586"
        },
        {
            "text": "100LGTM! | Hasuraで既存のPostgreSQLから爆速でGraphQL APIサーバーを構築する by @KawamataRyo https://t.co/2hSLn4XpxA",
            "author_id": "341374118",
            "created_at": "2021-04-29T06:20:01.000Z",
            "id": "1387652875547987969"
        },
        {
            "text": "300LGTM! | 機械学習×投資の無料ツールまとめ ~Awesome Algorithmic Trading~ by @cryptrader2020 https://t.co/UO3ZA8mRkj",
            "author_id": "341374118",
            "created_at": "2021-04-29T06:00:00.000Z",
            "id": "1387647837983412224"
        },
        {
            "text": "4000LGTM! | 使えるRSpec入門・その1「RSpecの基本的な構文や便利な機能を理解する」 by @jnchito https://t.co/3b255fR01l",
            "author_id": "341374118",
            "created_at": "2021-04-29T05:40:01.000Z",
            "id": "1387642808182452225"
        },
        {
            "text": "50LGTM! | [Pythonによる科学・技術計算] やさしい分子動力学シミュレーション, 2次元系, NVEアンサンブル,熱・統計物理学 https://t.co/ELvBHrXVnx",
            "author_id": "341374118",
            "created_at": "2021-04-29T05:20:01.000Z",
            "id": "1387637775919419393"
        },
        {
            "text": "50LGTM! | 【個人開発】ポモドーロテクニックとTodoリストを組み合わせた時間管理アプリを作りました by @miii01220 https://t.co/Y5u1rgHZAf",
            "author_id": "341374118",
            "created_at": "2021-04-29T04:40:01.000Z",
            "id": "1387627710198030337"
        },
        {
            "text": "50LGTM! | ペアプロ・モブプロでメンバーが驚くほど成長した話 by @kojimadev https://t.co/aq8VwBL40h",
            "author_id": "341374118",
            "created_at": "2021-04-29T04:30:00.000Z",
            "id": "1387625188330704897"
        },
        {
            "text": "1100LGTM! | SREやクラウドエンジニアが読むと良さげな本まとめ by @tmknom https://t.co/eihzWpp9H9",
            "author_id": "341374118",
            "created_at": "2021-04-29T03:20:01.000Z",
            "id": "1387607576032985094"
        },
        {
            "text": "200LGTM! | iOS14でのIDFA取得 https://t.co/RD6dfMlbpZ",
            "author_id": "341374118",
            "created_at": "2021-04-29T02:10:01.000Z",
            "id": "1387589960555974657"
        },
        {
            "text": "50LGTM! | ポストエフェクトクエスト - 波長方向の積分マジ大事という話 - https://t.co/v2CW7HqEhH",
            "author_id": "341374118",
            "created_at": "2021-04-28T23:20:01.000Z",
            "id": "1387547179829575680"
        }
    ],
    "includes": {
        "users": [
            {
                "username": "Qiita",
                "id": "341374118",
                "name": "Qiita (キータ) 公式",
                "url": "https://t.co/kT1Qi08l6z",
                "description": "Qiita公式アカウントです。何かありましたら support@qiita.com までご連絡ください :) / Qiita Team @QiitaTeam / Qiita Jobs @QiitaJobs / 人気の投稿 @qiitapoi / Qiita Zine https://t.co/6dzvjAhEcx /"
            }
        ]
    },
    "meta": {
        "newest_id": "1387655418776899586",
        "oldest_id": "1387547179829575680",
        "result_count": 10,
        "next_token": "b26v89c19zqg8o3fosttqjg5nlv28d3xdrvv4rx3cqk59"
    }
}

レスポンスデータの情報が厚くなっていることが分かる。

v1.1 から v2 への移行

v1.1 ユーザー向けに、移行ガイドが公開されている。

…が、普通にAPIリファレンス見ながら書き直した方が早いかも。

APIリファレンスはこちら。

そのほか

Twitter API v2 開発者のために、Postman用のコレクションが公開・頒布されていました。

説明ページ
https://developer.twitter.com/en/docs/tools-and-libraries/using-postman

Postman側のコレクション配布ページ
https://documenter.getpostman.com/view/9956214/T1LMiT5U

Postmanを使っている人は、上記のコレクションを使うのがおすすめ。パラメータの設定が楽で、v2の仕様を手っ取り早く把握できます。

以上、参考になれば幸いです。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
34
Help us understand the problem. What are the problem?