LoginSignup
4
2

More than 1 year has passed since last update.

【Rails】APIを使わずにYoutubeとTwitterの埋め込み備忘録

Last updated at Posted at 2022-02-25

実装内容

APIを使わずに記事投稿アプリで、YoutubeやTwitterを記事に埋め込む。URLを入力すると自動で埋め込み用に変換するもの。

実装の流れ

1.モデルにenumと入力フォームを追加
2.Youtubeを表示させる
3.Twitterを表示させる

1.モデルにenumと入力フォームを追加

ユーザーが入力した値を保存するためのカラムを用意する。

model/embed.rb
class Embed < ApplicationRecord

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

  validates :identifier, length: { maximum: 200 }

end

embed_typeでYoutubeかTwitterを選択する。
identifierでURLを保存する。

入力フォームではYoutubeかTwitterかを選択し、identifierを入力できるように設定する。

article_blocks/_edit_embed/html.slim
.box-body
    = f.input :embed_type, collect: Embed.embed_types_i18n.invert, include_blank: false
    = f.input :identifier

2.Youtubeを表示させる

Youtube公式 動画と再生リストを埋め込む
埋め込みたいYoutube動画ページで、「共有」→「<> 埋め込む」を選択すると、埋め込み用のHTMLを用意してくれるので、それをコピーする。

<iframe width="560" height="315" src="https://www.youtube.com/embed/88npQhcm9qk" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

上記は実際にHTMLをコピーしてきた内容。
Youtubeの埋め込み用URLは以下の構成になっている。

https://www.youtube.com/embed/動画一意のID

最後の/までは固定値として設定し、ユーザーの入力したURLのうち、最後の/以下だけを受け取るようなメソッドを記述する。

model/embed.rb
def split_id_from_youtube_url
    # YoutubeならIDのみ抽出
    identifier.split('/').last if youtube?
  end

例は以下の通り。

'https://youtu.be/88npQhcm9qk'.split('/')
# => ["https:", "", "youtu.be", "88npQhcm9qk"]

'https://youtu.be/88npQhcm9qk=125'.split('/').last
# => "88npQhcm9qk=125"

実際にviewに落とし込んでいく。

_embed_youtube.html.slim
ruby:
  embed = local_assigns[:embed]
  width = local_assigns[:width] || 853
  height = local_assigns[:height] || 480


.embed-youtube
  = content_tag 'iframe', nil, width: width, height: height, src: "https://www.youtube.com/embed/#{embed.split_id_from_youtube_url}", \
    frameborder: 0, gesture: 'media', allow: 'encrypted-media', allowfullscreen: true
/ ↑Youtube公式に乗っている埋め込み用のHTMLを出力する形にする
/ slimでRubyコードを途中改行する場合は末尾に\(バックスラッシュ)または,(カンマ)をつける

YouTube埋め込み部分に#{embed.split_id_from_youtube_url}と記入することで、指定した動画の埋め込みを作ることができる。

3.Twitterを表示させる

タイムラインを埋め込む方法
貼り付け用に変換してくれる公式ツールがあるので、ここにツイートを貼り付けて埋め込み用HTMLを生成する。

以下実際にHTMLをコピーしていた内容。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Twitter上にいる全猫たちと飼い主さんたち、今日はたくさんの癒しをありがとうございました!<a href="https://twitter.com/hashtag/%E7%8C%AB%E3%81%AE%E6%97%A5?src=hash&amp;ref_src=twsrc%5Etfw">#猫の日</a><br><br>写真は <a href="https://twitter.com/hashtag/Twitter%E7%8C%AB%E3%81%AE%E6%97%A5%E3%82%A2%E3%83%B3%E3%83%90%E3%82%B5%E3%83%80%E3%83%BC?src=hash&amp;ref_src=twsrc%5Etfw">#Twitter猫の日アンバサダー</a> <a href="https://twitter.com/slurmQuEBJUJK3X?ref_src=twsrc%5Etfw">@slurmQuEBJUJK3X</a> さんの猫ちゃんです✨ <a href="https://t.co/QVa21bdv3E">pic.twitter.com/QVa21bdv3E</a></p>&mdash; Twitter Japan (@TwitterJP) <a href="https://twitter.com/TwitterJP/status/1496116675858804736?ref_src=twsrc%5Etfw">February 22, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

これもYoutube同様無駄な部分を省く。

<blockquote class="twitter-tweet"> <a href="https://twitter.com/TwitterJP/status/1496116675858804736?ref_src=twsrc%5Etfw">February 22, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

省いたものを、viewに反映させればOK。

_embed_twitter.html.slim
.embed-twitter
  blockquote.twitter-tweet
    a href="#{embed.identifier}"
  script async="" charset="utf-8" src="https://platform.twitter.com/widgets.js"

#{embed.identifier}で任意のツイートのURLを埋め込むことができる。

上記rspec

require 'rails_helper'

RSpec.describe 'AdminArticlesEmbeddedMedia', type: :system do
  let(:admin) {create(:user, :admin)}
  let(:article) {create :article}

  describe '記事の埋め込みブロックを追加' do
    before do
      login(admin)
      article
      visit edit_admin_article_path(article.uuid)
      click_on('ブロックを追加する')
      click_on('埋め込み')
      click_on('編集')
    end
    
    context 'YouTubeを選択しアップロード' do
      it 'プレビューした記事にYouTubeが埋め込まれていること', js: true do
        select 'YouTube'
        fill_in 'ID', with: 'https://youtu.be/dZ2dcC4OnQE'
        page.all('.box-footer')[0].click_button('更新する')
                #更新ボタンが同じページにいくつかあるとき
        click_on('プレビュー')
        switch_to_window(windows.last)
        expect(current_path).to eq(admin_article_preview_path(article.uuid))
        expect(page).to have_selector("iframe[src='https://www.youtube.com/embed/dZ2dcC4OnQE']")
                #Youtubeの埋め込みを確認
      end
    end

    context 'Twitterを選択しアップロード' do
      it 'プレビューした記事にTwitterが埋め込まれていること', js: true do
        select 'Twitter'
        fill_in 'ID', with: 'https://twitter.com/_RUNTEQ_/status/1219795644807667712'
        page.all('.box-footer')[0].click_button('更新する')
        click_on('プレビュー')
        switch_to_window(windows.last)
        expect(current_path).to eq(admin_article_preview_path(article.uuid))
        sleep 1 
        # 全体テスト実行時に画面遷移が追いつかないので待機
        # sleep:プログラムの実行をストップする(秒数)
        expect(page).to have_selector(".twitter-tweet")
        # embedded_urlだと検証しづらいので固定値で確認
        # expect(page).to have_selector("iframe[src='#{embedded_url_twitter}']")
      end
    end
  end
end

参考記事

【Rails】YoutubeとTwitterをAPIを使わずに記事に埋め込む
rails学習 YouTubeとTwitterをローカルで埋め込む

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2