LINE公式アカウントに届いたメッセージを、スプレッドシートやSlackなど別のサービスへ流すときに使うのが、n8n・Make・Zapierのような自動化の道具です。どれも画面でブロックをつないで組むので、プログラムを書かなくても形になります。この記事では、サンプル料理教室の公式アカウントで「問い合わせが届いたらスプレッドシートに残し、Slackでスタッフに知らせ、受付時間外なら自動で返す」仕組みを、n8nで最初から最後まで組みます。そのあとで、MakeとZapierで同じことをするときの違いを書きます。Messaging APIの利用を始めていて、チャネルアクセストークンを発行できる状態が前提です。
この記事の内容
先に決めること
組み始めてから変えると、作り直しになる判断が5つあります。
- 標準機能で足りないか。受付時間外に決まった文面を返すだけなら、管理画面(LINE Official Account Manager)の「応答時間」で時間外の応答方法を選べば、標準機能で自動で返せます。自動化の道具が要るのは、届いた内容を別の場所に残したいとき、スタッフにSlackなどで知らせたいとき、内容や時刻で返す文面を変えたいときです
- Webhookの送り先を1か所にする。Messaging APIチャネルの「Webhook URL」の欄は1つです。n8nとMakeの両方に同じメッセージを送ることはできないので、受け口の道具を1つに決めます。ほかの道具には、受け口から転送します
- 返信を誰がするか。スタッフが管理画面のチャットで返す運用と、道具が自動で返す運用を同じ時間帯に混ぜると、同じ人に二重に返信が届きます。実際に運用していると「誰が返しているのか分からない」と言われます。サンプル料理教室では、受付時間内はスタッフが手で返し、時間外だけ道具が返すと決めました
- スタッフへの知らせ先。以前よく使われたLINE Notifyは終了しています(次の節)。Slack・メール・Messaging APIのプッシュのどれにするかを決めます
- 道具をどこで動かすか。n8nは自分のサーバーで動かす版と、n8nが運営するクラウド版があります。MakeとZapierはクラウドで使う前提です。問い合わせの本文がどこに保存されるかも含めて選びます
LINE Notifyは終了している
LINE Notifyは、2025年3月31日にサービスを終了しました。公式の終了のお知らせでは、通知を送る代わりの方法として、LINE公式アカウントからメッセージを送るMessaging APIを案内しています。
古い記事にある「LINE Notifyのトークンで通知を送る」手順は、今は使えません。n8nの「Line」ノードもLINE Notify用で、n8n 1.64.0から非推奨です。
代わりは次の2つです。
- スタッフへの知らせをSlackやメールで受ける。スタッフ側のLINEを使わないので、通数もかかりません
- スタッフにLINEで知らせたいときは、スタッフ全員に教室の公式アカウントを友だち追加してもらい、Messaging APIのプッシュでスタッフ宛てに送る。プッシュは料金プランのメッセージ通数にカウントされます
3つの道具の比較
2026年10月時点の公式ページの内容です。
| 項目 | n8n | Make | Zapier |
|---|---|---|---|
| LINE専用の部品 | 「Line」ノードはLINE Notify用で非推奨。Messaging API用の専用ノードは無い | 「LINE」アプリがある。トリガー「Watch Events」と、リッチメニューの作成・削除、添付ファイルの取得、友だち数・配信数の取得などのモジュール(全17) | アプリ一覧にLINEのページが見つからない |
| 受け方 | Webhookノード | LINEの「Watch Events」、または「Webhooks」の「Custom webhook」 | 「Webhooks by Zapier」の「Catch Hook」「Catch Raw Hook」 |
| 送り方 | HTTP Requestノード | LINEのモジュール、またはHTTPの「Make a request」 | 「Webhooks by Zapier」の「POST」「Custom Request」 |
| 受けたときの応答 | 「Immediately」「When Last Node Finishes」「Respond to Webhook」ノードから選ぶ | 応答のモジュールが無ければ受け付けた時点で200「Accepted」。「Webhook response」で指定もできる | 既定で200を返す。中身は変えられない |
| 署名の検証に使えるもの | 「Crypto」ノードのHmac(SHA256・BASE64) | 「Get request headers」でヘッダー、「JSON pass-through」で本文を文字列のまま受け取れる | 「Catch Raw Hook」でヘッダーと解析前の本文を受け取れる |
| 自分のサーバーで動かす | できる(Community版。Docker) | 料金ページに案内は無い | 料金ページに案内は無い |
料金の入口は次のとおりです(2026年10月時点)。
| 道具 | 無料の範囲 | 有料の入口 |
|---|---|---|
| n8n | 自分のサーバーで動かすCommunity版は無料。サーバー代は別 | クラウドのStarterが20ユーロ/月(年払い)で月2,500実行。Proが50ユーロ/月(年払い)で月10,000実行 |
| Make | Freeプランで月1,000クレジット | Core・Pro・Teams・Enterprise(金額は料金ページで選ぶ) |
| Zapier | Freeプランは月100タスク、2ステップまで。Webhooks by Zapierは使えない | Proが19.99ドル/月(年払い)・29.99ドル(月払い)で月750タスクから |
Zapierは、LINEとつなぐのにWebhooks by Zapierが要るので、実質は有料プランからです。n8nのクラウド版は実行数で上限が決まり、友だち追加やブロックのWebhookでもワークフローが動くので、問い合わせの件数より多めに見積もります。
LINE側の費用も忘れずに見ます。Messaging APIの応答メッセージ(reply)は通数にカウントされず、プッシュはカウントされます。無料の通数は料金プランで決まり、月額0円のプランが200通、ライトプランが5,000円で5,000通、スタンダードプランが15,000円で30,000通です(税別・2026年10月時点)。
サンプル料理教室で作るもの
受付時間は、スタッフがチャットを見られる10時から20時までにしました。流れは次のとおりです。
| 順番 | 何をするか | n8nのノード |
|---|---|---|
| 1 | LINEからWebhookを受ける | Webhook |
| 2 | 署名を計算して、LINEから届いたものか確かめる | Crypto、If |
| 3 | 本文をJSONに戻し、イベントを1件ずつに分ける | Extract from File、Split Out |
| 4 | テキストのメッセージだけを残す | Filter |
| 5 | 受付時間外なら自動で返す | If、HTTP Request |
| 6 | スプレッドシートに1行足す | Google Sheets |
| 7 | Slackに知らせる | Slack |
返信を記録より先に置くのは、応答トークンに1分の期限があるからです。

n8nで作る手順
準備:LINE側で控えておくもの
- LINE Developersコンソールを開き、サンプル料理教室のプロバイダーとMessaging APIチャネルを選ぶ
- 「チャネル基本設定」タブで「チャネルシークレット」を控える
- 「Messaging API設定」タブで、チャネルアクセストークン(長期)を「発行」して控える
シークレットは署名の検証に、トークンは返信とプッシュに使います。n8nではノードに直接書かず、認証情報(Credentials)に入れます。

1. Webhookノードで受ける
- n8nで新しいワークフローを作る
- ワークフローの設定で、タイムゾーンを「Asia/Tokyo」にする
- 最初のノードに「Webhook」を置く
- 「HTTP Method」を「POST」にする
- 「Path」に
line-inboxと入れる - 「Respond」を「Immediately」にする
- オプションの「Raw Body」をオンにする
n8nの既定のタイムゾーンはアメリカ・ニューヨークなので、2番を飛ばすと時刻の判定がずれます。6番は、うしろの処理を待たずに200を返す設定です。7番は署名の検証のためで、受け取ったままの本文を取っておきます。
テスト用のURLは画面で受信待ちにしているあいだだけ動き、本番用のURLはワークフローを公開(有効化)すると動きます。本番の中身は「Executions」タブで見ます。
2. LINEにWebhook URLを登録する
- Webhookノードでテスト用のURLをコピーする
- Webhookノードを受信待ちにする
- LINE Developersコンソールの「Messaging API設定」タブで、「Webhook URL」の「編集」を押す
- コピーしたURLを貼り、「更新」を押す。「検証」と「Webhookの利用」は、URLを保存したあとに出る
- 「検証」を押し、「成功」と出るのを確かめる
- 「Webhookの利用」をオンにする
Webhook URLはHTTPSで、一般のブラウザが信頼する認証局の証明書が要ります。自分のサーバーでn8nを動かすときは、自己署名の証明書では登録できません。
Webhookのオン・オフは、管理画面の「設定」>「応答設定」の「Webhook」と同期しています。どちらで切り替えても同じです。

3. 署名を確かめる
LINEはWebhookのヘッダー x-line-signature に署名を入れて送ってきます。署名は、チャネルシークレットを鍵にして、本文をHMAC-SHA256で計算し、BASE64にしたものです。同じ計算をして一致したときだけ処理します。
- Webhookノードのうしろに「Crypto」ノードを置く
- 「Action」を「Hmac」にする
- 「Type」を「SHA256」にする
- 「Encoding」を「BASE64」にする
- 「Binary File」をオンにし、「Binary Property Name」に本文が入っているバイナリの名前(既定は
data)を入れる - 「Property Name」を
calcSignatureにする - 認証情報の「Hmac Secret」に、チャネルシークレットを入れる
- うしろに「If」ノードを置き、
{{ $json.calcSignature }}が{{ $('Webhook').item.json.headers['x-line-signature'] }}と等しいかを条件にする - 一致しない側には何もつながない
テスト実行で、本文がバイナリとして出ている名前を先に見て、5番を合わせます。公式ドキュメントは、検証の前に本文を加工しないこと、UTF-8で扱うこと、IPアドレスで制限しないこと(LINEのIPは非公開)を求めています。
4. 本文をJSONに戻し、1件ずつに分ける
- Ifの一致した側に「Extract from File」ノードを置く
- 「Operation」を「Extract From JSON」にする
- 「Input Binary Field」を
dataにする - うしろに「Split Out」ノードを置き、分ける項目に
eventsを指定する
1回のWebhookに複数のイベントが入ることがあるので、1件ずつに分けます。「検証」ボタンのWebhookはイベントが空なので、ここで終わります。
メッセージのイベントは次の形で届きます(要るところだけ抜き出しています)。
{
"destination": "Uxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"events": [
{
"type": "message",
"mode": "active",
"timestamp": 1761530400000,
"webhookEventId": "01JXXXXXXXXXXXXXXXXXXXXXXX",
"deliveryContext": { "isRedelivery": false },
"replyToken": "xxxxxxxxxxxxxxxxxxxxxxxx",
"source": { "type": "user", "userId": "Uxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" },
"message": { "id": "xxxxxxxxxxxxxx", "type": "text", "text": "体験レッスンは子ども連れでも大丈夫ですか" }
}
]
}

5. テキストのメッセージだけを残す
- Split Outのうしろに「Filter」ノードを置く
- 条件1に
{{ $json.type }}がmessageと等しい、を入れる - 条件2に
{{ $json.message.type }}がtextと等しい、を入れる - 2つの条件を「AND」でつなぐ
友だち追加(follow)やブロック(unfollow)、スタンプや画像もWebhookで届くので、ここで落とします。
6. 受付時間外なら自動で返す
- Filterのうしろに「If」ノードを置く
- 条件に
{{ $now.hour }}が10より小さい、を入れる - 条件をもう1つ足し、
{{ $now.hour }}が20以上、を入れる - 2つの条件を「OR」でつなぐ
- trueの側(時間外)に「HTTP Request」ノードを置く
- 「Method」を
POST、「URL」をhttps://api.line.me/v2/bot/message/replyにする - 「Authentication」で、ヘッダーに
Authorization: Bearer YOUR_CHANNEL_ACCESS_TOKENを送る認証情報を作って選ぶ - 「Send Body」をオンにし、「Body Content Type」を「JSON」にして、次の本文を入れる
{
"replyToken": "{{ $json.replyToken }}",
"messages": [
{
"type": "text",
"text": "サンプル料理教室です。お問い合わせありがとうございます。受付時間(10:00〜20:00)外のため、翌日10時以降にスタッフからお返事します。"
}
]
}
タイムゾーンを「Asia/Tokyo」にしてあるので、$now.hour は日本時間の時です。応答トークンは1回しか使えず、受け取ってから1分以内に使う決まりです。1回で送れるメッセージは5つまでです。

7. スプレッドシートに1行足す
先にGoogleスプレッドシートを用意し、1行目に 受信日時 webhookEventId userId 内容 時間外 の5つの見出しを入れておきます。
- Filterの出力から、時間判定のIfとは別の線で「Google Sheets」ノードにつなぐ
- 「Resource」を「Sheet Within Document」、「Operation」を「Append or Update Row」にする
- 「Document」と「Sheet」で、用意したスプレッドシートとシートを選ぶ
- 「Mapping Column Mode」を「Map Each Column Manually」にする
- 既存の行と照らし合わせる列に
webhookEventIdを指定する - 受信日時に
{{ DateTime.fromMillis($json.timestamp).toFormat('yyyy-MM-dd HH:mm:ss') }}を入れる - webhookEventIdに
{{ $json.webhookEventId }}、userIdに{{ $json.source.userId }}、内容に{{ $json.message.text }}を入れる - 時間外に
{{ $now.hour < 10 || $now.hour >= 20 }}を入れる
「Append or Update Row」でwebhookEventIdを照合するので、同じイベントが2回届いても1行に上書きされます。

8. Slackに知らせる
- Google Sheetsのうしろに「Slack」ノードを置く
- 認証情報を作る(OAuth2かAccess Tokenのどちらか)
- 「Resource」を「Message」、「Operation」を「Send」にする
- 送り先に、スタッフが見ているチャンネル(例:
#line-問い合わせ)を選ぶ - 本文に次を入れる
LINEに問い合わせが届きました
内容:{{ $('Filter').item.json.message.text }}
時間外の自動返信:{{ $now.hour < 10 || $now.hour >= 20 ? '送信済み' : 'なし(スタッフが返信)' }}
返信は管理画面のチャットから
Slackのボットは、送り先のチャンネルに招待しておかないと投稿できません。

9. テストして本番に切り替える
- Webhookノードを受信待ちにする
- スタッフのスマホから教室の公式アカウントに「テスト」と送る
- 各ノードの出力を順に見て、署名のIfが一致した側に進んでいるかを確かめる
- スプレッドシートに1行増え、Slackに通知が届いたかを確かめる
- 時間外の分岐は、Ifの条件の
20を一時的に今の時より小さい数にして確かめ、終わったら戻す - ワークフローを公開(有効化)する
- LINE Developersコンソールの「Webhook URL」を本番用のURL(
/webhook/line-inboxで終わるもの)に差し替え、「検証」を押す
テスト用のURL(/webhook-test/ を含むもの)のままだと、受信待ちでないあいだのWebhookがすべて失敗します。開発ガイドラインは、検証用のアカウントで確かめてから本番に適用するよう求めているので、サンプル料理教室もテスト用の公式アカウントで組んでから移しました。
プッシュで送る形
こちらのタイミングで送るときはプッシュを使います。スタッフにLINEで知らせる場合や、翌日に返事を送る場合です。
curl -X POST https://api.line.me/v2/bot/message/push \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer YOUR_CHANNEL_ACCESS_TOKEN' \
-H 'X-Line-Retry-Key: 123e4567-e89b-12d3-a456-426614174000' \
-d '{
"to": "Uxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"messages": [
{ "type": "text", "text": "体験レッスンのご質問にお答えします。お子さま連れでのご参加も大丈夫です。" }
]
}'
返信との違いは次のとおりです。
| 項目 | 返信(reply) | プッシュ(push) |
|---|---|---|
| エンドポイント | https://api.line.me/v2/bot/message/reply | https://api.line.me/v2/bot/message/push |
| 宛先の指定 | replyToken | to にユーザーIDなど |
| 使えるとき | Webhookを受けてから1分以内、1回だけ | いつでも |
| 1回で送れるメッセージ | 5つまで | 5つまで |
| メッセージ通数 | カウントされない | 送った相手の人数でカウントされる |
| 再試行のキー | 使えない | X-Line-Retry-Key を付けられる |
X-Line-Retry-Key は送る側で作るUUIDで、最初のリクエストから24時間有効です。同じキーで送り直すと、受付済みなら409が返り、二重には届きません。再試行するのは500とタイムアウトのときだけで、200番台・409・ほかの400番台は再試行しません。
署名・タイムアウト・再送の扱い
公式ドキュメントに書かれている決まりをまとめます。
| 項目 | 公式の決まり | n8nでの扱い |
|---|---|---|
| 署名 | x-line-signature を、チャネルシークレットを鍵にしたHMAC-SHA256(BASE64)で照合する。不一致や署名なしは処理しない | Raw BodyをオンにしてCryptoノードで計算し、Ifで照合 |
| 応答 | ステータスコード200を返す。イベントが空の疎通確認にも200を返す | Webhookノードの「Respond」を「Immediately」 |
| タイムアウト | 秒数は公開されていない。Webhookの検証結果の原因に REQUEST_TIMEOUT(リクエストがタイムアウトしました)がある | 処理を待たずに200を返す |
| 処理の仕方 | 非同期で処理することを推奨 | 200を先に返し、うしろのノードで処理 |
| 応答トークン | 1回だけ、受信から1分以内 | 返信を記録やSlackより前に置く |
| 再送 | 既定はオフ。「Webhookの再送」をオンにすると、200番台を返さなかったときに一定期間・一定間隔で再送される。回数と間隔は非公開 | オンにするなら、記録をwebhookEventIdで照合して重複を防ぐ |
| 重複 | 再送をオフにしていても、同じイベントが重複して届くことがある。見分けは webhookEventId | 「Append or Update Row」で同じ行に上書き |
| 順番 | 再送で順番が前後することがある。前後関係は timestamp で見る | スプレッドシートは受信日時で並べ替える |
| 再送の目印 | deliveryContext.isRedelivery が true | 再送ならSlackの通知を省く分岐を入れてもよい |
再送されたWebhookの応答トークンは、受けてから1分以内なら使えます。元のトークンを使い済みか、イベントから20分を過ぎていれば使えません。LINEは確実な再送を保証しておらず、受信の失敗が長く続くと送信が止まることもあるので、サーバーを止めるときは先に「Webhookの利用」をオフにします。
Make・Zapierで同じことをする場合
Makeの場合
MakeにはLINEのアプリがあり、トリガーの「Watch Events」を置くと、Make側でWebhook URLが作られます。そのURLをLINE Developersコンソールの「Webhook URL」に入れて「Webhookの利用」をオンにすれば、イベントが届くたびにシナリオが動きます。接続には、チャネルアクセストークンなど、Makeの画面で求められる項目を入れます。自分のユーザーIDを求められたら、Webhookのイベントの source.userId で控えたものを使います(管理画面から有効にしたチャネルの「チャネル基本設定」タブには、自分のユーザーIDの欄が出ていません)。
n8nとの違いは3つです。
- 受信はLINEアプリの「Watch Events」を置くだけで始められる
- 署名を自分で確かめたい、ヘッダーを見たいときは、「Webhooks」アプリの「Custom webhook」で受け、詳細設定の「Get request headers」と「JSON pass-through」をオンにする
- 返信とプッシュは、HTTPアプリの「Make a request」で、プッシュの例と同じURL・ヘッダー・JSONを送れば組める
Makeは、応答のモジュールが無ければ受け付けた時点で200「Accepted」を返します。「Webhook response」を置くと最大180秒待つので、LINE向けには置かないほうが素直です。
Zapierの場合
2026年10月時点で、ZapierのアプリディレクトリにLINEのMessaging API用のアプリのページは見つかりませんでした。LINEとつなぐには、「Webhooks by Zapier」を使います。
- Zapのトリガーに「Webhooks by Zapier」の「Catch Raw Hook」を選ぶ
- Zapierが出すURLを、LINE Developersコンソールの「Webhook URL」に入れる
- アクションに、Googleスプレッドシート・Slackのステップを足す
- 返信は、「Webhooks by Zapier」の「Custom Request」で
https://api.line.me/v2/bot/message/replyにPOSTする
「Catch Raw Hook」は解析前の本文(2MBまで)とヘッダーを渡すので、署名を確かめるならこちらを選びます。
Zapierは既定で200を返し、中身は変えられません。Zapをオフにしても数時間は200を返すことがあるので、止めるときはLINE側の「Webhookの利用」をオフにします。Webhooks by Zapierも複数ステップのZapも有料プランからなので、Proプラン以上が前提です。
どれを選ぶか
- 問い合わせの本文を自分の管理するサーバーの外に出したくない、または件数が多い:n8nを自分のサーバーで動かす
- サーバーを持ちたくない、LINEの部品を使って早く形にしたい:MakeかZapier、またはn8nのクラウド版
- すでに社内でZapierを使っていて、ほかの業務のZapと並べて管理したい:Zapier
応用
顧客管理のkintoneに入れる
スプレッドシートの代わりに、kintoneの顧客管理アプリに入れることもできます。userIdで顧客のレコードを探し、無ければ作る形になります。
受け口から別の道具へ転送する
Webhook URLは1つなので、n8nで受けたものをほかのシステムにも渡したいときは、署名を確かめたあとでHTTP Requestで転送します。
拡張ツールのL Harness(GitHub Shudesu/line-harness-oss・MITライセンス・ソフトウェアの利用料は0円)を使っている場合は、L Harnessが受け口になります。READMEには、外部へのWebhook IN/OUTでSlackなどと連携できると書かれています。
できないことと、その代わり
| できないこと | 代わりの手 |
|---|---|
| LINE Notifyで通知を送る(2025年3月31日に終了) | Slackやメールに送る。LINEで受けたいならMessaging APIのプッシュでスタッフ宛てに送る |
| 1つのチャネルに複数のWebhook URLを登録する | 受け口を1つに決め、そこから転送する |
| 時間がたってから応答トークンで返す | 1分を過ぎたらプッシュで送る。通数にカウントされる |
| Webhookも応答メッセージもあいさつメッセージも使わない設定 | 開発ガイドラインで許可されていない。どれか1つは動かしておく |
受付時間外に決まった文面を返すだけなら、そもそも道具は要りません。管理画面の「設定」>「応答設定」で「応答時間」を設定し、時間外の応答方法を選べば、標準機能で自動で返せます。マニュアルでは、時間外の選択肢に「応答メッセージ+AIチャットボット(β)」が載っています。この場合、n8n側の自動返信は外し、記録とSlackの通知だけを残します。両方で返すと二重になります。
よく詰まるところ
| 症状 | 原因 | 直し方 |
|---|---|---|
| 「検証」を押すとエラーになる | テスト用のURLを入れたのに、n8nを受信待ちにしていない | 受信待ちにしてから押す。本番は公開してから本番用のURLを入れる |
| 公開したのに何も動かない | LINEに登録したのがテスト用のURL(/webhook-test/)のまま | 本番用のURL(/webhook/)に差し替える |
| 署名が毎回一致しない | 本文を解析したあとのJSONで計算している | WebhookノードのRaw Bodyをオンにし、受け取ったままの本文で計算する |
| 急に署名が一致しなくなった | チャネルシークレットを再発行した | 認証情報のHmac Secretを新しい値に差し替える |
| 返信が応答トークンの無効でエラーになる | 1分を過ぎた、または同じトークンを2回使った | 返信を記録やSlackより前に置く。返信のノードを1つにする |
| 時間外の判定が9時間ずれる | ワークフローのタイムゾーンが既定のアメリカ・ニューヨークのまま | ワークフローの設定で「Asia/Tokyo」にする |
| 自動返信とスタッフの返信が両方届く | 管理画面の自動応答とn8nの返信が同じ時間帯に動いている | 時間帯で役割を分ける。n8nで返すなら管理画面の時間外の自動応答は使わない |
| スプレッドシートに同じ問い合わせが2行入る | 同じイベントが重複して届いた | 「Append or Update Row」でwebhookEventIdを照合する |
| 友だち追加のたびにエラーが出る | followイベントには message が無い | Filterでtypeが message のものだけ残す |
| n8nのクラウド版で実行数が早く減る | 友だち追加やスタンプのWebhookでも動く | 件数が多ければ自分のサーバーへ移す |
| Zapierで止めたのにWebhookが成功扱いになる | Zapをオフにしても数時間は200を返すことがある | LINE側で「Webhookの利用」をオフにする |
次にやること
次は記録の作り込みと、返信の中身を増やす方向に進めます。