秘密にしておきたかったんだけど、実はTwitterにはWebページを埋め込めるんだよね

こんにちは、Twitter大好き丸の [あかい](https://twitter.com/Ver1000000000) です:baby_chick:

タイトルの通りなのですが、**実はTwitterにはWebページを埋め込むことができます**。（具体的には「ツイートには」ですが）

「WebページにTwitterを埋め込む」ではないですよ。
次のツイートをご覧ください。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">つくったから見て！！！！<br><br>特にPC版Twitterから《《《再生》》》してみて！！！！！<a href="https://t.co/a1KLMSXfaV">https://t.co/a1KLMSXfaV</a> <a href="https://twitter.com/hashtag/%E6%9C%B1%E7%8C%AA%E3%82%8F%E3%82%89%E3%81%84?src=hash&amp;ref_src=twsrc%5Etfw">#朱猪わらい</a></p>&mdash; あかい (@Ver1000000000) <a href="https://twitter.com/Ver1000000000/status/1281181791479455746?ref_src=twsrc%5Etfw">July 9, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

……何やら再生できそうな感じのインターフェースが表示されていますよね？


そうなのです、このツイートを[Web版Twitter公式クライアント](https://twitter.com/Ver1000000000/status/1281181791479455746)で開いて再生ボタン押下して展開するとなんと、
このために作った拙作の[朱猪わらいの動画（？）](https://ver-1000000.github.io/akaino-warai/)がはじまります。
（~~かなり適当なES2015をpolifyllもいれず生で書いたので、動かないブラウザがあるかも~~）
（~~モバイルサファリclass構文対応してねぇのかよ！！！！びっくりだよ！！！！~~ Babelでトランスパイルしたから諸々のブラウザで動くと思うよ）
（[クラス構文じゃなくてクラスフィールドの仕様がまだ勧告候補だからsafariでは動かないんだ](https://qiita.com/ver1000000/items/78736a74cfdb50934d8f#comment-7288714b959acb2ae169)よ、という話でした！）

ランダムな動的挙動や、クリックによるインタラクションを成し遂げています。

# どういう仕様？
これはいわゆる**Twitter カード**機能の**Player タイプ**と呼ばれる仕様で実現されています。

- [Player card — Twitter Developers](https://developer.twitter.com/en/docs/tweets/optimize-with-cards/overview/player-card)

Twitter カードについての諸々の仕様はみなさんに各自調べていただくとして、
Playerのカードについて、かいつまんで説明すると

- 動画サイトとか（rich media）を共有した時に、いい感じの再生可能なカードを表示するための仕様
    - 10秒未満の動画はカードがTLビュー内に入った時に自動で再生できたりする
- 技術的には**iframeを利用して、外部のリソースをカードの枠内に表示している**よ
- レスポンシブなデザインで、動画などのメディアや、可変の枠に収まるように作られたWebページを想定している

というところでしょうか。

htmlに

```html
<meta name="twitter:player" content="https://example.com/movie.mp4" />
```

などとするとよいようで、ここの`content`にhtmlを記述すると、
記述したhtmlがrich mediaとしてTwitter カードにﾄﾞﾝと現れるようになるわけです。

つまり、htmlをメディアとしてカードに表示したい場合は、2つのhtmlを準備する必要があります。

GitHub Pagesとかで適当に公開して、[Card Validator | Twitter Developers](https://cards-dev.twitter.com/validator)でテストしたら動作も含めて確認できます。

# TwitterのTLでWebページ表示できるとか面白すぎｗｗｗｗｗｗ クソゲーいっぱい作ってツイートしよ！！！！！！！！！！！！！！！！！！！！！！
**ちょっと待ってください！**

実は先程貼った [Player card — Twitter Developers](https://developer.twitter.com/en/docs/tweets/optimize-with-cards/overview/player-card) の
**Player card policy**項目に、いくつか気になる文章が書いてあります。

1文だけ、適当に要約します。


> - Do not circumvent the intended use of the Card. Player Cards are reserved for linear audio and video consumption only.

*「カードの目的逸脱しないでね、これ、ビデオとオーディオのためのモンだからね。」*

……

~~………… ハ！？！？ じゃぁなんでこんな何でもできるような可能性ありまくりの仕様実装しちゃったの？？？？？~~
どうやら昔は[「審査」](https://qiita.com/ver1000000/items/78736a74cfdb50934d8f#comment-6642950d4f5e30adca0b)をしてちゃんと問題がないかチェックしていたようでした。
（[ゲームの公開](https://qiita.com/laineus/items/a71d8fa4efae39119ef1)や[アプリでの利用](https://www.kagua.biz/social/post-36885.html)においても許可されていたようですね）

規模の大きくなってきたTwitterにおいて、こういった運用が難しくなったため、
夢のある（？）この仕様をそのままにしておくためにという意味でも、
厳しいポリシーで縛るという方向性に転換したのではないでしょうか。
（完全に憶測なので悪しからず）


Player タイプのカードにはなんかリッチなコントロールがついた動画や音声だけに設定するようにしましょう……:pensive:

そういうわけで、拙作の [朱猪わらい](https://ver-1000000.github.io/akaino-warai/) は、便宜上、
**スクショや共有のできる、ちょっと便利なコントロールのついたランダム性のあるビデオ** です。

いやぁ、面白い仕様見つけたなぁと思ってワクワクしながらたまたま実装したのが、
ユーザーを驚かせたりしないような**ビデオで良かった**。 **ビデオで良かった**。

# おまけ
## 朱猪わらいについて
この仕様を知った時、試してみたくて作ったゲ動画です。
とくに面白いところがあるわけではないのですが、Player カードの可能性を感じてもらうことは出来たかと思います。

リポジトリを置いておきますので、ぜひ参考にしてください。

- [ver-1000000/akaino-warai: 朱猪わらい](https://github.com/ver-1000000/akaino-warai)
- [AKAINO WARAI](https://ver-1000000.github.io/akaino-warai/content.html)

## iframeの詰まったポイント
iframeを利用すると、別ドメイン間の制約とかで苦しい思いをするのは
日本昔ばなしでもよく語られていますが（語られていません）、
今回朱猪わらいを実装する上でも引っかかりました。

中でも大変だったのは生成された画像の保存機能です。
調べれば色々でてくるかと思いますが、普通、iframe内のデータを端末に保存させることはできないのですよね。

これを回避するため、クエリパラムを利用して別ウィンドウで結果画像を再現し、
別ウィンドウでダウンロードさせて一瞬でウィンドウを閉じるという力技を使いました :muscle:

怪我の功名と言いますか、一石二鳥と言いますか、URLから状態を復元できる設計になったので、
結果をTweetで共有できるように作れたのはよかったですね。

## Card Validatorのサムネが更新されない問題
Twitter カードの再生マークのところに表示されるサムネイルは、
`twitter:image`という名前（name属性）の付いたメタタグで設定できるのですが、
一度設定した後、GitHub Pagesに画像を上げ直しても、新しい画像で反映されなくなってしまいました。

Card Validatorの`Preview Card`ボタンを何度押しても変わりません。

どうしようかなぁと思ってしばらくなやんだのですが、
[画像だけではなく、ファイル名とメタタグのurlを書き換えたら](https://github.com/ver-1000000/akaino-warai/commit/a374310ec7bdb987af75e11f3ed9bb68520f56b2)ちゃんと反映されるようになりました。

## 「悪いこと」について (2020-07-10追記
結構な反響をいただきまして、その中で時々「悪いことに使えそう」というコメントを目にします。

私は[その筋](https://qiita.com/search?q=iframe)はさほど詳しくないのですが、
この実装を知った時、「悪いことには使えなさそうだなぁ」という印象を受けました。

というのも、昨今のブラウザではiframeに[前述](https://qiita.com/ver1000000/items/78736a74cfdb50934d8f#iframe%E3%81%AE%E8%A9%B0%E3%81%BE%E3%81%A3%E3%81%9F%E3%83%9D%E3%82%A4%E3%83%B3%E3%83%88)のようなセキュリティ上の制限が数多く課されているためです。

- [**Same Origin Policy**](https://developer.mozilla.org/ja/docs/Web/Security/Same-origin_policy)の制約をうけるため、表示された別ドメインのコンテンツから親サイト（twitter.com）のcookieや画像、htmlなどのリソースにアクセスすることは出来ない
    - ユーザーの入力情報が盗まれたり、勝手に操作されたりは出来ない
- htmlのPlayer カードが自動展開されることはないため、ユーザーの操作なしにjsの操作を許可することはない
    - このリスクは「Twitter上の外部リンクをクリックする」のと同じですね
- topやtransformプロパティを用いて、iframeの枠を越えてDOMを表示することは出来ない**（要検証）**
    - 操作を阻害したり、不正な情報を表示しつづけてユーザーの不利益な操作を誘導できたりはしない

のような前提があり、別ドメインのWebサイトが親ドメインのWebサイトにできることは非常に限られています。
（このような前提がある上で、更にTwitter Player カードのポリシーが定められているわけですね、厳しい）

おそらく「悪いことに使えそう」とおっしゃっている方々は、Same Origin Policyの存在を度外視しているのではないかな？と感じました。

とは言え、XSSの手法は星の数ほどありますから、 気になる方は https://html5sec.org/ などで `iframe` について検索してみると良いかも知れません。
（もし「これヤバくね？」みたいなものがあったら「iframeのヤバイXSSたち」みたいなQiita記事を書かれて啓蒙されるとよいかもしれませんね）

私の見解では、
_「Twitter Player カードで使えるような重大なXSSが露見されれば、各種ブラウザベンダーがすぐにiframeに制限を加えてくるのではないか。 もしもそうでないなら、やはりPlayer カードはそのうちTwitterの機能からなくなるだろうな。 iframeもなくなるだろうな」_
というところです。