学習記録

アウトプット用に作りました

APIを使わずにTwitterとYouTubeの埋め込み処理を行う

APIを使わずにTwitterYouTubeのURLを入力したら埋め込み用に変換されて、記事に反映することが今回の最終目標です。

準備

ユーザーが入力するメディアタイプとURLの値を保存するためのカラムを用意します。
identifierはURLを保存するためのカラムです。

insert.rb

enum insert_type: { youtube: 0, twitter: 1 }

validates :identifier, length: { maximum: 200 }


Twitterの埋め込み方法

タイムラインの埋め込みではなく、ツイートのURLを入力フォームに入力してツイートを表示する実装をしていきます。

公式Twitterに埋め込み用のURLを生成してくれるツールがあるのでそれを使用していきます。それでは公式のサイトを参考にして進めていきます。

ウェブサイトやブログにツイートを埋め込む方法

まず最初に何でもいいのでツイートを開いて下記の画像の赤丸のついているリンクをクリックします。 f:id:kimura34:20210427231646p:plain

するとこのような画面に移ります。 f:id:kimura34:20210427231836p:plain

生成されたコードをコピーすると下記のような埋め込み用の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>&mdash; ダッフィーといっしょ【公式】 (@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の埋め込みも公式のサイトをみて進めていきたいと思います。

動画と再生リストを埋め込む - YouTube ヘルプ

動画を検索して共有ページを開いて、埋め込むを選択します。 f:id:kimura34:20210427235443p:plain

すると下記のような埋め込み用のHTMLが生成されるのでこれを編集していきます。 f:id:kimura34:20210427235754p:plain

<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']")
  • Twitterの埋め込みの時にsleep 1を使っている理由は、Json parce処理でUPDATE完了前にプレビューしないよう待機している。
# ページ内の一番最初の"更新する"を押す
page.all('.box-footer')[0].click_button('更新する')
sleep 1 
click_on('プレビュー')

Twitterの埋め込みの時にwidgets.jsを読み込んでいるので少し時間がかかる。なので少し時間をおく必要がある。