Chatbox playground

Test iframe, host config, and postMessage flows in one page.

Direct mode is the exact iframe URL you pasted. Bridge mode uses `/embed?view=panel` and sends `CHATBOX_CONFIG` from the parent window, which is the only message the widget currently listens for.

Control panel

Configure the host page and push a new payload.

Target origin
http://localhost:3004
This is where postMessage is sent.
Mode hint
Bridge mode expects CHATBOX_CONFIG from the host.
Only CHATBOX_CONFIG is consumed by the current widget runtime.
Iframe preview
http://localhost:3004/embed?view=panel
bridge
Message log
Incoming iframe messages are filtered by `event.source === iframe.contentWindow`.
system·BOOT·09:03:13
Open bridge mode to send CHATBOX_CONFIG into /embed?view=panel.
{
  "mode": "bridge"
}
1. The exact iframe from your prompt
<iframe
  id="chatbox-widget-direct-iframe"
  src="http://localhost:3004/embed?view=panel&instanceId=9b6c52e4-9c09-4c12-876b-4cf1961df575&apiUrl=&socketUrl=https%3A%2F%2Fapi.ai.seatek.vn&hostOrigin=http%3A%2F%2Flocalhost%3A3004&locale=vi&position=bottom-right&color=%232563eb&chatboxName=Facebook+Smart+Assistant&avatar=%F0%9F%93%98&quickActions=%5B%22%F0%9F%93%9D+T%E1%BA%A1o+b%C3%A0i+vi%E1%BA%BFt+m%E1%BB%9Bi%22%2C%22%F0%9F%92%A1+G%E1%BB%A3i+%C3%BD+%C3%BD+t%C6%B0%E1%BB%9Fng+n%E1%BB%99i+dung%22%2C%22%F0%9F%8E%AF+Vi%E1%BA%BFt+n%E1%BB%99i+dung+qu%E1%BA%A3ng+c%C3%A1o%22%2C%22%F0%9F%93%88+T%C4%83ng+t%C6%B0%C6%A1ng+t%C3%A1c+b%C3%A0i+vi%E1%BA%BFt%22%5D&welcomeMessage=Xin+ch%C3%A0o%21+T%C3%B4i+l%C3%A0+Facebook+Smart+Assistant&widgetKey=wk_011d7890047a076215f69b3f7b96ee49"
  style="position:fixed;right:16px;bottom:16px;z-index:2147483647;width:56px;height:56px;border:none;border-radius:9999px;box-shadow:none;background:transparent;overflow:hidden;"
  frameborder="0"
  allow="microphone">
</iframe>
<script>
  window.addEventListener("message", function (event) {
    var iframe = document.getElementById("chatbox-widget-direct-iframe");
    if (!iframe) return;
    if (event.data && event.data.type === "CHATBOX_CLOSE") {
      iframe.style.width = "56px";
      iframe.style.height = "56px";
      iframe.style.maxHeight = "56px";
      iframe.style.boxShadow = "none";
      iframe.style.borderRadius = "9999px";
      iframe.style.overflow = "hidden";
      iframe.style.pointerEvents = "auto";
    }
    if (event.data && event.data.type === "CHATBOX_OPEN") {
      iframe.style.width = "min(432px,calc(100vw - 32px))";
      iframe.style.height = "min(720px,calc(100vh - 32px))";
      iframe.style.maxHeight = "calc(100vh - 32px)";
      iframe.style.boxShadow = "0 20px 50px rgba(0,0,0,0.15)";
      iframe.style.borderRadius = "16px";
      iframe.style.overflow = "hidden";
      iframe.style.pointerEvents = "auto";
    }
  });
</script>
2. Bridge setup with postMessage
window.frames[0]?.postMessage(
  {
    type: "CHATBOX_CONFIG",
    payload: {
      instanceId: "9b6c52e4-9c09-4c12-876b-4cf1961df575",
      widgetKey: "wk_011d7890047a076215f69b3f7b96ee49",
      apiUrl: "",
      locale: "vi",
      position: "bottom-right",
      color: "#2563eb",
      chatboxName: "Facebook Smart Assistant",
      avatar: "📘",
      quickActions: [
        "📝 Tạo bài viết mới",
        "💡 Gợi ý ý tưởng nội dung"
      ],
      welcomeMessage: "Xin chào! Tôi là Facebook Smart Assistant"
    }
  },
  "http://localhost:3004"
);
3. Listening for iframe events
window.addEventListener("message", (event) => {
  if (event.origin !== "http://localhost:3004") return;

  if (event.data?.type === "CHATBOX_READY") {
    console.log("Widget is ready");
  }

  if (event.data?.type === "CHATBOX_CLOSE") {
    console.log("Widget requested close");
  }
});
4. Listening for tool requests
window.addEventListener("message", (event) => {
  if (event.origin !== "http://localhost:3004") return;

  if (event.data?.type === "CHATBOX_TOOL_REQUEST") {
    console.log("[Host] CHATBOX_TOOL_REQUEST", event.data);

    window.frames[0]?.postMessage(
      {
        type: "CHATBOX_TOOL_RESPONSE",
        requestId: event.data.requestId,
        ok: true,
        data: {
          orderId: event.data.input?.orderId || "ORD-001",
          status: "paid",
          total: 1250000,
        },
      },
      "http://localhost:3004"
    );
  }
});