皆さんこんにちは、横浜で清掃業をしているヤスです
今回は、LINEでお客さんが画像を送ってきたら、AI(Dify)がその内容を読んで自動で返信してくれる——そんなLINE Botを作った話です。
……と、一行で書くと簡単そうに聞こえますよね。でも正直に言います。私はこれで丸一日ハマりました。しかも、ハマった原因のほとんどが「AIの作り方」ではなく、ツール同士をつなぐ配線の部分でした。毎回MAKEにどはまりしてますが、今回もかなりの時間がかかってしまいました。
同じように「Difyでアプリは作れたけど、LINEやMakeとの連携でつまずいている」という40代・50代の方に、私がどこで止まって、どうやって抜け出したのかを、恥ずかしい部分もそのまま残してお伝えします。専門用語には一言ずつ解説を添えるので、身構えなくて大丈夫です。
この記事で作るもの(完成形)
まず、できあがったものから見せます。



裏側では、こんな流れが動いています。
- LINEにメッセージが届く(Webhook=外部からの通知を受け取る入口)が受信
- Router(=道を枝分かれさせる分岐)で「テキストか画像か」を振り分け
- 画像の場合、LINEから画像を取得
- その画像をDifyにアップロード
- Difyに「この画像について返信して」とお願い(API=アプリ同士をつなぐ窓口)
- Difyの回答テキストだけをLINEに返信
使ったツールは3つです。
- Make(旧Integromat)……ノーコードで自動化の流れを組むツール。今回は「配線盤」の役割
- Dify……ノーコードでAIアプリを作るツール。今回は「頭脳」の役割
- LINE公式アカウント……お客さんとの接点
作り方:再現できる最短手順
私は行ったり来たりして丸一日かかりましたが、答えが分かった今なら、手順はこれだけです。試行錯誤の順ではなく、再現できる順に並べ直しました。
ステップ1:LINEのWebhookをMakeにつなぐ
何をするか:Makeで「Webhook」モジュールを置き、発行されたURLをLINE公式アカウントのWebhook設定に貼る。
なぜか:これがないと、LINEに届いたメッセージがMakeに流れてきません。すべての起点です。
ステップ2:Routerで「テキスト」と「画像」を分ける
何をするか:Webhookの次にRouterを置き、2本のルートを作る。それぞれのルートに「フィルター」(=通過条件)を設定する。
- テキストのみ通すルート
- 画像のみ通すルート
なぜか:テキストと画像では、その後の処理がまったく違うからです。テキストはそのままDifyに送れますが、画像は「取得→アップロード」という一手間が必要になります。
フィルターの条件には、届いたメッセージの種類を見る変数を使います。私の環境では波カッコ記法(=変数を手打ちで指定する書き方)で、こう書きました。
{{5.events[].message.type}}
これが image と一致したら画像ルート、text なら テキストルート、という振り分けです。
※先頭の「5」はWebhookモジュールの番号です。ここが後で大事件を起こします(後述)。
ステップ3:画像ルートの処理を組む
画像ルートは、HTTPモジュール(=外部とデータをやり取りする部品)を3つ並べます。
- LINEから画像を取得(GET)
- Difyに画像をアップロード(POST/
/v1/files/upload) - Difyに返信を生成させる(POST/
/v1/chat-messages)
ステップ4:Difyの回答だけをLINEに返す
何をするか:最後にLINE返信モジュールを置き、本文に {{22.data.answer}} を指定する(22は私の環境でのDify呼び出しモジュールの番号)。
なぜか:ここを「Difyの返答まるごと」にすると、JSONという生データがそのままお客さんに届いてしまうからです。私は実際にこれをやらかしました(後述)。
つまずきポイント:ここが本番です
正直、上の手順よりこっちが本編です。私が実際に止まった場所を、生々しく残します。
つまずき①:Webhookを作り直したら、全部のモジュールが壊れた
途中でWebhookを作り直したんです。そうしたら、モジュール番号が「1」から「5」に変わってしまった。
何が起きたか。シナリオ中のすべての変数参照が、まだ古い「モジュール1」を指したままだったんです。フィルターも、HTTPモジュールも、LINE返信も、あちこちで「存在しないモジュールを参照しています」というエラーが連鎖しました。
一つずつ「1」を「5」に直していく作業は地味にこたえました。
教訓:トリガー(Webhookなど最初の部品)を作り直すと、番号が変わって連鎖崩壊する。作り直しは最終手段、まず既存を直せないか考える。
つまずき②:英語で入力したタグが、保存したら日本語に戻る
これが一番混乱しました。
フィルターの条件を英語表記の正しいタグに直す→保存する→開くと日本語表記に戻っている。「あれ、直したのに」ともう一度直す→保存→また戻る。これを何度も繰り返しました。
正体はこうでした。波カッコで手打ちした変数を、Makeが保存時に「これはこのフィールドのことだな」と解釈して、表示ラベルを自動的にUI言語(日本語)へ置き換えていたんです。つまり、表示が日本語に変わっても、参照先そのものは同じ。私の操作ミスではなく、Makeの正常な動きでした。
ここで大事な発想の転換がありました。表示が日本語に戻ること自体は追いかけても意味がない。見るべきは「表示が何であれ、実際に画像と一致判定されているか」だけ、と。
教訓:ノーコードツールの「表示ラベル」と「実際の参照先」は別物。見た目が変わっても中身は同じことがある。表示ではなく挙動で判断する。
つまずき③:Webhookは受信しているのに、その先に一切進まない
シナリオ図を見ると、Webhookには受信済みのバッジ(✓1)が付いている。なのに、Routerから先のフィルターは「通過0件(⊘0)」のまま。
「受信はしているのに、なぜ先に進まない?」——ここでしばらく足踏みしました。
[スクショ:Webhookは✓1、フィルターが⊘0のままのシナリオ図]
原因の切り分けとして、画面をリロードして数字が最新か確認したり、フィルターの参照が本当に正しい実体を指しているかを疑ったりしました。最終的には、フィルターの参照と条件を根気よく合わせていくことで、通過するようになりました。
教訓:「入口は受信、その先で停止」なら、疑うのは入口ではなく分岐(Router/フィルター)の条件。バッジの数字は切り分けの強力な味方。
つまずき④:返信が来た!と思ったら、JSONが丸ごと届いた
画像を送ったら、ついにDifyが反応して返信が届きました。……が、届いたのは回答文ではなく、answer やら何やらが詰まったJSONの生データまるごとでした。
原因は単純で、LINE返信モジュールの本文が「Difyの返答まるごと」を指していたから。ここを {{22.data.answer}}(=返答の中の「回答」部分だけ)に直したら、無事に回答テキストだけが届くようになりました。
教訓:APIの返事は、たいてい「箱に入った状態」で返ってくる。箱ごと渡さず、中の必要な一項目だけを取り出す。
おまけのつまずき:無料プランでは「即時返信」ができない
最後に、これは仕様の話。
「動いた!」と喜んだあと、Run once(=手動で1回だけ実行するテストボタン)を押さずに画像を送っても返信が来ないことに気づきました。スケジュール設定を見ると「15分ごと」。「すぐに(即時実行)」に変えて保存しても、リロードすると15分ごとに戻り、シナリオのスイッチまでオフになる。
調べたところ、Makeの無料プランは最短実行間隔が15分で、「すぐに」は事実上使えない仕様でした。リアルタイムに返信させたいなら、上位の有料プランが必要になります。
※プラン名や条件は変わる可能性があるので、契約前に必ずMakeの公式料金ページで最新情報を確認してください([要確認:現在のプラン名・価格])。
教訓:ノーコードは「設定できる」と「そのプランで有効になる」が別。動かないときは、自分のプランで許可されているかを疑う。
まとめ:この記事の手順を一言で
やったことを振り返ると、こうです。
- LINEのWebhookをMakeにつなぐ
- Routerでテキストと画像を分ける
- 画像は「取得→アップロード→Dify呼び出し」の3段
- 返信は
answerだけを取り出す
そして、つまずいたのは決まって「AIそのもの」ではなく、ツールとツールのつなぎ目でした。
もしあなたが今、似たような連携でつまずいているなら、最初の一歩としておすすめしたいのはこれです。
「シナリオ図のバッジ(✓や⊘の数字)を、まず声に出して読む」
どこまで進んで、どこで止まっているか。それが分かるだけで、闇雲に全部を疑わずに済みます。私はこれを知らずに、入口から出口まで全部を疑って一日溶かしました。
次回予告
今回は「画像を送ると返信が来る」ところまで作りました。毎回MAKEにはまってますね。いつになったら慣れることやら。次回は、今作成しているUdemyの講座作成について書こうと思います。
関連記事:【完全自動化】MakeとDifyを連携!SEO順位チェック→AI改善提案ループの作り方
それでは、また次回。横浜のヤスでした。

コメント