[ HELP ] ウェブサイトからパラメータを解析して Dify Chatflow に埋め込む(iFrame 経由)

こんにちは、みなさん。

私のウェブサイトからパラメータをDify Chatflowに渡す方法について、ご助力をお願いしたいです。

現在の設定は以下の通りです:

  • Dify Cloud を使用しています。
  • Chatflowは公開済みで、公開URLiframe内に埋め込んで私のウェブサイトに埋め込まれています

目標は、私のウェブサイトからパラメータ(例:ユーザー情報やセッションデータ)をDify Chatflowに渡し、チャットボットがそれらを処理または表示できるようにすることです。

すでにスクリプトを使用してパラメータ渡しのドキュメントに従って試してみましたが、残念ながらうまく動作しませんでした。

iframe経由でDify Chatflowにパラメータを正しく送信または解析する方法について、どなたかご指導いただけますでしょうか?
動作する例や実装例も大歓迎です。

事前にご協力いただき、ありがとうございます!

こんにちは、@cuifangxu さん、

ご支援ありがとうございます。Dify + Chatflow における Same-Origin Policy およびメッセージ処理に関連するいくつかの実装詳細を確認したいと思います。

1. デプロイ — Same-Origin Policy
Same-Origin Policy の制限に対応するため、Dify をウェブサイトと同じサーバー/環境(たとえば、同じホスト上でのローカルインストール)にインストールすることが推奨されますか? そうでない場合、推奨されるアプローチはどれですか(CORS、リバースプロキシ、または Dify とウェブサイトを同じオリジン下でホストするなど)?

2. Dify / Chatflow でのメッセージ受信
親ウィンドウから postMessage 経由で投稿されたデータを受信する場合、Dify 内部に window.addEventListener('message', ...) ハンドラーを追加する必要がありますか? それとも、Dify が自動的に必要な変数を設定してくれますか? イベントリスナーの追加が必要な場合、Dify/Chatflow との統合方法についてステップバイステップの例を教えていただけますか? 私は特に Chatflow を使用しており、受信パラメータ(例:user_id、user_name、session_id)を受け取り、使用する最適な方法を知りたいです。

参考 — 私のアプリで通常使用している postMessage 値の取得例:

window.addEventListener('message', function(event) {
    // 期待されるオリジンからのみメッセージを受け入れる
    if (event.origin !== 'https://my-parent-domain.com') {
        return;
    }

    if (event.data && event.data.type === 'DIFY_PARAMS') {
        const receivedData = event.data.data;

        console.log('親から受信したユーザーデータ:');
        console.log('ユーザーID:', receivedData.user_id);
        console.log('ユーザー名:', receivedData.user_name);
        console.log('セッションID:', receivedData.session_id);
    } else {
        console.log('メッセージを受信しましたが、DIFY_PARAMS 型ではありません:', event.data);
    }
}, false);

console.log('iframe は postMessages をリッスンしています...');

リクエスト: このアプローチが Dify Chatflow に適切かどうかご助言いただき、必要であれば以下の内容を含む簡潔なステップバイステップガイドをご提供ください:

  • Dify/Chatflow 内部に message リスナーを追加する方法、
  • 受信フィールドを Dify 変数または Chatflow コンテキストに検証・マッピングする方法、
  • 推奨されるセキュリティチェックやベストプラクティス(オリジン検証、メッセージ形状検証、予期しないメッセージの拒否、返信時に event.source を使用するなど)。

事前にご協力いただきありがとうございます。

image

image

iframe

<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Iframe Chatbot</title>
</head>
<body>
    <h1>Iframe Chatbot</h1>
    
    <script>
        // 変数をエンコードするための定義
        const inputs = {
            "user_name": "Tom"
        };

        // エンコード関数
        async function compressAndEncode(input) {
            const uint8Array = new TextEncoder().encode(input);
            const compressedStream = new Response(
                new Blob([uint8Array])
                    .stream()
                    .pipeThrough(new CompressionStream("gzip"))
            ).arrayBuffer();
            const compressedUint8Array = new Uint8Array(await compressedStream);
            return btoa(String.fromCharCode(...compressedUint8Array));
        }

        // エンコードされたURLを生成
        (async () => {
            const params = new URLSearchParams();
            for (const [key, value] of Object.entries(inputs)) {
                params.append(key, await compressAndEncode(value));
            }

            const baseUrl = "http://localhost/chatbot/nF6Zbpsxk2Hc5vxE";
            const iframeUrl = `${baseUrl}?${params.toString()}`;

            // iframeのsrcを更新
            document.querySelector("iframe").src = iframeUrl;
        })();
    </script>
    
    <iframe
      src="about:blank"
      style="width: 100%; height: 100%; min-height: 700px"
      frameborder="0"
      allow="microphone">
    </iframe>
</body>
</html>

script

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Script Chatbot</title>
</head>
<body>
    <h1>Script Chatbot</h1>
    
    <script>
      window.difyChatbotConfig = {
        token: 'nF6Zbpsxk2Hc5vxE',
        baseUrl: 'http://localhost',
        inputs: {
        // Startノードから入力を定義できます
        // keyは変数名
          user_name: "Tom"
        }
      }
    </script>
    <script
      src="http://localhost/embed.min.js"
      id="nF6Zbpsxk2Hc5vxE"
      defer>
    </script>
</body>
</html>
「いいね!」 2

ご協力いただきありがとうございます。ソリューションをテストしましたが、私の環境では正常に動作しています。ただし、URLを http://localhost/chatbot/nF6Zbpsxk2Hc5vxE に設定する必要があります。http://localhost/chat/nF6Zbpsxk2Hc5vxE を使用すると、パラメータ値が正しくデコードされません。私はチャット履歴のサイドバーを表示するために /chat パスを使用しています。/chatbot パスではサイドパネルが表示されないためです。

この状況は簡単です。圧縮やエンコードせずに、パラメータを直接URLに追加するだけです。

<!DOCTYPE html>
<head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Iframe Chatbot</title>
</head>
<body>
    <h1>Iframe Chatbot</h1>

    <script>
        const inputs = {
            "user_name": "Tom"
        };

        document.addEventListener('DOMContentLoaded', async () => {
            const params = new URLSearchParams();
            for (const [key, value] of Object.entries(inputs)) {
                params.append(key, value);
            }

            const baseUrl = "http://localhost/chat/WMnzIe1JaO25EwIq";
            const iframeUrl = `${baseUrl}?${params.toString()}`;

            const iframe = document.createElement('iframe');
            iframe.src = iframeUrl;
            iframe.style.width = '100%';
            iframe.style.height = '100%';
            iframe.style.minHeight = '700px';
            iframe.frameBorder = '0';
            iframe.allow = 'microphone';

            document.body.appendChild(iframe);
        });
    </script>
</body>
</html>