[HELP] Need Help Parsing Parameters from Website into Dify Chatflow (Embedded via iFrame)

Hello everyone,

I need some assistance with parsing parameters from my website into a Dify Chatflow.

Here’s my current setup:

  • I’m using Dify Cloud.

  • The chatflow is published and embedded in my website using the published URL inside an iframe.

My goal is to pass parameters from my website (for example, user information or session data) into the Dify chatflow so that the chatbot can process or display them.

I have already tried using scripts and followed the documentation related to parameter passing, but unfortunately, it doesn’t seem to work.

Could anyone please guide me on how to properly send or parse parameters into Dify chatflow when it is embedded via iframe?
Any examples or working implementations would be greatly appreciated.

Thank you in advance for your help!

Hello @cuifangxu,

Thanks for assistance, I would like to confirm a few implementation details related to Same-Origin Policy and message handling for Dify + Chatflow:

1. Deployment — Same-Origin Policy
To address Same-Origin Policy restrictions, is it recommended to install Dify on the same server / environment as the website (for example, a local installation on the same host)? If not, what is the recommended approach (CORS, reverse proxy, or hosting Dify and the website under the same origin)?

2. Receiving messages in Dify / Chatflow
For receiving data posted from a parent window (via postMessage), do I need to add a window.addEventListener('message', ...) handler inside Dify, or will Dify automatically populate the required variables? If I must add the event listener, could someone provide a step-by-step example for integrating it with Dify/Chatflow? I am specifically using Chatflow and want to know the best way to accept and use incoming params (e.g., user_id, user_name, session_id).

FYI — example usually I use to get the postMessage value in my apps:

window.addEventListener('message', function(event) {
    // Only accept messages from the expected origin
    if (event.origin !== 'https://my-parent-domain.com') {
        return;
    }

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

        console.log('Received user data from parent:');
        console.log('User ID:', receivedData.user_id);
        console.log('User Name:', receivedData.user_name);
        console.log('Session ID:', receivedData.session_id);
    } else {
        console.log('Received a message, but it was not the DIFY_PARAMS type:', event.data);
    }
}, false);

console.log('Iframe is listening for postMessages...');

Request: please advise if this approach is appropriate for Dify Chatflow and, if needed, provide a short step-by-step guide showing how to:

  • Add the message listener inside Dify/Chatflow,

  • Validate and map incoming fields into Dify variables or the Chatflow context, and

  • Any recommended security checks or best practices (origin validation, message shape validation, rejecting unexpected messages, using event.source when replying, etc.).

Thank you in advance for your help.

iframe

<!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>
        // Define variables to be encoded
        const inputs = {
            "user_name": "Tom"
        };

        // Encoding function
        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));
        }

        // Generate encoded 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()}`;

            // Update 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: {
        // You can define the inputs from the Start node here
        // key is the variable name
          user_name: "Tom"
        }
      }
    </script>
    <script
      src="http://localhost/embed.min.js"
      id="nF6Zbpsxk2Hc5vxE"
      defer>
    </script>
</body>
</html>
「いいね!」 2

Thank you very much for your assistance. I have tested the solution, and it works well on my end. However, the URL needs to be set as http://localhost/chatbot/nF6Zbpsxk2Hc5vxE. When I use http://localhost/chat/nF6Zbpsxk2Hc5vxE, the parameter values are not properly decoded. I am using the /chat path to display the chat history sidebar, as the /chatbot path does not show the side panel.

This situation is simpler - just append the parameters directly to the URL without compression and encoding.

<!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>