SETTINGS
設定の書き方
設定に書いた内容は、そのまま判定の材料として読まれます。「うちはどんな会社で、何を受け取りたくて、何が要らないか」が伝わるほど、問い合わせと売り込みの分かれ方が安定します。何を書けばいいか迷ったときの手引きです。
1歓迎する問い合わせ(必須)#
いちばん効く欄です。受け取りたい用件を、名詞で並べてください。会社の紹介文ではなく「訪問者が何をしに来たら歓迎か」の一覧です。1 行 1 種類で 3〜6 行あれば十分です。
こう書く — 用件が名詞で並んでいる
こう書かない — 会社紹介になっていて、用件が分からない
- 迷いやすいものこそ書く
採用応募・取材・登壇依頼・既存のお客様からの連絡は、書いておかないと売り込みに見えることがあります。 - 「スパム以外」とは書かない
何が歓迎かの手がかりが無くなり、本文の雰囲気だけで判断することになります。 - 要らないものはここに書かない
断りたいものは次の「自然文のポリシー」に分けて書くと、両方がはっきりします。
2自然文のポリシー(任意)#
歓迎する問い合わせが「受け取りたいもの」なら、こちらは境界線です。売り込みに見えるが受け取りたいもの、逆に丁寧でも要らないものを、ふつうの文章で書いてください。
SES・常駐エンジニアの人材提案は不要。
開発パートナーとしての協業の打診は見たい。
既存のお客様からの不具合連絡は最優先で受け取りたい。ジャンルまるごとで決まっている話(「採用支援の売り込みは全部いらない」など)は、文章よりも「このジャンルは売り込みでも受け取る」のチェックボックスの方が確実です。ポリシーは文章として読まれるぶん、揺れることがあります。
3このジャンルは売り込みでも受け取る#
売り込みは次のジャンルに分類されます。チェックを付けたジャンルは、売り込みだと判定されても必ず問い合わせ一覧に入り、通知されます。「開発の協業の話だけは見たい」のように、例外を機械的に決めたいときに使ってください。
4サービス名と通知#
- サービス名
判定のときに「誰宛ての問い合わせか」として読まれます。正式名称に加えて、よく呼ばれる屋号や英語表記も入れておくと、本文中の呼びかけと結び付きやすくなります。 - Webhook URL
入れておくと、問い合わせ一覧に入ったものが設定した Webhook に送られます。未設定でも取りこぼしはありませんが、画面を見に行くまで気付けません(httpsの URL のみ)。Pro プランのみSlack への通知は Pro プランの機能です。汎用 Webhook は Free でも使えます。
Pro プランのみスプレッドシートへの追記は Pro プランの機能です。汎用 Webhook は Free でも使えます。
- 通知先のメールアドレス
問い合わせ一覧に入ったものがあると、「届きました」という知らせと管理画面へのリンクだけをメールで送ります。問い合わせの内容はメールに載せないので、中身は管理画面で確認してください。カンマ区切りで 5 件まで入れられます。Pro プランのみメール通知は Pro プランの機能です。汎用 Webhook は Free でも使えます。
- 署名シークレット
Webhook URL を保存すると自動で払い出されます。フォームの画面に表示されるので、受け取り側の環境変数(例:INQBOX_WEBHOOK_SECRET)に入れてください。通知にはX-Inqbox-TimestampとX-Inqbox-Signature(sha256=+HMAC-SHA256(シークレット, "タイムスタンプ.ボディ")の 16 進数)が付きます。漏れたときはフォームの画面の「署名シークレットの再生成」で作り直せますが、古い値で検証している受け取り側は署名エラーになります。 - Webhook は再送されることがある
届いた通知にはX-Inqbox-Delivery-Id(値は問い合わせ ID)が付きます。同じ問い合わせに対する通知が複数回届くことがあるので、この ID で重複を判定して2回目以降は捨ててください。届かなかった場合は間隔をあけて再送します(4xx を返した場合は再送しません。408・429 は再送します)。内部アドレスへは送らず、リダイレクトも追いません。
// 受け取り側(Next.js の route handler の例)
import crypto from "node:crypto";
export async function POST(req) {
// 生のまま使う(JSON.parse して再シリアライズすると署名が合わなくなる)
const body = await req.text();
const timestamp = req.headers.get("X-Inqbox-Timestamp") ?? "";
const signature = req.headers.get("X-Inqbox-Signature") ?? "";
const secret = process.env.INQBOX_WEBHOOK_SECRET;
if (!secret) return new Response("misconfigured", { status: 500 });
// 古い通知の使い回し(リプレイ)を弾く
// Number.isFinite を先に見る(数字でないヘッダは NaN になり、比較が必ず false になる)
const sentAt = Number(timestamp);
if (!Number.isFinite(sentAt) || Math.abs(Date.now() / 1000 - sentAt) > 300) {
return new Response("stale timestamp", { status: 400 });
}
const expected =
"sha256=" +
crypto
.createHmac("sha256", secret)
.update(timestamp + "." + body)
.digest("hex");
// timingSafeEqual はバイト長が違うと throw するので、先に Buffer にして長さを比べる
// (文字数で比べると、同じ文字数でもバイト長が違う非 ASCII のヘッダで throw する)
const sent = Buffer.from(signature);
const want = Buffer.from(expected);
if (sent.length !== want.length || !crypto.timingSafeEqual(sent, want)) {
return new Response("invalid signature", { status: 401 });
}
// 重い処理は待たずに即 200 を返す(タイムアウトすると通知は失敗扱いになる)
// handleInquiry は受け取り側で用意する自前の処理(この例には含まれません)
void handleInquiry(JSON.parse(body));
return new Response(null, { status: 200 });
}検証は次の 4 点を守ってください。① 署名は await req.text() で取った生のボディに対して計算する(JSON にしてから作り直すと文字列が変わって一致しません)。② X-Inqbox-Timestamp も署名対象に含まれるので、現在時刻から ±300 秒を超えるものは古い通知の使い回しとして弾く。③ 比較は crypto.timingSafeEqual で行う(バイト長が違うと例外になるため、先に Buffer にしてバイト長を比べる)。④ 重い処理は待たずに即 200 を返す。
5どう振り分けられるか#
判定は 1 通ごとにその場で行われます。材料は次の 3 つだけで、過去の問い合わせも、他社の設定も参照しません。
- 設定
歓迎する問い合わせ・ポリシー・ジャンルの例外 - 問い合わせ
本文と、送信前に見ていたページ - 直近の訂正
同じフォームで人が振り分けを直した、新しいほうから 5 件 - フォームの使われ方
選択欄・件名・きっかけ・同じ回線からの連投
判定
- 問い合わせ一覧
- 確認待ち
- スパム一覧
振り分けを手で直すと、左の「直近の訂正」に入ります(訂正は次の判定の例になります を参照)。「設定」が書き換わることはありません。
行き先は、上から順に当てはまったところで決まります。
| こういうとき | 行き先 | 補足 |
|---|---|---|
| フォームに登録した文字列を含んでいた | スパム一覧 | AI の判定を待たずに決まります。ジャンルの例外より優先されます |
| チェックしたジャンルだと判定された | 問い合わせ一覧 | フォームの不審な使われ方や売り込み度より優先されます |
| フォームの不審な使われ方に当たった | スパム一覧 | 選択欄を 1 つも触っていない、件名が異様に長い、きっかけを全部チェックしている |
| 売り込み度 80% 以上 | スパム一覧 | 売り込みだと言い切れる |
| 売り込み度 50% 〜 80% | 確認待ち | 迷ったもの。ここが多いなら設定を足す合図 |
| 売り込み度 50% 未満 | 問い合わせ一覧 | ふつうの問い合わせ |
| 判定そのものが失敗した | 問い合わせ一覧 | 取りこぼさない側に倒します(フォームのルールに当たっていたときだけスパム一覧) |
設定を直したあとの判定から反映されます。過去の問い合わせは振り分け直されません。
6うまく分かれないときは#
- 確認待ちが多い
迷われている証拠です。確認待ちに溜まったものを読んで、歓迎する問い合わせに足りない用件を書き足してください。 - 欲しい問い合わせがスパム一覧に入る
その用件を歓迎する問い合わせに 1 行足すのが先です。ジャンルでまとめて決められるなら、チェックを付ける方が確実です。 - 売り込みが問い合わせ一覧に入る
ポリシーに「◯◯の提案は不要」と 1 行足してください。あわせて、そのジャンルのチェックが付いたままになっていないか確認を。
7訂正は次の判定の例になります#
間違った振り分けを画面から直すと、同じフォームに次に届く問い合わせを判定するとき、その訂正が「この文面はこちらに直された」という例として添えられます。使われるのは同じフォームで直した新しいほうから 5 件まで(本文は先頭の 300 文字)で、ゴミ箱に入れたものは除きます。ほかのフォームの訂正は使いません。
- 訂正でできること
その 1 件の行き先を正すことと、次の判定に例を見せることです。ただし例は 5 件までで、新しく直すたびに古いものから入れ替わります。毎月のレポートには「判定を訂正した件数」が載るので、訂正が増えている方向(問い合わせ↔スパム)が、設定のどこを足せばいいかの手がかりになります。 - 設定でできること
以後の判定が、毎回必ず変わります。歓迎する問い合わせに 1 行足す、ポリシーに境界線を書く、ジャンルにチェックを付ける — 効き方が強い順にこの 3 つです。 - 過去の問い合わせは直りません
訂正しても設定を変えても、すでに届いたものが振り分け直されることはありません。溜まった確認待ちは手で見てください。
同じ種類の間違いが何度も続くなら、訂正を重ねるより設定に書いてください。訂正の例は入れ替わっていきますが、設定は消えるまで毎回読まれます。
ここで説明した設定は、メニュー「フォーム」から開くフォームごとの画面の「問い合わせの受け取り方針」で変更できます(手順はフォームを作る・直す)。フォームの見た目については埋め込みフォームのカスタマイズをどうぞ。