mizuff_diary

もうあったものと、まだなかったもの

【Twitter】埋め込み処理をAPIに投げずにローカルで行う

概要

f:id:mizuff:20171219182554p:plain:w500
TwitterにはWebサイトへの埋め込み用コードを取得できる機能が存在し、これはAPIとしても提供されています(GET statuses/oembed — Twitter Developers)。このAPIを通して取得できるのは1ツイート分/1アクセスであり、大量のツイートを埋め込みたい場合にいちいちAPIに投げていてはかなりの時間を要してしまいます。
そこで、APIが行う処理を肩代わりし、埋め込み用コードをローカルで作成することで処理時間の短縮を図ります。

一般的なツイート埋め込み処理の流れ

1.APIに埋め込みたいツイートのURLを投げる

GET 
https://publish.twitter.com/oembed?url=https://twitter.com/imascg_stage/status/774134264107372548

2.返ってきたJSONのhtml要素を埋め込みに利用する

{
 "url":"https://twitter.com/imascg_stage/status/774134264107372548",
 "author_name":"スターライトステージ",
 "author_url":"https://twitter.com/imascg_stage",
 "html:"<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">『見つめて… ! もっと強く、強くです ! ムムムーン ! …曲がりませんね』<br><br>SSレアの堀裕子ちゃん登場です!<a href="https://t.co/mIoEjCBQs4">https://t.co/mIoEjCBQs4</a> <a href="https://twitter.com/hashtag/%E3%83%87%E3%83%AC%E3%82%B9%E3%83%86?src=hash&ref_src=twsrc%5Etfw">#デレステ</a> <a href="https://t.co/Ffflbfgs4b">pic.twitter.com/Ffflbfgs4b</a></p>— スターライトステージ (@imascg_stage) <a href="https://twitter.com/imascg_stage/status/774134264107372548?ref_src=twsrc%5Etfw">September 9, 2016</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>", 
 "width":"550",
 "height":"null",
 "type":"rich",
 "cache_age":"3153600000",
 "provider_name":"Twitter",
 "provider_url":"https://twitter.com",
 "version":"1.0",
}

ここで取得できるhtmlをwidgets.jsがレンダリングしてくれることで、いわゆる埋め込みツイートが完成します。
omit_scriptパラメータをtrueにした場合、ウィジェット用のscript要素は追加されません。大量のツイートを埋め込みたいときは他の場所でwidgets.jsを読み込んであげるのがよいでしょう。

この処理をHerokuアプリで行った結果

f:id:mizuff:20171219172634p:plain:w300
……100件単位のツイートをAPIに投げてみたところ、タイムアウトしました。 タイムアウト基準が30秒でツイート自体の取得が10秒ほどなので、埋め込み用コードの取得が相当ボトルネックになっていることがわかります。

埋め込み用コードを自作する

そこで埋め込み用コード作成をAPIに投げるのではなく、ローカルで行うことで処理時間を短縮しようというのが本記事です。
widgets.jsがレンダリングしてくれるように、見よう見まねでhtmlを成形していきます。
結論から言うと、これだけの情報があればOKです。

<blockquote class="twitter-tweet"><a href="https://twitter.com/imascg_stage/status/774134264107372548"></a></blockquote>

APIの処理を忠実に再現する必要はなく、ツイートのURL(細かく言えばscreen_nameとid)さえあればwidgets.jsがうまく処理してくれます。例えばツイート内のURLを正規表現で抽出して<a>タグを付加して……といったことは不要です。
あとは言語設定なり、レンダリング前の表示用に本文なりユーザー名なりを補ってあげるとよいでしょう。
レンダリングはweb上のwidgets.jsに任せることになるのですが、埋め込み用コードをローカルで作成するだけでも処理時間をかなり短縮できます。