Twitter のツイートを埋め込む HTML を oEmbed API を用いて取得する

Twitter のつぶやきは、個々のつぶやきから手作業で埋め込みコードを取得することもできますが、API を使えば [oEmbed](https://oembed.com/) という埋め込み用フォーマットをツイート URL から取得することができます。

[Twitter の oEmbed API](https://developer.twitter.com/en/docs/tweets/post-and-engage/api-reference/get-statuses-oembed)を使います。リンク先にサンプルレスポンスや色々付けれるクエリパラメータが載っています。

今回は [ruby-oembed](https://github.com/ruby-oembed/ruby-oembed) で取得しました。

```sh
$ irb -rpp
irb(main):001:0> require 'oembed'
=> true
irb(main):002:0> OEmbed::Providers.register(OEmbed::Providers::Twitter)
=> [#<OEmbed::Provider:0x000055e464082ef8 @endpoint="https://publish.twitter.com/oembed", @urls=[/^https:\/\/([^\.]+\.)?twitter\.com\/(.*?)\/status\/(.*?)/], @format=:json>]
irb(main):003:0> OEmbed::Providers::Twitter.endpoint += "?=omit_script=true"
irb(main):004:0> resource = OEmbed::Providers.get("https://twitter.com/aximovich/status/125
1416407582994435")
irb(main):005:0> resource
=>JSONがオブジェクトになったもの
```

`omit_script` というパラメータを true で渡すことで、今回は埋め込みに必要なスクリプトをロードするタグを省いています。

返ってくる json （がオブジェクトになったもの）は以下です。

```rb
irb(main):006:0> resource.fields
=>
{
  "url"=>"https://twitter.com/aximovich/status/1251416407582994435",
  "author_name"=>"Aximov",
  "author_url"=>"https://twitter.com/aximovich",
  "html"=>"<blockquote class=\"twitter-tweet\"><p lang=\"und\" dir=\"ltr\"><a href=\"https://twitter.com/hashtag/%E3%81%A9%E3%81%86%E3%81%B6%E3%81%A4%E3%81%AE%E6%A3%AE?src=hash&amp;ref_src=twsrc%5Etfw\">#どうぶつの森</a> <a href=\"https://twitter.com/hashtag/AnimalCrossing?src=hash&amp;ref_src=twsrc%5Etfw\">#AnimalCrossing</a> <a href=\"https://twitter.com/hashtag/ACNH?src=hash&amp;ref_src=twsrc%5Etfw\">#ACNH</a> <a href=\"https://twitter.com/hashtag/NintendoSwitch?src=hash&amp;ref_src=twsrc%5Etfw\">#NintendoSwitch</a> <a href=\"https://t.co/PuDKkaGIMr\">pic.twitter.com/PuDKkaGIMr</a></p>&mdash; Aximov (@aximovich) <a href=\"https://twitter.com/aximovich/status/1251416407582994435?ref_src=twsrc%5Etfw\">April 18, 2020</a></blockquote>\n",
  "width"=>550,
  "height"=>nil,
  "type"=>"rich",
  "cache_age"=>"3153600000",
  "provider_name"=>"Twitter",
  "provider_url"=>"https://twitter.com",
  "version"=>"1.0"
}
```

上の例では `resource.html` とすれば実際に埋め込むための HTML を取得することができます。

```sh
irb(main):007:0> resource.html
=> "<blockquote class=\"twitter-tweet\"><p lang=\"und\" dir=\"ltr\"><a href=\"https://twitter.com/hashtag/%E3%81%A9%E3%81%86%E3%81%B6%E3%81%A4%E3%81%AE%E6%A3%AE?src=hash&amp;ref_src=twsrc%5Etfw\">#どうぶつの森</a> <a href=\"https://twitter.com/hashtag/AnimalCrossing?src=hash&amp;ref_src=twsrc%5Etfw\">#AnimalCrossing</a> <a href=\"https://twitter.com/hashtag/ACNH?src=hash&amp;ref_src=twsrc%5Etfw\">#ACNH</a> <a href=\"https://twitter.com/hashtag/NintendoSwitch?src=hash&amp;ref_src=twsrc%5Etfw\">#NintendoSwitch</a> <a href=\"https://t.co/PuDKkaGIMr\">pic.twitter.com/PuDKkaGIMr</a></p>&mdash; Aximov (@aximovich) <a href=\"https://twitter.com/aximovich/status/1251416407582994435?ref_src=twsrc%5Etfw\">April 18, 2020</a></blockquote>\n"
```

埋め込むために必要な準備は[こちら](https://developer.twitter.com/en/docs/twitter-for-websites/javascript-api/guides/set-up-twitter-for-websites)をご参照ください。

今回は `omit_script=true` としましたが、これを付けずに取得した HTML はそのまま埋め込むことができます。（ただし個々のツイートごとに埋め込み用スクリプトが全部ついているHTMLになります）

なお取得した文字列はエスケープされていますので、使用する際には HTML に戻す必要があります。 たとえば Rails であれば [sanitize](https://api.rubyonrails.org/classes/ActionView/Helpers/SanitizeHelper.html#method-i-sanitize) を用いることが推奨されます。（ただし sanitize では script タグが削られることに注意してください。） Node.js なら [decodeURI](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURI) か、他にも [html-entities](https://www.npmjs.com/package/html-entities) といったデコードパッケージがたくさんあります。

-----

今回は Ruby で取得しましたが、 API が叩ければ curl でもなんでもいいので言語はまったく問題ではありません。また Twitter の oEmbed API は rate limit もなければ API key なども不要ですから、今日から試してみることができます。詳しくは[リファレンス](https://developer.twitter.com/en/docs/tweets/post-and-engage/api-reference/get-statuses-oembed)をご覧ください。