MENU

n8n × Claude API × Supabaseで訪問介護向けLINE自動応答を作った話訪問介護事業所のLINE問い合わせを、AIが自動で対応する仕組みを作ってみた。

目次

この記事について

訪問介護事業所向けに、LINEの問い合わせをAIが自動対応するデモシステムを実装しました。構成はn8n(Dockerローカル)× Claude API × Supabase × LINE Messaging APIです。

実装中に詰まったポイントを中心に、再現できるレベルで記録します。

技術スタック

  • n8n(Docker・ローカル環境)
  • Claude API(claude-haiku-4-5-20251001)
  • Supabase(PostgreSQL)
  • LINE Messaging API(push API)
  • ngrok(ローカル外部公開)
  • Windows 11 / WSL2

システム構成

LINEアプリ
  → LINE Messaging API(Webhook)
  → ngrok(HTTPS→localhost:5678)
  → n8n Webhookノード
  → Codeノード(ペイロード整形)
  → HTTP Requestノード(Claude API)
  → Codeノード(FormatClaude・LINE push送信)
  → HTTP Requestノード(Supabase INSERT)

環境構築

Docker + n8nの起動

# docker-compose.yml
services:
  n8n:
    image: n8nio/n8n
    restart: always
    ports:
      - "5678:5678"
    environment:
      - N8N_BASIC_AUTH_ACTIVE=true
      - N8N_BASIC_AUTH_USER=admin
      - N8N_BASIC_AUTH_PASSWORD=password
      - GENERIC_TIMEZONE=Asia/Tokyo
      - TZ=Asia/Tokyo
      - NODE_FUNCTION_ALLOW_BUILTIN=https,http
      - NODE_FUNCTION_ALLOW_EXTERNAL=*
    volumes:
      - n8n_data:/home/node/.n8n

volumes:
  n8n_data:

NODE_FUNCTION_ALLOW_BUILTINNODE_FUNCTION_ALLOW_EXTERNAL は必須です。これがないとCodeノードでaxiosなどのモジュールが使えません。最初に設定しておかないと後でコンテナを再起動することになります。

docker compose up -d

ngrokの設定

LINE WebhookにはHTTPS URLが必要なため、ngrokで外部公開します。

ngrok config add-authtoken YOUR_TOKEN
ngrok http 5678

表示された https://xxxx.ngrok-free.app をLINE DevelopersのWebhook URLに設定します。

Supabaseの設定手順

Supabaseは「Firebaseの代替」として注目されているオープンソースのデータベースサービスです。PostgreSQLをベースにしており、管理画面が直感的で使いやすく、無料プランでも十分な機能が使えます。

プロジェクトの作成

https://supabase.com にアクセスして、GitHubアカウントでサインアップします。ログイン後に「New project」をクリックして以下を入力します。

項目入力内容
Organization任意の名前(初回は自動作成)
Project namehomecare-demo(任意)
Database Password強力なパスワード(必ずメモする)
RegionNortheast Asia (Tokyo)

「Create new project」をクリックするとプロジェクトの作成が始まります。1〜2分ほどで完了します。

テーブルの作成

プロジェクトが作成されたら、左メニューの「SQL Editor」を開いて以下のSQLを実行します。これが問い合わせログを保存するテーブルの定義です。

sql

create table line_inquiries (
  id uuid default gen_random_uuid() primary key,
  created_at timestamp with time zone default now(),
  user_id text not null,
  display_name text,
  message_text text not null,
  claude_reply text,
  status text default 'open'
);

各カラムの意味は以下の通りです。user_id はLINEのユーザーID、message_text はご家族が送ったメッセージ、claude_reply はAIが生成した返答、status は対応状況(初期値は「open=未対応」)です。

右上の「Run」ボタンをクリックして「Success. No rows returned」と表示されればテーブルの作成完了です。

APIキーの取得

n8nからSupabaseに接続するには2つの情報が必要です。左メニューの「Settings」→「API」を開いて以下をメモします。

Project URL(例:https://xxxxxxxxxxxx.supabase.co)はデータベースへのアクセス先のURLです。

service_role keyは管理者権限を持つAPIキーです。「Reveal」ボタンで表示してコピーします。このキーはデータベースの全操作が可能な強力なキーですので、外部に漏れないよう厳重に管理してください。GitHubなどの公開リポジトリには絶対に含めないようにします。

データの確認方法

システムが動き始めたら、左メニューの「Table Editor」→「line_inquiries」を開くと、問い合わせが届くたびにレコードが追加されていくのをリアルタイムで確認できます。

iduser_idmessage_text claude_reply status
uuid-001U9f4fc3…サービス内容を教えてこんにちは…open
uuid-002U9f4fc3…料金はいくらですか料金について…open

この画面が事業所側の「問い合わせ管理台帳」になります。将来的にはここのデータをWebアプリの管理画面に表示して、対応済み・未対応のステータス管理や担当者への割り振りを行う仕組みに拡張できます。

Supabaseの料金について

無料プランでは500MBのデータベース容量・50,000行のデータが使えます。問い合わせログの保存であれば、数年分のデータを蓄積しても無料プランで十分まかなえます。


LINE Messaging APIの設定

LINEを公式アカウントとして使うには、LINE Developersという開発者向けの管理画面で設定を行います。無料で始められますので、順を追って説明します。

アカウントの作成とチャンネルの開設

まず https://developers.line.biz にアクセスして、普段お使いのLINEアカウントでログインします。ログイン後に「コンソール」画面が開きますので、「プロバイダーを作成」から任意の名前(例:「訪問介護デモ」)でプロバイダーを作成します。

次に「チャンネルを作成」をクリックして、種類として「Messaging API」を選択します。チャンネル名・説明・業種などを入力して作成を完了させます。

重要な設定項目

チャンネルが作成されたら「Messaging API設定」タブを開いて、以下の3点を設定します。

まずチャンネルアクセストークンの発行です。ページ下部の「チャンネルアクセストークン(長期)」の「発行」ボタンをクリックします。表示されたトークンは後でn8nの設定に使いますので、必ずメモしておいてください。このトークンはAPIを呼び出す際の「鍵」になります。

次にWebhook URLの設定です。「Webhook URL」の欄にn8nのエンドポイントURLを入力します。

https://あなたのn8nのURL/webhook/line

入力後に「検証」ボタンをクリックして「成功」と表示されれば、LINEからn8nへの通信が正常に届いていることが確認できます。

最後に応答メッセージをオフにします。LINE公式アカウントのデフォルト設定では、メッセージを受け取ると自動で定型文を返してしまいます。AIが返答を生成する今回の仕組みでは二重返信になってしまうため、「応答メッセージ」をオフ・「Webhookの利用」をオンに切り替えます。

友だち追加用QRコード

設定完了後、「Messaging API設定」タブの上部にQRコードが表示されます。このQRコードをスマートフォンのLINEアプリで読み取ることで、作成した公式アカウントを友だち追加できます。動作確認の際はこの手順でテストします。

LINEの料金について

Messaging APIのフリープランでは月1,000通まで無料でメッセージを送受信できます。30人規模の事業所であれば月200件前後の問い合わせを想定していますので、フリープランで十分まかなえます。

チャンネルアクセストークン(長期)を発行してメモします。Webhook URLに https://xxxx.ngrok-free.app/webhook/line を設定して「検証」で成功を確認します。応答メッセージをオフ・Webhookの利用をオンに切り替えます。

応答メッセージのオフを忘れると、LINEの定型文とAIの返答が二重に送信されます。


n8nワークフローの実装

ワークフローは以下の5つのノードで構成されています。

  • Webhookノード:LINEからの通知を受け取る
  • Codeノード:受け取ったデータを整形する
  • HTTP Requestノード:Claude APIを呼び出す
  • Codeノード(FormatClaude):返答を整形してLINEに送信する
  • HTTP Requestノード:Supabaseにデータを保存する

ノード①:Webhook

項目設定値
HTTP MethodPOST
Pathline
AuthenticationNone
RespondImmediately

ノード②:Code(ペイロード整形)

const body = $input.first().json.body;
const event = body.events[0];

if (!event) {
  return [{ json: { skip: true } }];
}

return [{
  json: {
    userId: event.source.userId,
    messageText: event.message.text,
    replyToken: event.replyToken,
    timestamp: event.timestamp
  }
}];

ノード③:HTTP Request(Claude API)

項目設定値
MethodPOST
URLhttps://api.anthropic.com/v1/messages
Body Content TypeRaw
Content Typeapplication/json

Headers:

NameValue
x-api-keysk-ant-xxxx
anthropic-version2023-06-01

Body(Expressionモードで入力):

{
  "model": "claude-haiku-4-5-20251001",
  "max_tokens": 1024,
  "system": "あなたは訪問介護事業所のAIアシスタントです。利用者や家族からの問い合わせに対して、丁寧で簡潔な日本語で回答してください。不明な点は「担当者に確認してご連絡します」と答えてください。",
  "messages": [
    {
      "role": "user",
      "content": "={{ $input.first().json.messageText }}"
    }
  ]
}

モデルの選定

今回は claude-haiku-4-5-20251001 を使いました。問い合わせ対応という用途ではHaikuで十分な品質が出ます。Sonnetと比べてレスポンスが速く、コストも約10分の1です。

月200件の問い合わせを想定した場合のClaude APIコストは月2,000〜5,000円程度です。

Claudeへのプロンプト設計が要

AIの返答品質はプロンプトの設計で大きく変わります。今回は以下のようなシステムプロンプトを設定しました。

あなたは訪問介護事業所のAIアシスタントです。
利用者や家族からの問い合わせに対して、丁寧で簡潔な日本語で回答してください。
サービス内容・料金・緊急時の対応に関する質問に答えてください。
不明な点は「担当者に確認してご連絡します」と答えてください。

「わからないことは担当者に繋ぐ」という指示を入れておくことで、AIが不確かな情報を返してしまうリスクを減らせます。

ノード④:Code(FormatClaude)

ここがこのワークフローの肝です。Claudeの返答整形とLINE push送信を1つのノードで完結させています。

const claudeReply = $input.first().json.content[0].text;
const webhookData = $('Webhook').first().json.body.events[0];

// 改行・特殊文字・Markdown記法を除去
const cleanReply = claudeReply
  .replace(/\n/g, ' ')
  .replace(/\r/g, '')
  .replace(/📋/g, '')
  .replace(/\*\*/g, '')
  .replace(/"/g, "'");

const userId = webhookData.source.userId;
const messageText = webhookData.message.text;

// LINE push APIをaxiosで直接呼ぶ
const axios = require('axios');

const lineResponse = await axios.post(
  'https://api.line.me/v2/bot/message/push',
  {
    to: userId,
    messages: [{ type: 'text', text: cleanReply }]
  },
  {
    headers: {
      'Content-Type': 'application/json',
      'Authorization': 'Bearer YOUR_CHANNEL_ACCESS_TOKEN'
    }
  }
);

return [{
  json: {
    userId: userId,
    messageText: messageText,
    claudeReply: cleanReply,
    lineStatus: lineResponse.status
  }
}];

ノード⑤:HTTP Request(Supabase INSERT)

項目設定値
MethodPOST
URLhttps://xxxx.supabase.co/rest/v1/line_inquiries
Body Content TypeJSON

Headers:

NameValue
apikeyservice_role_key
AuthorizationBearer service_role_key
Content-Typeapplication/json

Body:

{
  "user_id": "={{ $json.userId }}",
  "message_text": "={{ $json.messageText }}",
  "claude_reply": "={{ $json.claudeReply }}"
}

ハマったポイントと解決策

reply APIではなくpush APIを使う理由

LINE Messaging APIのreply APIはWebhook受信から30秒以内に呼ばないと期限切れになります。Claude APIの処理に数秒かかるため、n8nのノード間処理も含めると30秒を超えるケースがありました。

push APIは userId さえあれば時間制限なしに送信できるため、今回はpush APIを使っています。

Bodyが空になる問題

n8nのHTTP RequestノードでBody Content TypeをJSONに設定しても、={{ }} 式がうまく評価されずBodyが空になるケースがありました。

解決策は2つありました。1つ目はBody Content TypeをRawにしてExpressionモードで式を書く方法、2つ目はCodeノード内でaxiosを直接呼ぶ方法です。今回はpush APIの送信もCodeノードに組み込むことでこの問題を回避しました。

Claudeの返答にMarkdownが含まれる問題

Claudeはデフォルトで **太字** や絵文字を含む返答を生成することがあります。これをそのままLINE push APIに渡すとJSONが壊れる場合がありました。

replace() チェーンで送信前に除去しています。プロンプトに「Markdownや絵文字を使わず、プレーンテキストで回答してください」と明記する方法も有効です。

NODE_FUNCTION_ALLOW_BUILTINの設定忘れ

DockerのデフォルトではCodeノードで require('https')require('axios') が使えません。docker-compose.ymlに環境変数を追加してコンテナを再起動する必要があります。

- NODE_FUNCTION_ALLOW_BUILTIN=https,http
- NODE_FUNCTION_ALLOW_EXTERNAL=*


今後の拡張ポイント

意図分類の追加 Claudeに「緊急・相談・予約・その他」を判定させてSupabaseの intent カラムに保存すると、管理画面での絞り込みが便利になります。

前回の問い合わせ履歴の注入 「前回と同じで」という問い合わせに対応するため、Supabaseから直近の問い合わせ履歴を取得してプロンプトに注入できます。

営業時間外の振り分け n8nのIF分岐ノードで時間帯を判定し、営業時間外は「本日の受付は終了しました」という固定メッセージを返す設計にできます。


まとめ

実装自体はそれほど複雑ではありませんが、n8nのバージョン差異・LINE APIのreply/pushの違い・BodyのJSON評価まわりで詰まりポイントが集中しました。この記事がこれから同様の構成を試す方の参考になれば幸いです。


LINE Messaging APIの設定手順

LINEを公式アカウントとして使うには、LINE Developersという開発者向けの管理画面で設定を行います。無料で始められますので、順を追って説明します。

アカウントの作成とチャンネルの開設

まず https://developers.line.biz にアクセスして、普段お使いのLINEアカウントでログインします。ログイン後に「コンソール」画面が開きますので、「プロバイダーを作成」から任意の名前(例:「訪問介護デモ」)でプロバイダーを作成します。

次に「チャンネルを作成」をクリックして、種類として「Messaging API」を選択します。チャンネル名・説明・業種などを入力して作成を完了させます。

重要な設定項目

チャンネルが作成されたら「Messaging API設定」タブを開いて、以下の3点を設定します。

まずチャンネルアクセストークンの発行です。ページ下部の「チャンネルアクセストークン(長期)」の「発行」ボタンをクリックします。表示されたトークンは後でn8nの設定に使いますので、必ずメモしておいてください。このトークンはAPIを呼び出す際の「鍵」になります。

次にWebhook URLの設定です。「Webhook URL」の欄にn8nのエンドポイントURLを入力します。

https://あなたのn8nのURL/webhook/line

入力後に「検証」ボタンをクリックして「成功」と表示されれば、LINEからn8nへの通信が正常に届いていることが確認できます。

最後に応答メッセージをオフにします。LINE公式アカウントのデフォルト設定では、メッセージを受け取ると自動で定型文を返してしまいます。AIが返答を生成する今回の仕組みでは二重返信になってしまうため、「応答メッセージ」をオフ・「Webhookの利用」をオンに切り替えます。

友だち追加用QRコード

設定完了後、「Messaging API設定」タブの上部にQRコードが表示されます。このQRコードをスマートフォンのLINEアプリで読み取ることで、作成した公式アカウントを友だち追加できます。動作確認の際はこの手順でテストします。

LINEの料金について

Messaging APIのフリープランでは月1,000通まで無料でメッセージを送受信できます。30人規模の事業所であれば月200件前後の問い合わせを想定していますので、フリープランで十分まかなえます。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

コメント

コメントする

目次