Webhook の使い方
Reserve Care は、予約を受け付けたときと、予約を取り消したときに、登録した送り先(Webhook)へ予約の内容を送ります。Google Apps Script、Make、Zapier、n8n、ご自身のシステムなどで受け取って、台帳への記録やメールの送信などに使えます。
送り先は、管理画面のフォームの「送り先」のタブで登録します。1つのフォームに3つまで登録できます(Free)。
送る内容
予約を受け付けたとき(booking.created)と、予約を取り消したとき(booking.cancelled)に、次の JSON を POST で送ります。
{
"version": 1,
"event": "booking.created",
"event_id": "evt_0123456789abcdef0123456789abcdef",
"occurred_at": "2026-11-06T14:03:21+09:00",
"booking_id": "8f1c2d3e-4b5a-6789-abcd-ef0123456789",
"form_id": "1a2b3c4d-5e6f-7a8b-9c0d-e1f2a3b4c5d6",
"form_name": "初回相談",
"start_at": "2026-11-10T10:00:00+09:00",
"end_at": "2026-11-10T10:30:00+09:00",
"customer": {
"name": "山田太郎",
"email": "test@example.com",
"phone": "090-0000-0000",
"memo": "駐車場はありますか"
}
}
| 項目 | 内容 |
|---|---|
version |
送る内容の形の版。形を変えるときに上げます |
event |
booking.created(受け付け)か booking.cancelled(取り消し) |
event_id |
出来事ごとの ID。再送のときも同じ値です。重複を見分けるのに使ってください |
occurred_at |
受け付けや取り消しが起きた日時 |
booking_id、form_id、form_name |
予約とフォーム |
start_at、end_at |
予約の日時 |
customer |
予約者が入力した名前、メールアドレス、電話番号、メモ。電話番号とメモは、入力がなければ null |
日時は日本時間で、+09:00 付きの ISO 8601 の形です。
管理画面の「テスト送信」では、架空の予約の内容に "test": true を付けて送ります。
届いたことの扱い
- 送り先が 2xx を返したら成功とします。10秒以内に応答してください
- 3xx(別の URL への転送)は失敗として扱い、転送先には送りません。ただし、Google Apps Script の URL(
script.google.com)が返す 302 は成功とします - 失敗したら、5分後、30分後、2時間後の3回、自動で再送します。それでも失敗したものは、管理画面の「送信の結果」から手動で再送できます
- 再送でも同じ
event_idを送るので、同じevent_idが届いたら、2回目以降は処理しないでください
署名の確かめ方
汎用の送り先には、届いたものが Reserve Care から送られたものかを確かめるための署名を付けます。
X-CareCraft-Signature: t=1762405401,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd
tは送った時刻(UNIX 時間の秒)ですv1は、<t>.<届いた本文そのまま>という文字列を、送り先の秘密の値を鍵にして HMAC-SHA256 で計算し、16進数の小文字にしたものです- 秘密の値(
whsec_で始まる値)は、管理画面の送り先の編集で確かめられます。作り直すと、古い値はすぐに使えなくなります
受け取る側では、次のように確かめてください。
- 届いた本文を JSON に変換する前に、そのままの文字列で署名を計算して比べる。比べるときは、時間で差が出ない方法を使う
tが今の時刻から5分以上ずれていたら受け付けない- 同じ
event_idが届いたら、2回目以降は処理しない
Node.js での例です。
import crypto from "node:crypto";
// rawBody: 届いた本文(文字列のまま)、header: X-CareCraft-Signature の値
export function verify(rawBody, header, secret) {
const match = /^t=(\d+),v1=([0-9a-f]{64})$/.exec(header ?? "");
if (!match) return false;
const t = Number(match[1]);
if (Math.abs(Date.now() / 1000 - t) > 300) return false;
const expected = crypto.createHmac("sha256", secret).update(`${t}.${rawBody}`).digest("hex");
return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(match[2]));
}
Google Apps Script で受け取る
Google Apps Script は、届いたリクエストのヘッダーを読めないので、署名を確かめられません。代わりに、ご自身で決めた長い文字列を URL に付けて、それを確かめてください。
- Google スプレッドシートを作り、シートの名前を「予約」にする
- 「拡張機能」→「Apps Script」を開き、次のコードを貼る。
TOKENは、推測されにくい長い文字列に書き換える - 「デプロイ」→「新しいデプロイ」で、種類は「ウェブアプリ」、アクセスできるユーザーは「全員」にしてデプロイする
- 表示された URL の末尾に
?token=<TOKEN の値>を付けて、Reserve Care の送り先(種類は「汎用」)に登録する - 「テスト送信」を押し、シートに行が増えることを確かめる
const TOKEN = "ここを推測されにくい長い文字列に書き換える";
function doPost(e) {
if (e.parameter.token !== TOKEN) {
return ContentService.createTextOutput("forbidden");
}
const data = JSON.parse(e.postData.contents);
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("予約");
// 同じ event_id は1回だけ記録する(再送で同じものが届くため)
const ids = sheet.getRange("B:B").getValues().flat();
if (ids.includes(data.event_id)) {
return ContentService.createTextOutput("duplicate");
}
sheet.appendRow([
new Date(),
data.event_id,
data.event,
data.booking_id,
data.form_name,
data.start_at,
data.end_at,
data.customer.name,
data.customer.email,
data.customer.phone,
data.customer.memo,
data.test === true ? "テスト" : "",
]);
return ContentService.createTextOutput("ok");
}
URL に付けた文字列は、秘密の値と同じように扱ってください。漏れたときは、TOKEN を書き換えてデプロイし直し、送り先の URL も直してください。
Discord に通知する
Discord には、予約者の名前、予約の日時、フォームの名前と、管理画面へのリンクだけを送ります。メールアドレスなどは送りません。
- Discord のサーバーの設定 →「連携サービス」→「ウェブフック」→「新しいウェブフック」
- 通知を出すチャンネルを選び、「ウェブフック URL をコピー」
- Reserve Care の送り先に、種類「Discord」で URL を登録し、「テスト送信」を押す
Slack に通知する
Slack にも、Discord と同じ内容を送ります。
- Slack の API のサイトで「Create New App」→「Pick features」を選ぶ
- アプリの名前とワークスペースを決める。機能は「Incoming Webhooks」を選び、イベントは選ばずに進む
- アプリの設定の「Incoming Webhooks」を On にし、「Add New Webhook」で通知を出すチャンネルを選ぶ
- できた URL(
https://hooks.slack.com/services/…)を、Reserve Care の送り先に種類「Slack」で登録し、「テスト送信」を押す