APIを使わずにTwitterとYouTubeの埋め込み処理を行う
APIを使わずにTwitterとYouTubeのURLを入力したら埋め込み用に変換されて、記事に反映することが今回の最終目標です。
準備
ユーザーが入力するメディアタイプとURLの値を保存するためのカラムを用意します。
identifier
はURLを保存するためのカラムです。
insert.rb enum insert_type: { youtube: 0, twitter: 1 } validates :identifier, length: { maximum: 200 }
Twitterの埋め込み方法
タイムラインの埋め込みではなく、ツイートのURLを入力フォームに入力してツイートを表示する実装をしていきます。
公式Twitterに埋め込み用のURLを生成してくれるツールがあるのでそれを使用していきます。それでは公式のサイトを参考にして進めていきます。
まず最初に何でもいいのでツイートを開いて下記の画像の赤丸のついているリンクをクリックします。
するとこのような画面に移ります。
生成されたコードをコピーすると下記のような埋め込み用のHTMLが生成されました。
<blockquote class="twitter-tweet"> <p lang="ja" dir="ltr">わあ!ちょうちょはどこへ飛んでいくんだろう? <a href="https://t.co/BKmfg8wFy6">https://t.co/BKmfg8wFy6</a> <a href="https://t.co/YliyCv4LEQ">pic.twitter.com/YliyCv4LEQ</a> </p>— ダッフィーといっしょ【公式】 (@WithDuffy_TDS) <a href="https://twitter.com/WithDuffy_TDS/status/1385420681635004417?ref_src=twsrc%5Etfw">April 23, 2021</a> </blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
このHTMLの余分な情報の部分を削って、ツイートのURLの部分だけを抜き取ってみます。
<blockquote class="twitter-tweet"> <a href="https://twitter.com/WithDuffy_TDS/status/1385420681635004417?ref_src=twsrc%5Etfw"></a> </blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
上記のコードをもとに、TwitterのURLを送るフォームから入力されたデータをinsert.identifier
を使って出力されるように実装します。
※ slim表記になっています。
.insert-twitter blockquote.twitter-tweet a href="#{insert.identifier}" script async="" charset="utf-8" src="https://platform.twitter.com/widgets.js"
参考 : 【Twitter】埋め込み処理をAPIに投げずにローカルで行う - mizuff_diary
Youtubeの埋め込み方法
YouTubeの埋め込みも公式のサイトをみて進めていきたいと思います。
動画を検索して共有ページを開いて、埋め込むを選択します。
すると下記のような埋め込み用のHTMLが生成されるのでこれを編集していきます。
<iframe width="560" height="315" src="https://www.youtube.com/embed/yOAwvRmVIyo" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
これを見ると埋め込みURLの部分の記述は下記のようになっているのがわかります。
https://www.youtube.com/embed/動画のID
埋め込みURLと動画のURLを比較して見ると最後の動画のIDが一緒なので、フォームで送られたURLのIDの部分だけを抜き取って埋め込みURLとして出力すれば良いですね!
https://www.youtube.com/embed/yOAwvRmVIyo https://youtu.be/yOAwvRmVIyo
splitメソッド
ここでURLの下11桁を抜き取る時に少し躓いたので説明していきます。/
以下を抜き取るためにsplitメソッドを使っていきます。
/
で区切った配列を返してlast
を使って末尾の部分を取得しています。
https://youtu.be/yOAwvRmVIyo.split('/').last => yOAwvRmVIyo
insertモデルでURLの下11桁を抜き取るメソッドを定義しておきます。ビューが複雑になるのを防ぎます。
def split_id_from_youtube identifier.split('/').last if youtube? end
また下記のサイトを参考にしてYouTube出力画面を実装していきます。※ slim表記になっています。
YouTube 埋め込みプレーヤーとプレーヤーのパラメータ | YouTube IFrame Player API
.insert-youtube = content_tag 'iframe', nil, width: width, height: height, src: "https://www.youtube.com/embed/#{insert.split_id_from_youtube}", \ frameborder: 0, gesture: 'media', allow: 'encrypted-media', allowfullscreen: true
RSpecメモ
- なんで
js: true
が使われているのかについて、ブロック追加の画面がModalウィンドウだったので、JSをテストする必要があるから。
it 'プレビューした記事にYouTubeが埋め込まれていること', js: true do
- YouTubeのURLが適切に埋め込まれているか確認するための書き方。
expect(page).to have_selector("iframe[src='https://www.youtube.com/embed/yOAwvRmVIyo']")
# ページ内の一番最初の"更新する"を押す page.all('.box-footer')[0].click_button('更新する') sleep 1 click_on('プレビュー')
※ Twitterの埋め込みの時にwidgets.js
を読み込んでいるので少し時間がかかる。なので少し時間をおく必要がある。