Twitterデータの tweet.js を読み込んで全ツイート履歴を表示するツール「tweet.js loader」の技術面
はじめに
Twitterデータの tweet.js を読み込んで全ツイート履歴を表示するツール「tweet.js loader」の紹介 で作った tweet.js loader の技術面について整理した。
TL;DR
- 主に埋め込み用ツイートの表示で苦労した話をまとめた
- Vue + GitHub Pages の設定例についても少しまとめた
目次
環境・条件
1 | $ sw_vers |
詳細
リポジトリ: 17number/tweet-js-loader
使用しているもの
レベル感とか粒度とか適当だけど、以下を使用して作成。
より細かく見たい人は package.json を参照。
ポイントや苦労した箇所など
ツイートの埋め込み
埋め込み用コード
ツイートの埋め込み自体は Twitter Publish で、URL を指定すると HTML コードが取得できる。
↑は https://twitter.com/kantei/status/1183296748027969539 を指定し生成された HTML コードを埋め込んだもので、コードとしては以下のようなものが生成される。
1 | <blockquote class="twitter-tweet"> |
途中に挟まっているテキスト(【お知らせ】 など)は、ツイートが消された時でも最低限の情報は表示できるようにというもの。なので、埋め込みに必要な情報だけに極限まで削ると以下だけで良い。
1 | <blockquote class="twitter-tweet"> |
https://platform.twitter.com/widgets.js を script タグで読み込んだ時(= JS 実行時)に、<blockquote class="twitter-tweet"> で囲まれた部分を解析して、<twitter-widget> というタグに置き換えている模様。
1 | <twitter-widget class="twitter-tweet twitter-tweet-rendered" id="twitter-widget-0" style="..." data-tweet-id="1183296748027969539"> |
widgets.js の挙動
前セクションで、<blockquote class="twitter-tweet"> が widgets.js の読み込み完了時に置き換わることが分かったが、大量に <blockquote class="twitter-tweet"> を生成後に widgets.js を読み込むとエラーとなった。
Developer Tools の Network タブで確認したところ、414 URI Too Long。
どうやら https://cdn.syndication.twimg.com/tweets.json に対して情報を要求しているが、クエリパラメータとして Tweet ID を指定しているため埋め込みが多すぎると「URI が長すぎるよ!」とエラーになる模様。(以下のように ids で tweet_id をカンマ(%2C)区切りで指定)
1 | https://cdn.syndication.twimg.com/tweets.json?callback=__twttr.callbacks.cb0&ids=1160544024694054912%2C1185383050273669120&lang=en&suppress_response_codes=true&theme=light&tz=GMT%2B0900` |
ここは Vue Router を導入して、ページネーションで表示件数を制限することで対応した。(ここでも苦労したが、その話は に記載)
なお、axios で https://cdn.syndication.twimg.com/tweets.json を直接叩くことも試みたが、CORS の設定であっさりと弾かれたのでまぁまぁ粘ったけど断念した。
screen_name の省略
ここであらためて Twitterデータ から取得した tweet.js の構造を見てみる。
1 | window.YTD.tweet.part0 = [ { |
分かりづらいかもしれないが、実はツイート主の screen_name はどこにも含まれていない。
ツイート主(の screen_name)を特定しようと思うと、Twitter API - GET collections/show に Tweet ID(https://twitter.com/screen_name/status/**1234** の最後の数値部分。↑だと id とか id_str の部分)を指定して実行するしか無さそうだが、それはやりたくない(面倒だし、API Rate Limit の話もあるし)。
そこで screen_name を使わない方向で検討、以前は https://twitter.com/-/status/1234 みたいに、- を使えば screen_name を指定しなくても良かったがいつの間にか使えなくなっていた。
当然同じ疑問を持つ人が居て解決策まで提示してくれていた。
現在は https://twitter.com/i/status/1234 のように - ではなく i を指定すれば良い模様。ということで、twitter.js のデータを元に以下の HTML を生成し、最後に https://platform.twitter.com/widgets.js を読み込むこととした。
1 | <blockquote class="twitter-tweet"> |
ページ遷移時に埋め込みツイートを削除
ここまででツイートの埋め込み表示が実現できたが、Vue Router によるページ遷移後に埋め込みツイートが切り替わってくれなかった。
Tweet.vue で <blockquote class="twitter-tweet"> の部分を描画しているのだが、widgets.js で <twitter-widget> に置き換わってしまうため、ページ遷移後に描画対象の HTML 要素が無くて上手くいっていないようだった。
そこで無理やりではあるが、ナビゲーションガード の beforeRouteUpdate を使って以下の処理を行っている。
<twitter-widget>の削除- 読み込み済の
widgets.jsの削除
その後、Tweet.vue の updated フック内で以下を実施。
<blockquote>要素が無ければinsertAdjacentHTMLで追加
最後に Home.vue の updated フック内で以下を実施。
widgets.jsの読み込み
かなり無理やり実現している(もっとうまくできそう)感があるが、Vue.js にそこまで詳しいわけじゃないのでいったん良しとする。
最終的にこうなった
n(=60にした)件ずつ埋め込みツイートの元ネタ(<blockquote class="twitter-tweet">)を埋め込み- ページ遷移したら、以下を実施することで各ページごとの埋め込みツイート表示を実現
- 現在の埋め込みツイート(
<twitter-widget>)を削除して - 埋め込みツイート用のスクリプト(
widgets.js)を削除して - 埋め込みツイートの元ネタ(
<blockquote>)を生成して - 埋め込みツイート用のスクリプト(
widgets.js)を読み込む
- 現在の埋め込みツイート(
Vue CLI + GitHub Pages
この辺の話は別記事(Vue CLI で作った Vue Router 利用プロジェクトを GitHub Pages で公開する方法)にもまとめた。
ビルド結果出力先の設定
docs ディレクトリを GitHub Pages の対象に設定できるので、vue.config.js に outputDir オプションを追加して docs にビルド結果を出力するように変更。あと filenameHashing も合わせてオフにした。
1 | module.exports = { |
publicPath の設定
(設定やディレクトリ構成次第ではあるが) docs/js/hoge.js は https://username.github.io/repository/js/hoge.js に配置される。
だが、デフォルトの設定だと https://username.github.io/js/hoge.js を読みにいくような HTML が出力されるので、vue.config.js に publicPath の設定を追加する。
1 | module.exports = { |
Vue Router + GitHub Pages
Vue Router を https://username.github.io/repository/ というリポジトリ名ありの URL で利用する場合、new VueRouter するときに base オプションを指定する。
1 | new Router({ |
config/dev.env.js と config/prod.env.js を用意して、base: process.env.BASE_URL, としても良い。
1 | // config/dev.env.js |
※vue-routerのgithub-pages用設定 - Qiita を参考に ROOT_BASE を使ったら、何故か上手くいかなくてハマった。ググっても同事例が出てこなかったので、自分の環境だけかもしれない。
まとめ
- 主に埋め込み用ツイートの表示で苦労した話をまとめた
- Vue + GitHub Pages の設定例についても少しまとめた
その他・メモ
tweet.js loader 使ってみて。
紹介記事: Twitterデータの tweet.js を読み込んで全ツイート履歴を表示するツール「tweet.js loader」の紹介
参考文献
- Vue-router を使ったときに URL は変わったのに画面に反映されないとき - Qiita
- Vue Routerでのページネーションライフサイクル - Qiita
- vue-routerのナビゲーションガードを利用してページ遷移時のローディング処理をまとめる - Mobile Factory Tech Blog
- Vue RouterでbeforeEnterとwindow.locationを組み合わせて外部サイトへページ遷移させてみた · polidog lab++
- GitHub Pages
- Vue.js
- Vue CLI
- Vue Router
- Bulma
- FontAwesome
- Pug
- Sass
関連記事
- Cordova アプリに Twitter Timeline の埋め込み
- Twitterデータの tweet.js を読み込んで全ツイート履歴を表示するツール「tweet.js loader」を作った
- Chart.js(vue-chartjs) でツールチップの表示内容を変更
- Vue.js で日本語変換での誤発火を抑止しつつ Enter キーで Submit
- Vue で子コンポーネントのメソッドをコールする
- apertureless/vue-chartjs でチャートの高さ(や幅、サイズ)を変更
- JavaScript で URL のクエリパラメータを操作する方法
- jQuery Select2 で、初期値の設定と選択状態のクリア