Kanorio

ビジネスシステム

フォーム

Kanorioフォームを独自のフロントエンドに配置しましょう。ボット保護、ファイルアップロード、同意確認、連絡先収集を自動的に処理します。

管理画面のマーケティング › オンラインフォームでフォームを作成し、フロントエンドに表示します。Kanorioはボットやスパムのチェックを行い、回答を保存し、連絡先の作成や更新、確認メールやチームへの通知メールの送信、そして customers.form.submitted ウェブフックをトリガーします。

開始する前に、管理画面からフォームIDをコピーしてください。ブラウザから独自のドメインでAPIを呼び出す場合は、サイト設定 › 開発者 の 許可されたオリジン にそのドメインを追加してください。localhost は常に許可されています。

オプション1: フォーム要素の使用

<KanorioForm> は、あらゆる質問タイプ、ファイルアップロード、同意チェックボックスをレンダリングし、ボット保護を実行します。最も迅速な方法であり、アップグレードなしで新しい保護ルールが適用されます。

import { KanorioProvider, KanorioForm } from "@kanorio/elements";
import "@kanorio/elements/elements.css";

export function ContactSection() {
  return (
    <KanorioProvider siteUrl="https://s-xxxxxxxxxxxx.kanorio.com">
      <KanorioForm formId="cform12345678901234567890" siteName="Sourdough Studio" />
    </KanorioProvider>
  );
}

Reactを使用しない場合は、<kanorio-form site-url="…" form-id="…"> を使用してください。Elements を参照してください。

オプション2: 独自のマークアップの使用

HTMLを完全に制御したい場合は、Content Delivery APIを直接使用します。

1. フォームの読み込み

GET /api/v1/forms/{id} は、質問、同意設定、フォームが回答を受け付けているかどうかを返します。availability.accepting が false の場合、入力欄の代わりに終了メッセージを表示してください。

2. フォーム表示時のボットチェックの取得

GET /api/v1/forms/{id}/challenge は、この送信に対するボットチェックを返します。その provider は、サイト所有者が サイト設定 › ボット保護 で設定します。

  • kanorio (デフォルト): altcha に組み込まれたプルーフ・オブ・ワークのチャレンジです。SDKが自動的に解決し(中程度の性能のスマートフォンで約0.5秒)、結果を _tk として送信します。
  • turnstile, recaptcha, hcaptcha: 所有者自身のキーです。そのプロバイダーのウィジェットを siteKey と action(Turnstileの場合は cData も)でレンダリングし、トークンを captchaToken として渡します。サーバーはサイト設定から検証するプロバイダーを決定するため、他のプロバイダーからのトークンは拒否されます。

送信ごとに新しいチャレンジを取得してください。チャレンジとウィジェットトークンは使い捨てです。

3. 送信

質問IDをキーとした回答を、保護フィールドと共に送信します。ハニーポットフィールドは空である必要があります。

import { forms } from "@kanorio/sdk/forms";

const SITE_URL = "https://s-xxxxxxxxxxxx.kanorio.com";
const FORM_ID = "cform12345678901234567890";
const client = forms.client({ siteUrl: SITE_URL });

// when the form is shown
const renderedAt = Date.now();
const challenge = await client.challenge(FORM_ID);

// when the visitor submits
// built-in: the SDK solves the challenge; third-party: pass the widget token
const protection = await forms.protectionFromChallenge(FORM_ID, challenge, renderedAt, {
  captchaToken: challenge.provider === "kanorio" ? undefined : widgetToken,
});

const result = await client.submit(FORM_ID, {
  answers: { name: "Ada", email: "ada@example.com", message: "Do you ship?" },
  consent: "checked",
  pagePath: window.location.pathname,
  protection,
});

if (!result.ok) {
  // result.error.code, and result.error.issues for INVALID_ANSWERS
}

SDKを使用しない場合、以下のボディで POST /api/v1/forms/{id}/submit を実行します(組み込みチェックの場合。サードパーティプロバイダーの場合は _tk の代わりに captchaToken を送信してください):

{
  "answers": { "name": "Ada", "email": "ada@example.com" },
  "consent": "checked",
  "pagePath": "/contact",
  "_hp": "",
  "_ts": 1793520000000,
  "_tk": "<solved ALTCHA payload>",
  "_ctx": "cform12345678901234567890"
}

送信に成功すると 200 と {} が返されます。その間にフォームが終了していた場合、ボディは { "state": "closed" }、"not_open"、または "full" となります。

エラーコード対処方法
INVALID_ANSWERSdetails.issues に含まれるメッセージを質問IDごとに表示します
VERIFICATION_EXPIRED新しいチャレンジを取得(ウィジェットをリセット)し、再度送信します
DUPLICATE_SUBMISSIONフォームはすでに送信済みであることを訪問者に伝えます
RATE_LIMITEDRetry-After の時間まで待機してから再試行します

ファイルアップロード

ファイルに関する質問の場合、まず POST /api/v1/forms/{id}/upload-request でアップロードチケットを要求します。その際、質問ID、ファイル名、タイプ、サイズを forms.uploadProtectionFromChallenge(FORM_ID, challenge, renderedAt, solved) からの保護フィールドと共に送信します。組み込みチェックの場合、これは送信時に使用する解決済みのチャレンジと同じです。サードパーティプロバイダーの場合は、チャレンジの uploadToken を使用します(ウィジェットトークンは使い捨てであり、送信時にチェックされるため)。返された headers を使用して PUT で uploadUrl にファイルをアップロードし、その後 uploadId をその質問の回答として送信します。質問の制限を超えるファイルは 413 FILE_TOO_LARGE エラーとなります。

送信後

  • 送信内容は管理画面およびManagement APIの submissions に表示されます。
  • メールまたは電話番号の回答に基づいて連絡先が作成または更新されます。
  • フォームの設定に従って、確認メールとチームへの通知メールが送信されます。
  • ウェブフックの購読者に customers.form.submitted が通知されます。

サーバーからの転送

Next.jsのサーバーアクションなど、独自のサーバーから送信することも可能です。レート制限は訪問者ごとに適用されるため、ブラウザから直接送信する方がクォータを保護できます。転送する場合は、ブラウザの保護フィールドを変更しないでください。