「動いた」と思うたびに次の問題が出てきて、GASのログをにらみながら一日つぶれた。LINE公式アカウントとDifyをGASでつないだときの話です。
仕組みの考え方はシンプルです。ただ、細かい詰まり所がいくつかあって、そこを抑えていないと半分くらいのところで止まります。
最小構成の考え方
仕組みは3つの部品で成り立ちます。
LINE公式アカウント(ユーザーがメッセージを送る)
↓ Webhook(通知を受け取る仕組み)
GAS(Google Apps Script)(中継役)
↓ APIリクエスト
Dify(AI側)
GASが真ん中に入って、LINEからのメッセージをDifyに渡し、Difyの返答をLINEに戻す。これだけです。
会話の文脈を引き継がせるには、ユーザーごとに「この人は今どの会話の続き?」をGASが管理する必要があります。そのためにスプレッドシートを使いました。LINEのユーザーIDと、Difyが発行する会話IDをセットで保存しておいて、次のメッセージが来たときに「この人の続き」として送る。
AIへの頼み方
自分でコードを書かず、AIに「こういうものを作って」と頼みました。要件を日本語でそのまま渡した感じです。
LINEとDifyを連携するためにGASを使いたい。
- LINEのユーザーIDと、Difyの会話IDをスプレッドシートに保存して
- 初回のメッセージでそれぞれのIDを保存し、2回目以降はスプレッドシートからユーザーIDを特定して会話IDをDifyへのパラメータとして渡して
- スプレッドシートのA列にLINEユーザーID、B列に会話ID
これで動くコードの下地は出てきます。ただ、その後が長かった。
実際に詰まったところ
接続検証で302が返る
LINEは、Webhook URLを登録するときに「本当にそのURLで受け取れるか」を確認します。このとき、GASのURLの末尾が /dev になっていると302(リダイレクト)が返ってしまって、検証が通りません。
デプロイ時のURLは /exec で終わるものを使う必要があります。これはGASの仕様なのですが、開発中は /dev で確認することが多いので、うっかり混乱します。
もう一点、GASのウェブアプリ設定で「アクセスできるユーザー」を「全員(匿名ユーザーを含む)」にしていないとLINEからのリクエストが届きません。この2点をセットで確認しないと、そもそも始まらない。
初回の会話IDが保存されない
最初に作ったコードでは、Difyに問い合わせをしてから返ってきた「会話ID」をスプレッドシートに書くタイミングがずれていました。Difyにメッセージを送るリクエストのレスポンスに会話IDが含まれているので、それを受け取ってから保存しないといけない。でも最初の実装は別のエンドポイントを呼ぼうとしていて、実はそこに会話IDは入っていなかった。
同じユーザーIDが二重に登録されていたのも、重複チェックが入っていなかったからです。保存前に「このIDはすでにあるか」を確認するコードを1行加えるだけで直りました。
LINEへの応答が返ってこない
「messages[0].text が空」というエラーが出て、LINEへの返信が飛んでいませんでした。原因はDifyのレスポンスから返答テキストを取り出す部分の指定ミス。Difyが返すデータの中に answer という項目があって、そこに返答が入っているのですが、別の場所を参照していたので空になっていた。
この手のエラーは、GASの実行ログを見れば「どこで詰まったか」が分かります。最初からログを仕込んでおくと、後で原因を追いやすい。
user パラメータのフォーマット誤り
Difyに送るリクエストに user という項目を含める必要があります。「誰のリクエストか」をDify側に伝えるためです。ここで「文字列として渡せばいいだろう」と思っていたのですが、Difyの仕様では別の形式が求められていました。
エラーメッセージは「Arg user must be provided」。意味は分かるのですが、文字列で渡しているつもりなのになぜ?となる。実際にはオブジェクト形式で渡す必要があって、これはAPIドキュメントを見ないと気づきにくい。
必要なものまとめ
同じことをやるのに要るのはこれだけです。
- LINE公式アカウント(Messaging APIが使えるプランが必要)
- DifyのAPIキー(Difyのアカウントで発行できます)
- GAS(Googleアカウントがあれば無料で使えます)
- スプレッドシート(Googleドライブに1枚あればOK)
費用はDify側のAPI利用料だけです。GASもスプレッドシートも無料。
動いてから出てきた追加要件
一通り動くと、「ニックネームも保存したい」「DifyにユーザーIDも渡したい」という話が出てきます。これも追加で頼めば対応できました。
ただ、user パラメータの件(前述)はここで発生しました。「ユーザーIDを渡して」と追加したところ、渡し方のフォーマットが違っていてエラーになった。機能を足すたびに小さい詰まりが出る、というのが正直なところです。
LINE側とDify側でそれぞれ「こういう形式で送れ」という決まりがあり、GASはその通訳をやっています。通訳が少し間違えると止まる。エラーが出たら、GASのログで「どこまで届いて、どこで詰まったか」を順番に確認していくのが一番早かったです。
LINE公式にAIをつなぎたいだけなら、これが今のところ私が使う最小の形です。ここから始めると話が早い。
