基本ガイド
署名付き URL
誰かが開いたときにテンプレートの画像を描画するリンクの作成方法を説明します。
署名付き URL は、誰かが開いたときにテンプレートの画像を描画するリンクです。<img> タグ、メール、Open Graph タグに入れられ、画像が読み込まれるときに、サーバーは何も処理しません。パーソナライズしたメールのヘッダー、シェアカード、バッジに便利です。
リンクには、テンプレート ID、modification、署名が含まれます。リンクを持っている人は、その画像をそのまま開けますが、署名を壊さずにテンプレートや modification を変更することは、誰にもできません。
SDK で署名付き URL を作成する
SDK は、サーバー上で URL に署名します。ネットワークリクエストは送りません。
Examples
Open only what you need
JavaScript
const url = await bannerify.generateImageSignedUrl("tpl_xxx", {
modifications: [{ name: "headline", text: "Hello, Ada" }],
})Python
url = client.generate_image_signed_url(
"tpl_xxx",
modifications=[{"name": "headline", "text": "Hello, Ada"}],
)PHP
$url = $client->generateImageSignedUrl('tpl_xxx', [
'modifications' => [['name' => 'headline', 'text' => 'Hello, Ada']],
]);Go
url, err := client.GenerateImageSignedURL("tpl_xxx", &bannerify.CreateImageOptions{
Modifications: []bannerify.Modification{{Name: "headline", Text: ptr("Hello, Ada")}},
})各 SDK のオプションは、それぞれのページにまとめています: JavaScript、Python、PHP、Go。
署名付き URL を自分で作成する
署名付き URL は、どの言語でも作成できます。使っている言語の SDK がない場合や、Go の nocache のように、必要なオプションが SDK にない場合に便利です。
- API キーを SHA-256 でハッシュ化し、ダイジェストを 16 進数で書き出します。これが
apiKeyHashedです。Bannerify はこれを使ってキーを探しますが、これで何かに署名することはできません。 - 下の表からパラメーターを集めます。
modificationsは JSON 文字列です。 - パラメーターを名前でソートし、
URLSearchParamsが生成する形式のクエリ文字列として書き出します。スペースは+になり、英字、数字、*、-、.、_以外のすべての文字は、パーセントエスケープされます。 - そのクエリ文字列の HMAC-SHA256 を、API キーをシークレットとして計算し、ダイジェストを 16 進数で書き出します。これが
signです。 - クエリ文字列に
signを追加します。
import { createHash, createHmac } from "node:crypto"
const apiKey = process.env.BANNERIFY_API_KEY!
const params = new URLSearchParams({
templateId: "tpl_xxx",
apiKeyHashed: createHash("sha256").update(apiKey).digest("hex"),
modifications: JSON.stringify([{ name: "headline", text: "Hello, Ada" }]),
nocache: "true",
})
params.sort()
params.set("sign", createHmac("sha256", apiKey).update(params.toString()).digest("hex"))
const url = `https://api.bannerify.co/v1/templates/signedurl?${params}`
パラメーター
| パラメーター | 必須 | 説明 |
|---|---|---|
templateId |
はい | テンプレート ID |
apiKeyHashed |
はい | API キーの SHA-256 ハッシュ(16 進数) |
sign |
はい | 手順 4 の署名 |
modifications |
いいえ | JSON 文字列。フィールドは Modificationsにまとめています |
format |
いいえ | png、jpeg、webp。初期値は png です |
quality |
いいえ | jpeg と webp 用の 1〜100 の整数。初期値は 90 です |
nocache |
いいえ | キャッシュをスキップするには true |
キャッシュ
Bannerify は、描画した画像をエッジキャッシュに最大 7 日間保持します。キャッシュキーは URL 全体のため、modification が異なれば、別の画像になります。キャッシュが応答したリクエストでは、再描画されません。
繰り返しリクエストされる画像は、キャッシュに残り続けます。キャッシュは Cloudflare が運用し、何を保持するかも Cloudflare が決めるため、しばらく誰もリクエストしなかったコピーは、7 日が経つ前に破棄されることがあります。次のリクエストで画像が再描画され、その描画はクォータに数えられます。
- エディターでテンプレートを保存すると、そのテンプレートのキャッシュ済みの画像が消去されます。それ以外の方法で行った変更では、消去されません。
- Settings の General タブにある Clear image cache は、プロジェクトのすべてのテンプレートのキャッシュ済みの画像と、それらが他のサイトから読み込むキャッシュ済みのファイルを消去します。
nocache=trueは、描画した画像のキャッシュをスキップします。リクエストのたびに新しい画像が描画され、レスポンスは保存されません。これらの描画は、1 つずつクォータに数えられます。レイヤーが読み込むキャッシュ済みのファイルは、引き続き使われます。
Bannerify は、レイヤーが他のサイトから読み込む各ファイルもキャッシュします。そのサイトの Cache-Control ヘッダーの max-age が許す期間、ただし最短 60 秒、最長 7 日間、ファイルを保持します。サイトが max-age を送らない場合は、ファイルを 1 日間保持します。ファイルが変わったときは、新しい URL を付けるか、Clear image cache を使ってください。
クォータとレート制限
描画は、1 回の生成として数えられます。キャッシュが応答したリクエストは数えられません。何が数えられるかは、クォータと制限にまとめています。
署名付き URL の描画には、API キーごとに 10 秒間に 100 リクエストという、独自のレート制限があります。キャッシュが応答したリクエストは、これに含まれません。制限を超えると、リクエストは RATE_LIMITED を返します。
安全に使う
- 署名は、サーバーで行います。署名には API キーを使うため、署名のコードをブラウザーや、配布するアプリで実行してはいけません。
- URL は、共有しても安全です。URL には署名とキーのハッシュが含まれますが、どちらも別の URL に署名することはできません。
- URL を持っている人は、何度でも開けます。URL に有効期限はなく、キャッシュに当たらない描画は、すべてクォータに数えられます。
- modification は、プレーンテキストとして URL に含まれます。非公開のデータを入れないでください。
- キーが署名したすべての URL を無効にするには、API Keys ページでそのキーを削除します。
トラブルシューティング
リクエストが失敗すると、画像タグには壊れた画像が表示されます。エラーを読み取るには、ブラウザーのタブで URL を開いてください。
| エラー | 原因 | 対処 |
|---|---|---|
BAD_REQUEST: Missing apiKeyHashed |
URL に apiKeyHashed パラメーターがありません |
追加します。SDK は自動で追加します |
BAD_REQUEST: Invalid api key |
apiKeyHashed に一致するキーがありません。たとえば、キーを削除した場合です |
存在するキーで署名します |
BAD_REQUEST: Invalid sign |
署名がパラメーターと一致しません | URL が編集されていないこと、上で説明したとおりにパラメーターをソートしてエンコードしたことを確認します |
NOT_FOUND |
テンプレートが存在しません | templateId を確認します |
USAGE_EXCEEDED |
生成回数の上限に達しました | クォータと制限を参照してください |
RATE_LIMITED |
10 秒間の描画が多すぎます | 次の 10 秒のウィンドウまで待つか、繰り返しのリクエストはキャッシュに任せます |