1. やりたかったこと
TokiQRのplay.htmlは、QRコードに記録された音声・画像・テキストを再生するページだ。URLパラメータにすべてのデータが含まれている。サーバーへの問い合わせは一切ない。
このURLをLINEで送ったとき、リッチなサムネイル——タイトル、説明文、カスタム画像——が表示されれば、受け取る側の体験が良くなる。OGP(Open Graph Protocol)のメタタグをクローラーに返せば実現できるはずだった。
実装したこと
既存のCloudflare Worker(52行のGASプロキシ)にOGP機能を追加した。ロジックは明快だ。
- User-Agentがクローラー(LINE、Facebook、Twitter等)→ 動的OGP HTMLを返す
- 通常ブラウザ → 302リダイレクトでGitHub Pagesに飛ばす
URLパラメータからデータ種別(音声・画像・テキスト)を判定し、適切なOGPタイトルと説明文を生成する。Codec2音声の場合はBase64長から秒数まで計算して「14.0秒の音声メモリー」のように表示する。OGP画像も3種類作成した。
実装は完了し、Cloudflareにデプロイし、play.jsのシェア機能をWorker URL経由に切り替えた。curlでテストすると、クローラーUAには正しくOGP HTMLが返り、通常UAには302リダイレクトが返った。技術的には正しく動作していた。
2. 何が起きたか
LINEで実際にURLを送信した結果、OGPのタイトルと説明文、そしてアイコン画像は正しく表示された。しかし、カスタムサムネイル画像——1200x630pxのリッチな画像——は表示されなかった。
LINEのURL共有では、コンパクトカード(小さなアイコン+タイトル+説明文)しか表示されない。og:imageに指定した大きな画像は、LINEのプレビューカードには反映されない仕様だった。
これはバグではない。LINEというプラットフォームの設計判断だ。
加えて、play.htmlのURLは最大4000文字近くになる(Base64エンコードされた音声データがパラメータに含まれるため)。この長さのURLがLINEのメッセージに貼り付けられると、URL自体がメッセージの大部分を占め、サムネイル以前の問題として見栄えが悪い。
3. 短縮URLという誘惑
技術的な解決策は存在した。Cloudflare Workers KV(Key-Value Store)を使って短縮URLを実装すれば、4000文字のURLを20文字程度に圧縮できる。LINEのメッセージも綺麗になる。
しかし、この解決策は設計原則に正面から反する。
TokiQRの核心は、データがURLパラメータとして自己完結していることだ。サーバーに問い合わせる必要がない。QRコードをスキャンし、ブラウザで開くだけで音声が再生される。CloudflareもGASもGitHubも関係ない。
短縮URLを導入した瞬間、この自己完結性が崩れる。短縮URLのマッピングはCloudflare KVに保存される。KVが消えたら、短縮URLは永久にデッドリンクになる。データの永続性を、外部サービスの寿命に委ねることになる。
短縮URLは便利だ。しかしそれは、4000文字のURLに込められた自己完結性を、20文字の外部依存に置き換える行為だ。
前回のエッセイ「CloudflareとGAS——使うことと、頼ることは違う」で定義した原則がここで機能した。運用レイヤーは外部に依存してよいが、永続レイヤーは何にも依存してはならない。短縮URLは永続レイヤーの問題だ。だから却下した。
4. 原則が判断を代行する
短縮URLの却下は即座だった。検討に要した時間はほぼゼロだ。
これは判断力の問題ではない。原則が判断を代行したのだ。
設計原則が明確に言語化されていれば、新しい問題に直面したとき、考える必要がない。原則に照らすだけで答えが出る。
| 問い | 原則との照合 | 判断 |
|---|---|---|
| 短縮URLを導入するか? | 永続レイヤーが外部KVに依存する | 却下 |
| OGP Worker自体を維持するか? | LINEの制約で目的を達成できない | 全コードを戻す |
| noindexは戻すか? | 個人データURLの検索インデックスは不要 | noindexだけ残す |
3つの判断すべてに迷いがなかった。原則が明確だからだ。原則がなければ、「短縮URLにすれば見栄えが良くなるし、とりあえず入れておこうか」という議論が始まっていただろう。そしてその議論は、技術的な実現可能性やユーザー体験やコストの話に分岐し、何時間もかかったかもしれない。
5. 試すことの価値
この一連の取り組みは無駄だったか。そうは思わない。
試す前には分からなかったことがある。LINEがカスタムサムネイルを表示しないこと。play.htmlの長大なURLがLINEのメッセージで視覚的に破綻すること。これらは実装してデプロイしてテストして初めて分かった事実だ。
そして、試したからこそ戻す判断に確信が持てた。「LINEがサムネイルを出せないらしい」という伝聞と、「自分で実装してデプロイして確認した結果、出ない」という経験では、判断の重みが違う。
加えて、OGP対応の過程でplay.htmlにnoindexを追加するという副産物が得られた。個人の音声データを含むURLが検索エンジンにインデックスされる必要はない。これは試みの中で自然に浮かんだ改善であり、OGPとは無関係に価値がある。
半日の時系列
| ステップ | 内容 |
|---|---|
| 計画 | Cloudflare Worker OGPプロキシの設計 |
| 実装 | Worker拡張、OGP画像3枚生成、play.js修正 |
| デプロイ | Cloudflareにデプロイ、curlで動作確認 |
| 検証 | LINEで実際に送信、カスタムサムネイル非表示を確認 |
| 判断 | 短縮URL却下、全コードrevert、noindexだけ残す |
| 復旧 | Worker・play.js・OGP画像をすべて元に戻す |
6ステップが半日で完結した。「戻す」という判断に時間がかからなかったのは、原則が明確だったからだ。そして「戻す」という実作業に時間がかからなかったのは、Gitがあったからだ。
6. 結び——原則は判断のキャッシュだ
設計原則は、判断のキャッシュだ。
一度深く考えて言語化しておけば、
次から同じ問いに即座に答えられる。
設計原則が明確でないプロジェクトでは、同じ種類の判断が何度も議論される。「外部依存を増やしていいのか」「ユーザー体験のためなら許容するのか」「一時的なら問題ないのか」。毎回ゼロから議論するのは時間の浪費だ。
トキストレージでは「永続レイヤーは外部に依存しない」と言語化してある。だから短縮URLは即座に却下できた。OGP対応は目的を達成できないと分かった瞬間に全コードを戻せた。判断のたびに立ち止まる必要がなかった。
試して、原則に照らして、戻す。この循環を高速に回せることが、設計原則の実践的な価値だ。原則は理念ではなく、判断を加速する道具だ。