ニュースレター登録フォーム

ニュースレター登録フォーム2 分で読めます

自作のニュースレターフォームの登録を Kit に送る

購読者を作成し、特典メールのために Kit のフォームに追加し、設置場所のタグを付けるリレーで、自作のニュースレターフォームを Kit につなぎます。

Preet SutharIkiform 創業者

自分のフォームを Ikiform に送信し、Ikiform の Webhook を、Kit v4 API を最大 3 回呼び出すリレーに向けます。購読者の作成、Kit のフォームへの追加、登録場所のタグ付けです。購読者を inactive として作成し、特典メールがオンのフォームに追加すれば、Kit が独自の確認メールを送るはずです。Kit がこれを一括エンドポイントについてしか説明していないので、自分のアドレスで一度テストしてください。Kit の API キーはリレーが保持し、ページからは見えません。

Kit で異なる点

Kit は 1 件の登録を別々のオブジェクトに分けます。購読者は人です。フォームはその人がどこから来たかを表し、確認メールを持っています。Kit はこれを特典メール(incentive email)とも呼び、ダブルオプトインの手順になっています。タグはセグメント分けに使うラベルです。v4 API にはそれぞれ 1 つのエンドポイントがあり、フォームとタグのエンドポイントはどちらも先に購読者が存在している必要があります。そのため、Ikiform の 1 件の登録は、短い一連の呼び出しを順番に行うことになります。

1 件の登録でリレーが行う Kit API の呼び出しIkiform のWebhookリレーが検証POST/v4/subscribersstate: inactivePOST/v4/forms/{id}/subscribers特典メールを送信POST/v4/tags/{id}/subscribers設置場所をタグ付け1231 件の登録でリレーが行う Kit API の呼び出しIkiform の Webhookリレーが検証POST /v4/subscribersstate: inactivePOST/v4/forms/{id}/subscribers特典メールを送信POST/v4/tags/{id}/subscribers設置場所をタグ付け123
  1. リレーが Ikiform の署名付き Webhook を受け取り、検証します。
  2. Kit に購読者を inactive として作成します。アドレスがすでに存在する場合、Kit は名を更新し、状態はそのままにします。
  3. 購読者を Kit のフォームに追加します。そのフォームの特典メールがオンなら、Kit が確認メールを送ります。
  4. 登録の source にタグがあれば、購読者にタグを付けます。この手順は任意です。
各呼び出しは前の呼び出しに依存するので、リレーは最初の失敗で止まり、Ikiform にリトライさせます。
呼び出しKit の応答意味
購読者の作成201新しい購読者が、送った状態で作成された
購読者の作成200すでに存在する。名は更新され、状態は変わらない
フォームへの追加201 または 200追加された、またはすでにフォームにいる。Kit の一括フォームのドキュメントによると、すでにフォームにいる人には特典メールは再送されない
すべての呼び出し401API キーが間違っているか、ない
フォームへの追加またはタグ付け404フォームまたはタグの id がこのアカウントに存在しない
すべての呼び出し429API キーのレート制限を超えた

Kit を設定する

  1. Kit で、これらの登録用のフォームを「Website signup」などの名前で作成します。埋め込みはしません。購読者がどこから来たかの記録であり、特典メールの置き場所です。
  2. ダブルオプトインにしたい場合は、フォームの設定を開いて特典メールをオンにします。メールの文面を書き、確認リンクの遷移先を設定してください。
  3. フォームの数値の id を、Kit のアプリか API のフォーム一覧エンドポイントで確認します。必要なら設置場所ごとにタグを作成し、その id を控えておきます。
  4. Kit の開発者設定で v4 の API キーを作成し、リレーの環境変数用に保管しておきます。
Kit の API ドキュメントによると、API へのアクセスはアカウントのプランが対象かどうかによって決まり、料金ページではアプリと連携は Creator プラン以上に記載されています。これを前提に作り込む前に、自分のプランで v4 のキーを作成できるか確認してください。

リレー

Next.js のルートハンドラーが Webhook を受け取り、小さなモジュールが Kit とやり取りします。同じ 2 つのファイルは、公開の HTTPS URL が得られる Node やエッジのホストならどこでも動きます。

lib/kit.ts
const KIT = "https://api.kit.com/v4";

const TAGS: Record<string, number> = {
  footer: 1111111,
  post: 2222222,
};

function call(path: string, body: Record<string, unknown>) {
  return fetch(`${KIT}${path}`, {
    method: "POST",
    headers: {
      "X-Kit-Api-Key": process.env.KIT_API_KEY!,
      "Content-Type": "application/json",
      Accept: "application/json",
    },
    body: JSON.stringify(body),
  });
}

export async function addToKit(signup: { email: string; firstName?: string; source: string; referrer?: string }) {
  const created = await call("/subscribers", {
    email_address: signup.email,
    first_name: signup.firstName ?? null,
    state: "inactive",
  });
  if (!created.ok) return created;

  const joined = await call(`/forms/${process.env.KIT_FORM_ID}/subscribers`, {
    email_address: signup.email,
    referrer: signup.referrer ?? null,
  });
  if (!joined.ok) return joined;

  const tag = TAGS[signup.source];
  if (!tag) return joined;
  return call(`/tags/${tag}/subscribers`, { email_address: signup.email });
}
app/api/kit/route.ts
import { verifyWebhook, WebhookVerificationError } from "@ikiform/sdk/webhooks";
import { addToKit } from "@/lib/kit";

export async function POST(request: Request) {
  const payload = await request.text();
  let event;
  try {
    event = await verifyWebhook({ payload, headers: request.headers, secret: process.env.IKIFORM_WEBHOOK_SECRET! });
  } catch (error) {
    if (error instanceof WebhookVerificationError) return new Response(error.reason, { status: 400 });
    throw error;
  }
  if (event.type !== "submission.created") return new Response(null, { status: 204 });

  const { email, first_name, consent, source } = event.data.fields;
  if (consent !== true || typeof email !== "string") return new Response("Skipped", { status: 200 });

  const answer = await addToKit({
    email,
    firstName: typeof first_name === "string" ? first_name : undefined,
    source: typeof source === "string" ? source : "unknown",
    referrer: typeof event.data.meta.referrer === "string" ? event.data.meta.referrer : undefined,
  });

  if (answer.status === 429) return new Response("Kit rate limit", { status: 503, headers: { "retry-after": "60" } });
  if (!answer.ok) return new Response(`Kit answered ${answer.status}: ${await answer.text()}`, { status: 502 });
  return new Response(null, { status: 204 });
}
.env.local
IKIFORM_WEBHOOK_SECRET=whsec_...
KIT_API_KEY=your-v4-api-key
KIT_FORM_ID=1234567
  • Kit の v4 API は、個人の API キーを X-Kit-Api-Key で受け取ります。OAuth は他の人がインストールするアプリ向けで、自分のリスト用のリレーには不要です。
  • state: "inactive" を送ることで、新しい購読者はクリックするまで未確認のままになります。省略すると Kit は active として作成し、同じエンドポイントであとから状態を変えることはできません。
  • ページのリファラーはフォームの referrer として Kit に送られるので、読者がどの記事から来たかが Kit に表示されます。
  • Kit のエラーのボディは 502 に入るので、Ikiform の配信ログに Kit 自身のメッセージが表示されます。
  • 各 source の値を TAGS のタグ id に対応付けます。タグのない source では 3 つ目の呼び出しを飛ばします。

Ikiform のダッシュボードの Webhooks にルートの URL を追加し、ニュースレターのフォームを選び、whsec_ のシークレットを IKIFORM_WEBHOOK_SECRET にコピーします。URL と各応答のルールはすべて Webhook のドキュメントにあります。

レート制限とリトライ

Kit は API キーごとに、直近 60 秒で 120 リクエストまで許可します。1 件の登録で 2〜3 リクエスト使うので、Kit が 429 を返すまでに 1 分あたりおよそ 40〜60 件の登録が収まります。フッターのフォームには十分ですが、投稿がバズった日には上限に近づきます。

Kit が 429 を返すと、リレーは Retry-After 付きの 503 を返し、Ikiform は待ってからリトライします。リトライでは一連の処理を最初から実行します。それでも安全です。作成は既存の購読者に 200 を返し、すでにフォームにいる人の追加も 200 を返します。Kit の一括フォームのドキュメントでは、すでにフォームにいる人に特典メールは再送されないとされていますが、単一のエンドポイントについては記載がないので、自分のアドレスでリトライをテストしてください。完了済みのリトライを飛ばしたいなら、各 webhook-id を記録する方法を自前のサーバーで紹介しています。

ハマりどころ

  • カスタムフィールドは先に作っておく。 作成の呼び出しに fields を追加するなら、last_name のような各フィールドのキーを使い、送る前に Kit でフィールドを作成してください。
  • アクティブな購読者はアクティブのまま。 作成は既存の購読者の状態を変えないので、確認済みの読者がもう一度登録しても、再び確認を求められることはありません。
  • 配信停止した読者。 配信停止したあとに再び登録した読者はすでに存在するので、作成は 200 を返し、状態は変わりません。そうした読者をどう扱うかは Kit で確認してください。
  • 1 つのフォームを複数の場所で。 ウェブサイトには Kit のフォームを 1 つ使い、設置場所はタグで区別します。Kit のフォームが複数あると、そろえておくべき特典メールも複数になります。
  • Ikiform からのメールはない。 Ikiform はフォームに入力した人にはメールを送りません。通知メールが届くのはあなたとチームだけなので、自動返信、確認メール、ダブルオプトインはありません。それらは Webhook をきっかけにメールツールから送ってください。

動作を確認する

  1. Ikiform でエンドポイントの Send test を選びます。配信には 204 が表示され、Kit では何も変わりません。
  2. 自分のアドレスでページから購読します。配信には 204 が表示されます。
  3. Kit では、購読者がフォーム上に未確認として、設置場所のタグ付きで表示されます。
  4. 特典メールが届きます。リンクをクリックすると、購読者が確認済みになります。
  5. 同じアドレスでもう一度購読します。配信には 204 が表示され、2 通目の特典メールは届きません。
  6. 一時的に間違った KIT_FORM_ID を設定します。配信には Kit の 404 のメッセージ付きで 502 が表示されます。

よくある質問

手順で詰まったときや、あなたの状況に合うガイドがほしいときはメールでどうぞ: hello@ikiform.com