Open Graphのデータをカードでプレビューする
Published at 2016-01-29
オープングラフのデータを取得して表示する機能は、FacebookやらTwitter、Google+では当たり前のようにある機能だが、業務上必要になったので調査して、ツールを作った話。
文字列や画像のURLといった表示させたいデータを<meta>
や<link>
で記述するのは御存知の通りだが、HTMLにどのように記述するかは各プラットフォーム毎に定義がなされている。FacebookであればOpen Graph、TwitterであればTwitter Cardsといった名前が付いている。
<!-- Open Graph -->
<meta property="og:title" content="The Rock">
<meta property="og:type" content="video.movie">
<meta property="og:url" content="http://www.imdb.com/title/tt0117500/">
<meta property="og:image" content="http://ia.media-imdb.com/images/rock.jpg">
<!-- Twitter Cards -->
<meta name="twitter:card" content="">
<meta name="twitter:site" content="">
<meta name="twitter:url" content="">
<meta name="twitter:title" content="">
<meta name="twitter:description" content="">
<meta name="twitter:image" content="">
これだけではなく、Googleの検索結果からネイティブアプリを起動させたい場合はApp Indexingの対応が必要だったり、iOSはカスタムのURLスキーマを使う必要があったりと、かなり複雑で様々な対応が必要になる。これについてはネイティブ・ソーシャル時代にWeb・アプリでやっておくべきことまとめ (ネイティブSEO)に詳しくまとまっているので読んでもらうとして、今回はOpen GraphやTwitter Cardsに記述されているデータを取得してカードに表示する実装をした。
ブラウザからはcors制限で取得できない
特定のURLのHTMLを閲覧しているページコンテキストから取得できれば、Open Graphのタグなどを参照できるが、corsの制限でHTMLを得ることが出来ないことが多い(ほとんど?)。なのでまずは、Node.jsのプログラムからリクエストしてHTMLを取得してくることを試みる。
プログラム自体は難しいものではなく、1000/rogのような実装になった。
const rog = require('rog');
rog('http://google.com').then(data => {
console.log(data.title);
console.log(data.type);
console.log(data.url);
console.log(data.image);
console.log(data.site);
console.log(data.description);
console.log(data.locale);
}).catch(error => {
console.error(error);
});
この例でいうdata.title
は内部的にmeta[property="og:title"]
またはmeta[name="twitter:title"]
またはmeta[name="title"]
を参照している。正確に言えば異なるデータを指定するケースがあるのかもしれないが、大抵の場合は同じだろうと括ってこのようにした。
プロキシ的に簡易サーバーを立てる
1000ch/og-card-simulatorはテキストエリアに入力されたURLのOpen Graphデータを取得してカードとして表示するサンプル。
- テキストエリアに入力された文字列からURLを判別
- そのURLをパラメータとしてサーバーにリクエスト
- 指定されたURLにNode.jsから再度リクエストしJSONデータを取得
- 取得したJSONデータをクライアントに返却
- 返却されたJSONデータに応じてカードを表示
cors問題がある限りプロキシ的なものを挟まないとデータを取れない気はしてるが、これが正攻法なのかわからない。ネイティブアプリからならこういった中継をせずとも、HTTPクライアントからリクエストしてHTMLを検証するということを直接できるんだろうか。