LINEで予約を受ける方法は5つあります。LINE公式アカウントの標準機能「LINEで予約」、外部の予約システムをLINEと連携する形、リッチメニューから予約ページへ送るだけの形、オープンソースの拡張ツールL Harnessの予約、Googleフォームとスプレッドシートで組む自作です。どれを選ぶかで、月の費用だけでなく、前日のリマインドを送れるか、キャンセル待ちを回せるか、入会の案内につなげられるかが変わります。この記事では5つを費用・手間・できることで比べ、例の「サンプル料理教室」の体験レッスンならどれで受けるかを判断の順に書きます。LINE公式アカウントを開設済みで、リッチメニューを1つ作ったことがある前提です。
先に決めること
あとから乗り換えると予約データの移し替えが要るので、先に次の5つを決めます。
予約の正本をどこに置くか
「この枠は何人埋まっているか」を誰が知っているかを決めます。予約システムなら台帳、自作ならスプレッドシートの1シートが正本で、LINEのトークは空き枠の数を持っていません。スタッフが手帳とスプレッドシートを両方見て空きを答えている状態は、正本が2つある状態です。実際に運用していると、ダブルブッキングはほぼこの「正本が2つ」から起きます。
予約した人をLINEの友だちと結びつけるか
5つの方法を分ける一番の違いです。
予約の数と枠の形
月の予約件数、1枠の定員、講師の指名の有無を書き出します。外部の予約システムは月の予約件数でプランが分かれているものが多く、件数で費用が決まります。サンプル料理教室の体験レッスンは平日夜1枠と土日2枠の週3枠、1枠4名までなので、多くても月50件ほどです。
予約の時点でお金を受け取るか
事前決済が要るなら、自作は候補から外れます。LINE公式アカウントにもGoogleフォームにも、予約と決済をまとめる仕組みはありません。
誰が予約を管理するか
確認・変更・キャンセルの対応を誰がやるかを決めます。受付担当が日替わりなら、全員が同じ画面をスマホでも見られることが条件です。
予約とLINEの友だちを結びつける意味
LINEの友だち1人ひとりには、Messaging APIで使うユーザーID(Uで始まる33文字の値)があります。予約1件ごとにこのユーザーIDを記録しておくと、その予約をした本人だけにメッセージを送れます。できるようになるのは次のことです。
- 予約が確定した直後に、日時と持ち物をその人だけに送る
- 前日と当日の朝に、その日の参加者だけにリマインドを送る
- キャンセルが出たとき、キャンセル待ちの人だけに空きを知らせる
- 体験に来た人と来なかった人で、入会の案内を送り分ける
- 問い合わせのチャットで、その人の予約履歴がすぐわかる
結びつけないと、リマインドは予約システムのメール頼み、入会の案内は友だち全員への一斉配信になり、来ていない人にも届くのでブロックされやすく、通数も無駄に使います。
LINEで予約を受ける5つの方法
5つを並べると次のようになります。料金は2026年10月時点で、各社の公式の料金ページで確かめた値です。LINE公式アカウント自体の月額(コミュニケーションプラン0円・ライトプラン月5,000円・スタンダードプラン月15,000円、いずれも税別)は別にかかります。
| 方法 | 費用の目安 | 作る手間 | 友だちとの結びつき | 確定・リマインドをLINEで | 向く場面 |
|---|---|---|---|---|---|
| 「LINEで予約」 | 予約手数料0円(連携パートナーの契約プランにより異なる) | 小 | あり | 連携パートナー次第 | 飲食店だけ |
| 外部の予約システムをLINE連携 | RESERVAは本体0円〜+LINE連携オプション月3,300円(税込)、SelectTypeはLINE連携がプレミアム(月10,000円・税込11,000円) | 中 | あり | できる | 枠・講師・コースが多い教室やサロン |
| リッチメニューから予約ページへ | 予約システムの無料プランなら0円 | 小 | なし | できない(予約システムのメール) | まず予約を受け始めたいとき |
| L Harnessの予約 | ソフトウェア利用料0円(Cloudflareの利用量・LINEの配信料金は別) | 大(設置が必要) | あり | できる | 配信やステップ配信もまとめて自前で持ちたいとき |
| 自作(Googleフォーム+スプレッドシート+Messaging API) | 0円 | 中〜大(GASを書く) | あり | できる | 枠が少なく、流れを自分で決めたいとき |
方法によって通数の使い方も変わります。無料メッセージ通数は、Messaging APIで送った分も数えます。Messaging APIの料金ページの数え方は次のとおりです。
| 送り方 | 通数に数えるか | 予約で使う場面 |
|---|---|---|
| 応答メッセージ(相手の発言への返信) | 数えない | 「予約したい」に予約フォームのボタンを返す |
| プッシュメッセージ(1人に送る) | 数える | 確定の連絡、前日・当日のリマインド、空きの通知 |
| マルチキャスト・ナローキャスト・ブロードキャスト | 数える | 来月の日程の一斉案内 |
数えるのは送った相手の人数で、1回に吹き出しを3つ送っても1人なら1通です。ブロック中の人への送信は数えません。無料メッセージ通数を超えると送信はエラーになり、届きません。追加メッセージを買えるのはスタンダードプランだけです(2026年10月時点)。リマインドが月末に止まるのはこのためです。
それぞれの作り方の要点
LINE公式アカウントの「LINEで予約」
LINEヤフー for Businessのサービスページでは「LINEで予約」は飲食店向けとされ、連携パートナーは一休(RESZAIKO)、イデアレコード、ebisol、ぐるなび、TableCheck、トレタ予約台帳、Yahoo!リザベーションマネージャー、ヒトサラ(USEN Media)、Rettyです(2026年10月時点)。料理教室は飲食店ではないので、サンプル料理教室では使えません。
飲食店で使う場合の流れです。
- LINE公式アカウントを作る
- 連携パートナーの予約台帳の管理画面で、LINE公式アカウントと紐づける
- 両方の設定が終わったら受付を始める
連携後、予約フォームは「メッセージ配信」「あいさつメッセージ」「応答メッセージ」でリンクを送る、「リッチメニュー」などのアクションに設定する、「チャット」から個別に送る、「プロフィール」の予約ボタンから受ける、の4通りで置けます。プロフィールの「LINEで予約」ボタンは、連携が完了している、店舗が受付中である、予約在庫がある、の3つを全部満たすときだけ出ます。
外部の予約システムをLINEと連携する
教室・サロン・士業の相談枠のように飲食店以外で予約をLINEにつなぐなら、ここが本命です。予約システムの「LINE連携」は、多くの場合、予約システムがMessaging API経由でこちらのLINE公式アカウントからメッセージを送る仕組みで、予約した人のユーザーIDは予約システムが持ちます。公式の料金・機能ページで確かめた2社の内容です(2026年10月時点)。
| 予約システム | 本体の料金 | LINE連携の条件 | LINEでできること | 事前決済 |
|---|---|---|---|---|
| RESERVA | フリー0円(月50件まで)、ブルー年払い月3,850円・月払い5,500円(月200件まで)ほか、税込 | 全プランで機能追加オプション月3,300円(税込) | 料金ページでは「LINE連携」とだけ記載 | オンラインカード決済、手数料4.9% |
| SelectType | フリー0円、ベーシック月1,500円、プロフェッショナル月3,000円、プレミアム月10,000円(税別) | プレミアムで利用可。他のプランは30日間のお試し | 予約の控え、来店前のリマインド、来店後のお礼、新規予約の管理者への通知 | カード・コンビニ・銀行振込の手数料の記載あり |
RESERVAは一部プランの料金を11月16日に改定する予定です。Airリザーブはフリー0円、ベーシック月5,500円(税込)ですが、料金ページの機能一覧にLINE連携が無いので、次の「リッチメニューから予約ページへ」の形になります。
つなぐ手順の要点です。
- 予約システムで体験レッスンのメニュー・枠・定員を作り、予約ページのURLを出す
- 予約システムの手順で求められたら、LINE公式アカウントでMessaging APIを有効にする
- 予約システムのLINE連携の画面にチャネルの情報を入れる
- リッチメニューの「体験レッスンの予約」に予約ページのURLを設定する
注意が1つあります。Messaging APIのチャネルに設定できるWebhook URLは1つだけです。予約システムのLINE連携がWebhookを使う場合、あとから自作のBotやL Harnessを同じ公式アカウントにつなぐと、どちらかが受け取れなくなります。契約前に、そのLINE連携がWebhook URLを使うかを予約システムのヘルプで確かめます。
リッチメニューから予約ページへ(連携しない)
一番早く始められる形です。予約システムの予約ページのURLを、リッチメニューのボタンに置くだけで、Messaging APIも要りません。PC(管理画面)での手順です。
- LINE Official Account Manager(管理画面)にログインし、公式アカウントを選ぶ
- 「トークルーム管理」の「リッチメニュー」を開く
- 画面右上の「作成」を押す
- 管理用のタイトルと表示期間を入れる
- テンプレートで4分割を選ぶ
- 「画像をアップロードして適用する」で、テンプレートの大きさに合う画像(大は2500×1686、小は2500×843)を上げる
- 左上のエリアのタイプで「URL」を選び、予約ページのURLを入れる
- アクションラベルに「体験レッスンの予約」と入れる
- 残りのエリアに「レッスン日程」「よくある質問」「問い合わせ」を設定する
- メニューバーに表示する文言(例「メニュー」)を入れる
- 「保存」を押す
スマホ(LINE公式アカウントアプリ)では、メニューから「リッチメニュー」を選び、「作成」をタップして同じ順に入れます。アクションラベルは20文字までです。

弱点は、誰がどの友だちか予約システムにわからないことです。確定の連絡とリマインドはメールになり、体験に来た人だけに入会の案内を送ることもできません。それでも受け始めの段階では十分で、あとで移るときもURLを差し替えるだけです。
L Harnessの予約
L Harnessは、GitHubで公開されているオープンソースのLINE公式アカウント向け拡張ツールです(Shudesu/line-harness-oss、MITライセンス)。ソフトウェア利用料は0円で、Cloudflare Workers(Cloudflareのサーバーで動くプログラム)とD1(同じくデータベース)の上で動きます。Cloudflareは無料枠で使え、LINEの配信料金やCloudflareの利用量は別です。D1の無料プランは、日ごとの読み書きの上限に達すると処理がエラーになります。
機能一覧には「カレンダー予約」(Googleカレンダー連携の予約システム)とリマインダーがあります。管理画面の「予約管理」で予約メニュー・担当スタッフ・曜日ごとの受付時間を決めてGoogleアカウントを接続すると、Googleカレンダーに「予定あり」で入っている時間が空き枠から除かれます。公式のドキュメントには、日時を選んだあとにサーバーが空きをもう一度確かめてから確定し、先に別の人が予約していたら選び直してもらう、と書かれています。
ステップ配信・タグ・フォームまでまとめて自前で持ちたい場合に向きます。Cloudflareでの設置が要るので、予約だけのためなら手間が大きい方法です。
自作(Googleフォーム+スプレッドシート+Messaging API)
枠が少なく流れを自分で決めたいなら、Googleフォームとスプレッドシートに、Google Apps Script(GAS。スプレッドシートに付けて動かすプログラム)でMessaging APIをつなぎます。費用は0円です。
[友だち] リッチメニューの「体験レッスンの予約」をタップ
│ 「体験レッスンを予約」というテキストが送られる
▼
[LINEプラットフォーム] ── Webhook ──▶ [GAS doPost]
│◀── 応答メッセージ(通数に数えない)── ユーザーID入りのフォームURLを返す
▼
[Googleフォーム] 名前・希望日を入れて送信(ユーザーIDは事前入力済み)
▼
[スプレッドシート] 回答が1行増える
▼
[GAS フォーム送信時トリガー] 定員を数えて「確定」か「キャンセル待ち」を書く
└── プッシュメッセージ(通数に数える)──▶ [友だち] 確定の連絡
Googleフォームだけでは、送ってきた人のユーザーIDがわかりません。そこで先にLINEで「予約したい」と送ってもらい、その発言から取ったユーザーIDを、フォームの事前入力でURLに入れて渡します。作る順番です。
- 管理画面の「設定」から「Messaging API」を開き、「Messaging APIを利用する」を押す
- プロバイダーを選んで「同意する」、確認画面で「OK」を押す(プロバイダーはあとから変えられない)
- LINE Developersコンソールの「Messaging API設定」タブで、チャネルアクセストークン(長期)を発行して控える
- 同じタブの「応答メッセージ」の「編集」から管理画面に移り、応答メッセージをオフにする
- Googleフォームに「お名前」(記述式)、「希望の日程」(ラジオボタン)、「LINEユーザーID」(記述式)の3つの質問を作る
- フォームの「回答」タブで「スプレッドシートにリンク」を押す
- 回答のシートの右端の空いた列の1行目に「状態」と入れる
- フォーム右上の「︙」から「フォームに事前入力する」を開き、「LINEユーザーID」に仮の値を入れて、画面下の「リンクを取得」でリンクを作り、
entry.で始まる番号を控える - スプレッドシートの「拡張機能」から「Apps Script」を開き、下のコードを貼る
- 「プロジェクトの設定」の「スクリプト プロパティ」に、
LINE_TOKENという名前でトークンを保存する - 「デプロイ」の「新しいデプロイ」で種類を「ウェブアプリ」にし、自分(スクリプトのオーナー)として実行し、ログインしていない相手(LINEプラットフォーム)からも開ける公開範囲にしてデプロイし、URLを控える
- 「トリガー」で関数
onFormSubmit、イベントのソース「スプレッドシートから」、イベントの種類「フォーム送信時」のトリガーを追加する - LINE Developersコンソールの「Messaging API設定」タブで、「Webhook URL」の「編集」を押してウェブアプリのURLを入れ、「更新」を押す。保存すると「検証」と「Webhookの利用」が出るので、「Webhookの利用」がオンになっているか確かめる
- リッチメニューの「体験レッスンの予約」のエリアを、タップすると「体験レッスンを予約」という言葉がトークに送られるアクションに変える
- 自分のスマホで予約を1件通し、確定の連絡が届くことを確かめる



GASのコードです。YOUR_FORM_ID と entry.1234567890 は自分のフォームの値に置き換えます。トークンはコードに書かず、スクリプト プロパティから読みます。
const TOKEN = PropertiesService.getScriptProperties().getProperty('LINE_TOKEN');
const FORM_URL = 'https://docs.google.com/forms/d/e/YOUR_FORM_ID/viewform?usp=pp_url&entry.1234567890=';
const CAPACITY = 4;
function doPost(e) {
const body = JSON.parse(e.postData.contents);
(body.events || []).forEach(function (ev) {
if (ev.type !== 'message' || ev.message.text !== '体験レッスンを予約') return;
callLine('reply', {
replyToken: ev.replyToken,
messages: [{
type: 'template', altText: '体験レッスンの予約フォーム',
template: {
type: 'buttons', text: '希望の日程を選んでください。',
actions: [{ type: 'uri', label: '予約フォームを開く',
uri: FORM_URL + encodeURIComponent(ev.source.userId) }]
}
}]
});
});
return ContentService.createTextOutput('OK');
}
function onFormSubmit(e) {
const lock = LockService.getScriptLock();
lock.waitLock(30000);
try {
const sheet = e.range.getSheet();
const r = e.range.getRow() - 1;
const data = sheet.getDataRange().getDisplayValues();
const h = data[0];
const slotC = h.indexOf('希望の日程'), idC = h.indexOf('LINEユーザーID'), stC = h.indexOf('状態');
const slot = data[r][slotC], userId = data[r][idC];
if (!isFriend(userId)) { sheet.getRange(r + 1, stC + 1).setValue('要確認'); return; }
const count = data.filter(function (d, i) {
return i > 0 && i !== r && d[slotC] === slot && d[stC] === '確定';
}).length;
const status = count < CAPACITY ? '確定' : 'キャンセル待ち';
sheet.getRange(r + 1, stC + 1).setValue(status);
const text = status === '確定'
? '体験レッスンのご予約を承りました。\n日程:' + slot + '\n持ち物:エプロン'
: slot + 'は満席のため、キャンセル待ちで承りました。空きが出たらお知らせします。';
callLine('push', { to: userId, messages: [{ type: 'text', text: text }] });
} finally {
lock.releaseLock();
}
}
function isFriend(userId) {
if (!/^U[0-9a-f]{32}$/.test(userId)) return false;
const res = UrlFetchApp.fetch('https://api.line.me/v2/bot/profile/' + userId, {
headers: { Authorization: 'Bearer ' + TOKEN }, muteHttpExceptions: true
});
return res.getResponseCode() === 200;
}
function callLine(type, payload) {
const res = UrlFetchApp.fetch('https://api.line.me/v2/bot/message/' + type, {
method: 'post', contentType: 'application/json',
headers: { Authorization: 'Bearer ' + TOKEN },
payload: JSON.stringify(payload), muteHttpExceptions: true
});
if (res.getResponseCode() !== 200) console.log(type + ' ' + res.getContentText());
}
フォームのボタンは応答メッセージで返すので、何度押されても通数は減りません。isFriend は「プロフィール取得が200を返せばユーザーIDは有効」という公式の記述を使った確認で、転送やIDの書き換えで送れない相手は「要確認」にしてスタッフが見ます。LockService は処理を1件ずつにして、同じ枠への同時送信で定員を数え間違えないためのものです。前日・当日のリマインドも、毎朝動くトリガーで「確定」の行に送れば作れます。

サンプル料理教室で選ぶなら
サンプル料理教室で受けるのは、体験レッスンと会員の通常レッスンの2種類です。体験は週3枠・1枠4名で月50件以下、通常レッスンは会員が月に数回、複数の枠と講師から選びます。判断は次の順で進めます。
- 飲食店か。料理教室は飲食店ではないので「LINEで予約」は外れる
- 予約の時点で決済が要るか。体験の材料費は当日現金なので要らない。要るなら外部の予約システムに決まる
- 予約した人を友だちと結びつけたいか。体験の前日・当日のリマインドと入会案内に使うので結びつけたい。ここで「リッチメニューから予約ページへ」が外れる
- 枠と予約数は多いか。体験は少なく、通常レッスンは多い
- 誰が管理するか。体験の受付は2名が交代で、スプレッドシートに慣れている
この流れで次のように決めます。
| 予約の種類 | 選ぶ方法 | 理由 |
|---|---|---|
| 体験レッスン | 自作(Googleフォーム+スプレッドシート+Messaging API) | 枠が少なく定員の判定が単純。ユーザーIDを持てるので、リマインドと入会案内までスプレッドシート1枚でつながる |
| 通常レッスン(会員) | 外部の予約システムをLINE連携 | 枠・講師・振替が多く、自作では壊れやすい。予約時の決済にも移りやすい |
通数も見積もります。体験の予約が月30件で、確定・前日・当日の3通なら90通です。友だち400人に月2回の日程案内を送ると800通が加わり、コミュニケーションプランの200通を超えるので、ライトプラン(5,000通)にします。通常レッスンの予約システムがLINEでリマインドを送るなら、その分も同じ公式アカウントの通数から出ます。
通常レッスンの予約システムのLINE連携がWebhook URLを使うなら、体験の自作Botとは同居できないので、体験も予約システムに寄せます。
応用
キャンセルとキャンセル待ちを回す
自作なら、スタッフが「状態」を「キャンセル」に書き換えたとき、同じ枠の「キャンセル待ち」の一番上の人に空きを知らせる関数を、スプレッドシートの編集時のトリガーで動かします。自動で確定まで進めると、繰り上がった人が来られないことがあるので、「参加されるならこのトークで返信してください」と送り、返事が来てから確定にするほうが運用は安定します。
スタッフへの通知と来店の記録
スタッフへの予約の通知は、GASからメールで送れば通数を使いません。体験に来た人には当日ショップカードのポイントを付け、次のレッスンで使えるクーポンを渡します。シートで「参加」に印を付けた人にだけ入会案内のステップを始めると、来なかった人に入会案内が届くことがなくなります。
LIFFやLINEミニアプリで予約画面を作る
LIFF(LINEの中で開くWebアプリの仕組み)で予約画面を作れば、事前入力に頼らずユーザーIDを受け取れます。LIFFとLINEミニアプリはブランド統合が予定されていて、新しく作るならLINEミニアプリとして作ることが推奨されています。
できないことと、その代わり
| できないこと | 理由 | 代わりの手 |
|---|---|---|
| 標準機能だけで教室の予約枠を管理する | 「LINEで予約」は飲食店向け | 外部の予約システムか自作で枠を持つ |
| Googleフォームで送信前に満席を止める | フォームは選択肢ごとの定員を見ない | 送信後にGASで数えてキャンセル待ちで返し、満席の選択肢は手で消す。送信前に止めたいなら予約システム |
| 予約と同時に決済を受ける | 公式アカウントにもフォームにも決済の仕組みがない | RESERVAのオンラインカード決済、Airリザーブのオンライン決済など予約システムの事前決済 |
| GASでWebhookの署名を確かめる | 署名は x-line-signature ヘッダーに入るが、公式のdoPostのイベントオブジェクトにリクエストヘッダーは含まれない | doPostはフォームのリンクを返すだけにし、確定や書き換えはしない。検証まで要るならヘッダーを読めるn8nやCloudflare Workersで受ける |
| 友だちでない人にLINEで確定を送る | プッシュメッセージは友だちにしか届かない | フォームにメールアドレスの欄を足し、届かない人にはメールで送る |
| 予約システムのLINE連携と自作Botを両方Webhookで動かす | Webhook URLは1チャネルに1つ | どちらかに寄せる |
よく詰まるところ
| 症状 | 原因 | 直し方 |
|---|---|---|
| 月の後半に確定の連絡が届かなくなった | 無料メッセージ通数を使い切った。コミュニケーションとライトは追加で買えない | 送信数を見てプランを上げる。一斉配信を減らしリマインドを優先する |
| 「体験レッスンを予約」を押しても何も返らない | 「Webhookの利用」がオフ、URLが古い、テキストが一字違う | 「Webhookの利用」をオンにし、URLを貼り直す。リッチメニューとコードの文言を全角・半角まで揃える |
| GASを直したのに動きが変わらない | デプロイを更新していない | 「デプロイの管理」で今のデプロイを編集し、新しいバージョンを選ぶ。この方法ならURLは変わらない |
| フォームのボタンと一緒に自動の応答も出る | 応答メッセージがオンのまま | 応答メッセージをオフにする。Webhookがオフのままで応答・あいさつを両方オフにはできないが、この構成はWebhookをオンにするので、応答・あいさつとも切ってよい |
| 「LINEユーザーID」が空や「要確認」になる | Webサイトなどに貼られた普通のフォームURLから開かれた | フォームのURLを外に貼らず、リッチメニューから開くよう案内する |
| プッシュメッセージが401で失敗する | トークンの誤り、または長期のトークンを再発行して古いものが無効になった | スクリプト プロパティを新しい値に直す。同じトークンを使う他のツールも直す |
| 予約システムのLINE連携を入れたら自作Botが黙った | 予約システムがWebhook URLを書き換えた | どちらに寄せるか決める |
| 同じ枠に定員より多い「確定」が付いた | 選択肢の文言を途中で変え、同じ枠が2つの書き方で並んだ | 選択肢は「体験A:11月8日(土)10時」のように固定し、途中で変えない |
| 「希望の日程」が日付に化けて数がずれる | 「11/8 10:00」のような選択肢をスプレッドシートが日付と読んだ | 選択肢の頭に文字を付け、コードは表示どおりの値(getDisplayValues)で比べる |
| 差し替えたのに古い予約ページが開く | リッチメニューが端末に反映されるまで時間がかかる | トークを開き直して待つ。急ぐときはトークに新しいリンクを1回送る |
| プロフィールの「予約」ボタンが消えた | 予約ページのURLを直接置けた「予約」ボタンは、2025年10月22日のプロフィールの仕様変更で廃止された | URLは基本情報の「Webサイト」に移っている。予約の導線はリッチメニューに置く。別物の「LINEで予約」ボタンは、連携済みの飲食店だけに出る |
次にやること
予約を受けられるようになったら、次は無断キャンセルを減らす仕組みです。前日と当日のリマインドは「予約のリマインドをLINEで自動送信する:前日・当日の通知と無断キャンセル対策」で組みます。
問い合わせも同じスプレッドシートに残すと、予約と問い合わせを同じユーザーIDで追えます。作り方は「LINEの問い合わせをスプレッドシートに貯める:Webhookで1件ずつ記録する」にあります。
LINEの中で開く予約画面を作るかどうかは「LINEミニアプリとLIFF:何が違い、自社に要るか」で判断できます。予約・フォーム・ステップ配信をまとめて自前で持つなら「L Harnessで予約・フォーム・ステップ配信を組む:教室の例で一通り」に進みます。