<!doctype html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title></title>
    <style>
      /* .coze-chat-sdk{
            width: calc(100% - 20px) !important; */
      /* box-sizing: border-box; */
      /* left:10px;
        } */
    </style>
  </head>

  <body style="height: 100vh; overflow: hidden">
    <div id="cozeChat" style="height: 100%; overflow: hidden">
      <!-- <div class="header">
            <h1></h1>
        </div> -->
    </div>

    <script>
      // 加载JWT生成库并初始化Coze智能体,替换你的配置后,加到网页的js里
      (function () {
        const COZE_CONFIG = {
          botId: "botId",
          appId: "appId",
          publicKey: "xxx",
          privateKey: `xxxx`,
        };

        function loadJwtLibrary() {
          return new Promise((resolve, reject) => {
            // 检查是否加载成功
            if (window.KJUR && window.KJUR.jws && window.KJUR.jws.JWS) {
              resolve();
              return;
            }
            const script = document.createElement("script");
            script.src =
              "https://cdnjs.cloudflare.com/ajax/libs/jsrsasign/8.0.20/jsrsasign-all-min.js";
            script.type = "text/javascript";
            script.crossOrigin = "anonymous"; // 处理跨域问题

            // 加载成功回调
            script.onload = () => {
              // 验证库是否正确加载
              if (window.KJUR && window.KJUR.jws && window.KJUR.jws.JWS) {
                resolve();
              } else {
                reject(new Error("JWT库加载但未正确初始化"));
              }
            };

            // 加载失败回调
            script.onerror = () => {
              reject(new Error(`JWT库加载失败,请检查链接: ${script.src}`));
            };

            document.head.appendChild(script);
          });
        }

        // 生成符合Coze要求的JWT
        function generateCozeJwt(userUid) {
          const header = {
            alg: "RS256",
            typ: "JWT",
            kid: COZE_CONFIG.publicKey,
          };
          const currentTime = Math.floor(Date.now() / 1000);
          const payload = {
            iss: COZE_CONFIG.appId,
            aud: "api.coze.cn",
            jti: Math.random().toString(36).substr(2, 32) + Date.now(),
            iat: currentTime,
            exp: currentTime + 3600,
            session_name: userUid,
          };
          const formattedPublicKey = COZE_CONFIG.privateKey;
          return window.KJUR.jws.JWS.sign(
            header.alg,
            JSON.stringify(header),
            JSON.stringify(payload),
            formattedPublicKey,
          );
        }
        // 获得Token并创建Coze智能体界面
        async function getAccessToken(jwt) {
          try {
            const response = await fetch(
              "https://api.coze.cn/api/permission/oauth2/token",
              {
                method: "POST",
                headers: {
                  "Content-Type": "application/json",
                  Authorization: `Bearer ${jwt}`,
                },
                body: JSON.stringify({
                  grant_type: "urn:ietf:params:oauth:grant-type:jwt-bearer",
                  duration_seconds: 900,
                }),
              },
            );
            if (!response.ok) {
              throw new Error(`获取token失败,HTTP状态码: ${response.status}`);
            }

            const data = await response.json();
            const cozeWebSDK = await new CozeWebSDK.WebChatClient({
              config: {
                bot_id: COZE_CONFIG.botId,
              },
              auth: {
                type: "token",
                token: data.access_token,
                onRefreshToken: () => data.access_token,
              },
              /**
               * userInfo 参数用于设置聊天框中智能体用户信息的展示。
               * @param userInfo.id - 智能体用户的 ID。
               * @param userInfo.url - 用户头像的 URL 地址。
               * @param userInfo.nickname - 智能体用户的昵称。
               */
              userInfo: {
                id: "user",
                url: "https://lf-coze-web-cdn.coze.cn/obj/eden-cn/lm-lgvj/ljhwZthlaukjlkulzlp/coze/coze-logo.png",
                nickname: "User",
              },
              ui: {
                /**
                 * ui.base 参数用于设置聊天窗口的整体 UI 效果。
                 * @param base.icon - 应用图标 URL。
                 * @param base.layout - 智能体聊天框窗口的布局样式,可设为 'pc' 或 'mobile'。
                 * @param base.lang - 智能体的系统语言,可设为 'en' 或 'zh-CN'。
                 * @param base.zIndex - 聊天框的 z-index。
                 */
                base: {
                  icon: "https://lf-coze-web-cdn.coze.cn/obj/eden-cn/lm-lgvj/ljhwZthlaukjlkulzlp/coze/chatsdk-logo.png",
                  layout: 'mobile',
                  lang: "zh-CN",
                  zIndex: 1000,
                },
                /**
                 * 控制是否显示顶部标题栏和关闭按钮。
                 * @param header.isShow - 是否显示顶部标题栏。
                 * @param header.isNeedClose - 是否显示关闭按钮。
                 */
                header: {
                  isShow: true,
                  isNeedClose: true,
                },
                /**
                 * 控制是否在页面右下角显示悬浮球。
                 */
                asstBtn: {
                  isNeed: true,
                },
                /**
                 * ui.footer 参数用于设置聊天窗口的底部区域。
                 * @param footer.isShow - 是否显示底部复制模块。
                 * @param footer.expressionText - 底部显示的文字信息。
                 * @param footer.linkvars - 底部的链接文案与链接地址。
                 */
                footer: {
                  isShow: true,
                  expressionText: "独家",
                },
                conversations: {
                  isNeed: true,
                },
                /**
                 * 控制聊天框的 UI 与基础能力。
                 * @param chatBot.title - 聊天框标题。
                 * @param chatBot.uploadable - 是否支持文件上传。
                 * @param chatBot.width - PC 端智能体窗口宽度,单位为 px,默认 460。
                 * @param chatBot.el - 设置聊天框放置位置的容器(Element)。
                 */
                chatBot: {
                  title: "租房智能体",
                  uploadable: true,
                },
              },
            });
            // 自动打开智能体
            cozeWebSDK.showChatBot();
          } catch (error) {
            throw new Error(`获取Access Token失败: ${error.message}`);
          }
        }

        // 获取用户唯一标识
        function getUserUid() {
          // 从本地存储获取登录用户ID
          const loggedUserId = localStorage.getItem("website_user_id");
          if (loggedUserId) return loggedUserId;

          // 生成临时访客ID
          let visitorId = localStorage.getItem("coze_visitor_id");
          if (!visitorId) {
            visitorId = `visitor_${Date.now()}_${Math.random().toString(36).slice(-6)}`;
            localStorage.setItem("coze_visitor_id", visitorId);
          }
          return visitorId;
        }
        // 初始化Coze聊天
        function initCozeChat() {
          if (!window.CozeWebSDK || !window.CozeWebSDK.WebChatClient) {
            console.error("Coze SDK未加载");
            return;
          }

          const userUid = getUserUid();
          const jwtToken = generateCozeJwt(userUid);
          getAccessToken(jwtToken);
        }

        // 加载Coze SDK
        function loadCozeSdk() {
          const script = document.createElement("script");
          script.src =
            "https://lf-cdn.coze.cn/obj/unpkg/flow-platform/chat-app-sdk/1.2.0-beta.20/libs/cn/index.js";
          script.onload = initCozeChat;
          script.onerror = () =>
            console.error(`Coze SDK加载失败: ${COZE_CONFIG.sdkSrc}`);
          document.head.appendChild(script);
        }

        // 初始化流程
        async function init() {
          try {
            await loadJwtLibrary();
            loadCozeSdk();
          } catch (error) {
            console.error("初始化失败:", error.message);
          }
        }

        // 页面加载完成后初始化
        if (document.readyState === "complete") {
          init();
        } else {
          window.addEventListener("load", init);
        }
      })();
    </script>
  </body>
</html>

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐