Tweepyで複数動画を持つツイートの動画URL取得時にハマったときの解決法メモ

## 結論
**expansions**に`attachments.media_keys`を
**media_fields**に`variants`を与えてやればいい。
欲しい物は`includes`の中の`['media'][i]['variants']`の中に入っている。
また、動画と画像が混在しているツイートの場合には**media_fields**を`["variants","url"]`とする。
以下にコードを示す。

```Python:code.py
import tweepy

#v2.0
client = tweepy.Client(bearer_token=TWITTERAPI_BEARER_TOKEN)
res = client.get_tweet(id=id,expansions="attachments.media_keys",media_fields="variants")
for i in range(len(res.includes['media'])):
    print(res.includes['media'][i]['variants'])
```

## そもそも...
今まで1個だけの動画取得の場合はv1.1の`statuses/show/:id`で事足りていたのだが、
複数の動画が1ツイートに入ってたらどうなるんだろ？と思って試しにリクエストしたのがきっかけだった。
```Python:code.py
#v1.1
auth = tweepy.OAuth1UserHandler(consumer_key=TWITTERAPI_CONSUMER_KEY,consumer_secret=TWITTERAPI_CONSUMER_SECRET,access_token=TWITTERAPI_ACCESS_TOKEN,access_token_secret=TWITTERAPI_ACCESS_TOKEN_SECRET)
api = tweepy.API(auth)
#ここでtweet_mode="extended"にしないとツイート+動画URLで140文字を超える時におかしくなるので注意
res = api.get_status(id=id,trim_user=True,include_entities=True,tweet_mode="extended")
print(res)
```
そうしたら最初の1つの動画URLしか取得できなかった。(私が試した限りでは)

## ハマり1: ライブラリだけじゃなくAPIのドキュメント
オプション引数について[tweepyのドキュメント](https://docs.tweepy.org/en/stable/expansions_and_fields.html)がぼやっとしすぎてわかりにくかったため、コードを書いてエラーの文章から使えるパラメータを知るという無駄なことをしていた。
また、[同じ疑問のissue](https://github.com/tweepy/tweepy/issues/2011)も調べたら出てきたが、クレクレに対しての無視という姿勢を貫くのか「tweepyはミックスメディアもサポートしてる」という回答だけだった。
そもそも最初からTwitter API v2のドキュメントを読んどけばよかった。

## ハマり2: v2での方針変更
ただidだけでリクエストするとツイートについての基本的な情報しか出てこない。
そのため、メディア,位置情報,投票などについては
①expansionを使って**取得したい追加情報**(メディアや位置情報など)**を指定する**([Available expansions for Tweet payloads](https://developer.twitter.com/en/docs/twitter-api/expansions)を参照)
②**追加情報のうちデフォルトで返答に含まれない値**を`hoge_fields="fuga"`というような**フィールドパラメータを使って指定する**(mediaのうちのwidthなら`media_fields="width"`となる。[APIドキュメントのQuery parameters項](https://developer.twitter.com/en/docs/twitter-api/tweets/lookup/api-reference/get-tweets-id)を参照)
の**合わせ技**で、情報が得られるようになる。
(また、①も②も複数条件指定でき、その場合は文字列のリストで与えてやる。)

このように、場合に応じて必要なデータだけを取得できるようになったのである。
v1.1→v2.0への変更で方針がこのように変わったことを掴んどけばよかった。
んでこのフィールドパラメータについて記述したものこそが[先述したtweepyのドキュメント](https://docs.tweepy.org/en/stable/expansions_and_fields.html)なんだなと気づいた。
ただやっぱりわかりにくいので、支持されてるライブラリのドキュメントの整備者には面倒でもどのフィールドパラメータではどれが使えるってのを書いておいて欲しいなと思った。

## ハマり3: urlじゃなくvariants
確かにurlというパラメータは「これに全部メディアのurlが入ってくるんだろうなぁ」と思わせる名前だが、これはあくまで**画像ツイートの場合に**ここに画像の元URLが入ってくるよ、ということである。
[Twitter API v2 data dictionary](https://developer.twitter.com/en/docs/twitter-api/data-dictionary/object-model/media)にもご丁寧に
*Returns a Media object with a URL field for **photos***と書いてある。
また、同ドキュメントを見ていくと、動画のURLらしきものが、**variants**という配列の中に入っているのがわかる...(複数の解像度を持っていたりするからか？)
|画像  |動画  |
|---|---|
|**url**  |**variants**  |



## 教訓
APIを使うサービスで分からんことがあったら、ライブラリのドキュメントだけじゃなく**API自体のドキュメント**もちゃんと読むようにしよう。


## 未だにわからんこと
複数動画を1ツイートにまとめて投稿できるようになったと公式から[アナウンス](https://blog.twitter.com/ja_jp/topics/product/2022/introducing_mixed_media_videos_images_gifs_together_one_tweet)があったのは2022/10/7だが、
・なぜv2にしか実装されなかったのか
・v1.1でもやる方法はあるのか
ソース等わかる人いたらコメント下さい。
また、[公式チュートリアルのRequesting additional fields and objects.](https://developer.twitter.com/en/docs/twitter-api/data-dictionary/using-fields-and-expansions)によるとフィールドパラメータのみでニーズを満たせる場合もあるっぽいです。そこもよくわかりませんでした。

## これから
・Twitter APIの有料化に怯える
・複数動画を含むツイを投げられた時も処理できるようにGASのスクリプトを書き直す