> For the complete documentation index, see [llms.txt](https://docs.maiagent.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.maiagent.ai/tech/api-integration/web-chat-sdk.md).

# Web Chat 嵌入與 SDK

將 MaiAgent Web Chat 嵌入任何網站：嵌入碼、視窗模式、身份識別、完整配置參考與 JavaScript SDK API

在網頁加入一段嵌入碼，即可將 MaiAgent 的 AI 助理放進您的網站。嵌入碼載入 `embed.min.js`（以下稱 SDK）後，SDK 會在頁面上建立聊天按鈕與 iframe 聊天視窗，並提供全域 `MaiAgent` JavaScript API 供程式操作。

本頁是 Web Chat 嵌入的完整技術參考。相關主題：

* [串接 MaiGPT：選對助理、補齊能力](/tech/api-integration/web-chat-sdk/maigpt-integration.md) — MaiGPT 產品 vs MaiGPT 視窗模式，以及讓嵌入的助理會生圖、會用工具
* [Web Chat MaiGPT 模式嵌入](/tech/api-integration/web-chat-sdk/web-chat-maigpt-mode.md) — 類 ChatGPT 的全功能對話介面
* [WebChat 注入頁面 Context](/tech/api-integration/web-chat-sdk/web-chat-context-data.md) — 把頁面資訊注入 LLM System Prompt
* [聯絡人身份同步與 Token 更新](/tech/authorization-integration/contact-credentials-sync.md) — 後端建立聯絡人與憑證
* [軟體廠商整合指南（端到端）](/tech/authorization-integration/vendor-integration-guide.md) — 嵌入＋權限對接的完整旅程（批次補建、登入同步、登出註銷）

## 一、快速開始 <a href="#quickstart" id="quickstart"></a>

在頁面 `</body>` 前加入：

```html
<script>
  window.maiagentChatbotConfig = {
    webChatId: 'your-web-chat-id',
    baseUrl: 'https://chat.maiagent.ai/web-chats',
    primaryColor: '#1890ff',
  }
</script>
<script src="https://chat.maiagent.ai/js/embed.min.js" defer></script>
```

* `webChatId` 從管理後台的 Web Chat 設定頁取得（參考[串接對話平台：網站](https://docs.maiagent.ai/release/website)，由後台產生的嵌入碼會自動帶入）
* `baseUrl` 與 SDK 網址以 SaaS 環境（`chat.maiagent.ai`）為例；私有雲／地端部署請換成您環境的網域
* `window.maiagentChatbotConfig` **必須在 SDK 腳本載入前定義**

預設行為：頁面右下角出現聊天按鈕，點擊開啟漂浮聊天視窗，使用者可在漂浮（floating）與側欄（sidebar）兩種視窗模式間切換。

### 初始化時機 <a href="#init-timing" id="init-timing"></a>

SDK 載入後會註冊 `document.body.onload` 處理器執行初始化，一般情況不需手動介入。需要控制初始化時機時（例如 SPA 等容器 mount、或延遲渲染）：

1. **延遲載入腳本**：在適當時機才動態插入 `embed.min.js` 的 `<script>` 標籤
2. **手動觸發**：先設定好 `window.maiagentChatbotConfig`，再呼叫 `document.body.onload()`

同一頁面 SDK 只會初始化一次，重複載入會被忽略。

## 二、視窗模式 <a href="#window-modes" id="window-modes"></a>

`enabledWindowModes` 陣列決定使用者可用的視窗模式，**第一個元素是預設模式**；不設定時等同 `['floating', 'sidebar']`。

| 模式         | 形態                                               | 適用情境                                                                                       |
| ---------- | ------------------------------------------------ | ------------------------------------------------------------------------------------------ |
| `floating` | 疊在頁面右下角的漂浮視窗，可拖曳按鈕、可調整視窗大小（320×400 至 900×900 px） | 一般客服、諮詢                                                                                    |
| `sidebar`  | 貼齊視窗右側的側欄（寬 320–800 px，可拖曳調整），頁面內容自動收縮避讓         | 需要邊看頁面邊對話的工作情境                                                                             |
| `maigpt`   | 類 ChatGPT 完整介面（對話歷史側欄、搜尋、設定），佔滿指定容器或全屏           | 頁面主功能區塊、全站 AI 入口，見 [MaiGPT 模式](/tech/api-integration/web-chat-sdk/web-chat-maigpt-mode.md) |

```javascript
// 只允許側欄模式
window.maiagentChatbotConfig = {
  webChatId: 'your-web-chat-id',
  baseUrl: 'https://chat.maiagent.ai/web-chats',
  enabledWindowModes: ['sidebar'],
}
```

* 陣列有兩種以上模式時，聊天視窗會出現模式切換鈕；`allowWindowModeSwitch: false` 可隱藏
* `maigpt` 作為第一個元素時進入 MaiGPT 模式，其餘元素無效（該模式不提供切換）
* 舊欄位 `defaultWindowMode` 已棄用：仍可運作（視同 `enabledWindowModes: [該值]`），但會在 console 顯示棄用警告

### 三種模式的實際畫面 <a href="#window-modes-gallery" id="window-modes-gallery"></a>

{% tabs %}
{% tab title="floating 漂浮視窗" %}

<figure><img src="https://527168072-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F38pkhhqHl1oA6yyE9R2n%2Fuploads%2Fgit-blob-56a6936e787340e6429586677d8be3bacc08b308%2Fwebchat-mode-floating.png?alt=media" alt="floating 模式：聊天視窗疊在頁面右下角"><figcaption><p>floating：聊天視窗疊在頁面右下角，不影響頁面排版，可拖曳按鈕移動位置</p></figcaption></figure>
{% endtab %}

{% tab title="sidebar 側欄" %}

<figure><img src="https://527168072-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F38pkhhqHl1oA6yyE9R2n%2Fuploads%2Fgit-blob-4d989af74c4a47e70c3d61a6f6f4b496a31f6a09%2Fwebchat-mode-sidebar.png?alt=media" alt="sidebar 模式：聊天視窗貼齊右側，頁面內容自動收縮"><figcaption><p>sidebar：聊天視窗貼齊視窗右側，頁面內容自動收縮避讓，適合邊看頁面邊對話</p></figcaption></figure>
{% endtab %}

{% tab title="maigpt 完整介面" %}

<figure><img src="https://527168072-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F38pkhhqHl1oA6yyE9R2n%2Fuploads%2Fgit-blob-aab515bf01f9122d1b558aeaefcd1e59079466a0%2Fwebchat-maigpt-mode-a-container.png?alt=media" alt="maigpt 模式：類 ChatGPT 完整對話介面"><figcaption><p>maigpt：類 ChatGPT 完整介面（含對話歷史側欄），詳見 <a href="/tech/api-integration/web-chat-sdk/web-chat-maigpt-mode.md">MaiGPT 模式嵌入</a></p></figcaption></figure>
{% endtab %}
{% endtabs %}

## 三、識別使用者 <a href="#identify-users" id="identify-users"></a>

Web Chat 依是否綁定聯絡人（Contact），分為三個身份層級：

| 層級      | 設定方式                                                                                                            | 對話歷史       | AI 個人化／以使用者權限呼叫工具 |
| ------- | --------------------------------------------------------------------------------------------------------------- | ---------- | ----------------- |
| 匿名      | 什麼都不設定                                                                                                          | 以瀏覽器為單位保留  | ✖                 |
| 前端 auth | config 帶 `auth: { sourceId, ... }`，SDK 自動建立或對應聯絡人                                                               | 跟著聯絡人、可跨裝置 | ✔                 |
| 後端串接    | 後端呼叫[身份同步 API](/tech/authorization-integration/contact-credentials-sync.md) 取得 `contactId`，config 帶 `contactId` | 跟著聯絡人、可跨裝置 | ✔                 |

**前端 auth**：SDK 初始化完成後，會自動以 `auth` 的內容呼叫 MaiAgent 的身份同步 API（`setup-contact-credentials`），依 `sourceId` 建立或對應聯絡人：

```javascript
window.maiagentChatbotConfig = {
  webChatId: 'your-web-chat-id',
  baseUrl: 'https://chat.maiagent.ai/web-chats',
  auth: {
    sourceId: 'user-12345',   // 必填：您系統中該使用者的唯一識別碼
    name: '王小明',            // 選填：聯絡人顯示名稱（只在首次建立時生效）
    contextData: { ... },     // 選填：注入 LLM System Prompt，見 contextData 頁
    ts: 1785500000,           // 開啟簽章驗證時必填：Unix 秒（UTC），由您的後端產生
    sig: '9f2c...',           // 開啟簽章驗證時必填：HMAC-SHA256 簽章，見下方「簽章驗證」
  },
}
```

若該 Web Chat 的登入設定開啟了「允許嵌入端以 Source ID 免登入對話」並選擇簽章模式，`ts` 與 `sig` 為必填，缺少或驗證不通過時使用者會被導向登入頁。手動呼叫 `MaiAgent.auth.setup()` 時同樣接受這兩個欄位。

**後端串接**：由您的後端在使用者登入時呼叫同一支 API（可同時綁定 MCP 工具憑證），將回傳的 `contactId` 存進會員資料，前端只帶 `contactId`。

兩條路怎麼選：

* 只需要「認得使用者、保留跨裝置對話」→ **前端 auth** 最省事
* 需要把使用者的 Access Token 綁進 MCP 工具憑證（讓 AI 以使用者權限呼叫您的 API），且不希望 token 出現在前端頁面原始碼 → **後端串接**
* 兩者底層是同一套聯絡人機制，`sourceId` 相同即視為同一聯絡人，可混用

{% hint style="info" %}
另可用 `queryMetadata` 控制該使用者的知識庫檢索範圍（RAG 權限過濾），詳見[知識管理權限（Query Metadata）總覽](/tech/authorization-integration/zhi-shi-guan-li-quan-xian-query-metadata-cha-xun-yuan-zi-liao-zong-lan.md)。`queryMetadata` 不會進入 LLM prompt；要讓 AI「知道」某個值請用 [contextData](/tech/api-integration/web-chat-sdk/web-chat-context-data.md)。
{% endhint %}

### 安全注意事項 <a href="#identity-security" id="identity-security"></a>

{% hint style="danger" %}
**`contactId` 是身份憑證**：拿到它就能以該使用者身份對話、看到他的對話歷史。只在**登入後**的頁面把 `contactId` 輸出給該使用者本人，不要放進公開頁面的原始碼。

`auth.sourceId` 的要求取決於是否開啟簽章驗證：

* **未開啟簽章驗證**：身份同步是公開端點，可猜測的 `sourceId` 等於可冒充的身份。請使用不可猜測的值（如 UUID），不要用流水號、Email 或手機號碼。
* **已開啟簽章驗證**：安全性來自簽章而非 `sourceId` 本身，因此學號、員工編號、註冊 Email 等可讀值都可以直接使用。密鑰只存在您的伺服器，沒有密鑰就算知道 `sourceId` 也算不出有效簽章。
  {% endhint %}

### 簽章驗證 <a href="#source-id-signature" id="source-id-signature"></a>

Web Chat 的登入設定可開啟「允許嵌入端以 Source ID 免登入對話」，讓您網站上已登入的使用者不必在聊天視窗再登入一次。開關與密鑰在後台的登入設定分頁，操作方式見使用者手冊的[以聯絡人 Source ID 免登入對話](https://docs.maiagent.ai/conversations/web-chat/source-id-access)。

驗證方式有兩種，簽章模式為建議值：

| 驗證方式         | 行為                                 |
| ------------ | ---------------------------------- |
| 要求簽章驗證       | 須帶 `ts` 與 `sig`，驗章通過才放行            |
| 僅憑 Source ID | 不驗章，帶了 `sourceId` 就放行；僅適合測試或內網封閉環境 |

**簽章算法**

```
HMAC-SHA256(密鑰, "{webChatId}.{sourceId}.{ts}")
```

以 hex 小寫字串傳遞。`ts` 為 Unix 秒（UTC）。密鑰由平台在後台產生，只能存在您的伺服器環境變數，不得寫入前端程式碼。

{% tabs %}
{% tab title="PHP" %}

```php
$ts  = time();
$sig = hash_hmac('sha256', "{$webChatId}.{$sourceId}.{$ts}", $SIGNING_SECRET);
```

{% endtab %}

{% tab title="Node" %}

```javascript
const ts = Math.floor(Date.now() / 1000);
const sig = crypto.createHmac('sha256', SIGNING_SECRET)
  .update(`${webChatId}.${sourceId}.${ts}`).digest('hex');
```

{% endtab %}

{% tab title="Python" %}

```python
ts = int(time.time())
sig = hmac.new(SIGNING_SECRET.encode(),
  f"{web_chat_id}.{source_id}.{ts}".encode(), hashlib.sha256).hexdigest()
```

{% endtab %}
{% endtabs %}

**驗證規則**

| 規則   | 說明                                      |
| ---- | --------------------------------------- |
| 有效期限 | 後台可設 1／5／15 分鐘，預設 5 分鐘                  |
| 時鐘容忍 | 允許 60 秒偏差；時間戳超出未來 60 秒一律拒絕              |
| 一次性  | 同一組簽章只能成功使用一次，簽章本身即為防重放 nonce           |
| 綁定平台 | 簽章含 `webChatId`，同組織其他 Web Chat 的簽章不能重用  |
| 拒絕回應 | 所有失敗原因對外回應一致，不透露原因，也不透露 `sourceId` 是否存在 |

{% hint style="warning" %}
簽章一次有效，**每次進場都要重新計算，不得快取**。有效期限限制的是「多久內可以用這組簽章換取聯絡人身份」，不是對話的存續時間；換得身份後對話不會因簽章逾期而中斷。
{% endhint %}

**有效期限與登出的關係**

換得的 `contactId` 本身沒有到期時間，平台目前也沒有作廢它的端點。使用者在您的網站登出後，您能控制的是不再簽發新簽章；前端可呼叫 `MaiAgent.auth.signOut()` 讓聊天視窗回到匿名，工具憑證的註銷見[登出與憑證註銷](/tech/authorization-integration/contact-credentials-sync.md#logout-revoke)。

**排查驗章失敗**

後台登入設定的「查看驗章失敗紀錄」列出最近的失敗事件與原因，供您自助排查：

| 原因                 | 常見成因                                |
| ------------------ | ----------------------------------- |
| 簽章逾期               | 伺服器時鐘偏移，或前端快取了簽章                    |
| 時間戳超出未來容許範圍        | 伺服器時鐘快了超過 60 秒                      |
| 簽章不符               | 密鑰不一致，或簽章字串組法有誤（分隔符號為半形句點）          |
| 缺少時間戳或簽章           | 未帶 `ts` 或 `sig`                     |
| 簽章已被使用             | 同一組簽章送了第二次                          |
| Source ID 對應到多位聯絡人 | 該 Web Chat 存在同一 `sourceId` 的重複聯絡人資料 |

### 允許嵌入網域 <a href="#embed-origin-allowlist" id="embed-origin-allowlist"></a>

Web Chat 的「允許嵌入網域」清單限制哪些網站能完成**身份同步**（`auth` 與後端的 setup-contact-credentials 都受此約束）。此清單目前由 MaiAgent 團隊為您設定：請將要允許的網域清單提供給您的對接窗口。

| 清單狀態                     | 行為                                       |
| ------------------------ | ---------------------------------------- |
| 空清單（預設）                  | 不限制來源                                    |
| 列出 `https://example.com` | 精確比對 scheme＋host（＋port）                  |
| 列出 `*.example.com`       | 涵蓋 `example.com` 與其所有子網域（任何 scheme／port） |
| 清單有值但全部格式無效              | **拒絕所有來源**（fail closed），不會靜默退回不限制        |

有對外嵌入且使用身份功能的 Web Chat，建議一律設定此清單，縮小可取得 `contactId` 的來源。

## 四、配置選項參考 <a href="#config-reference" id="config-reference"></a>

`window.maiagentChatbotConfig` 支援的全部欄位。設定未知欄位不會報錯，但 console 會出現 `[maiagent] Unknown config options: ...` 警告，方便檢查拼字。

### 基本 <a href="#config-basic" id="config-basic"></a>

| 欄位              | 型別                  | 必填 | 說明                                                                                                                                                   |
| --------------- | ------------------- | -- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| `webChatId`     | `string`            | ✅  | Web Chat 的唯一識別碼                                                                                                                                      |
| `baseUrl`       | `string`            | ✅  | Web Chat 服務位址，SaaS 為 `https://chat.maiagent.ai/web-chats`                                                                                            |
| `contactId`     | `string`            |    | 聯絡人 ID（後端串接時使用，見[識別使用者](#identify-users)）                                                                                                            |
| `auth`          | `object`            |    | 前端身份設定：`sourceId`（必填）、`name`、`contextData`、`mcpCredentials`、`ts` 與 `sig`（開啟簽章驗證時必填，見[簽章驗證](#source-id-signature)）。SDK 就緒後自動執行 `auth.setup()`         |
| `queryMetadata` | `object` 或 `string` |    | 知識庫檢索範圍過濾（不進 LLM prompt）                                                                                                                             |
| `locale`        | `string`            |    | 介面語系（如 `zh-TW`、`en`），支援清單見 [MaiGPT 模式頁第五節](/tech/api-integration/web-chat-sdk/web-chat-maigpt-mode.md#locale)；優先權：config > 使用者上次選擇 > 瀏覽器語系 > `zh-TW` |

{% hint style="warning" %}
目前版本傳入 `auth` 時 console 會誤報 `Unknown config options: auth`，功能不受影響，可忽略該則警告。
{% endhint %}

### 視窗模式與行為 <a href="#config-behavior" id="config-behavior"></a>

| 欄位                      | 型別                       | 預設值                       | 說明                                                                                         |
| ----------------------- | ------------------------ | ------------------------- | ------------------------------------------------------------------------------------------ |
| `enabledWindowModes`    | `string[]`               | `['floating', 'sidebar']` | 可用視窗模式，第一項為預設；見[視窗模式](#window-modes)                                                       |
| `allowWindowModeSwitch` | `boolean`                | `true`                    | 是否顯示視窗模式切換鈕（僅在啟用兩種以上模式時有意義）                                                                |
| `showButton`            | `boolean`                | `true`                    | 是否顯示聊天按鈕。設 `false` 時改由程式呼叫 `MaiAgent.control.open()` 開啟                                    |
| `showChatNotification`  | `boolean`                | `false`                   | 視窗關閉時收到回覆，是否在按鈕旁顯示通知                                                                       |
| `chatNotificationTitle` | `string`                 |                           | 通知的標題文字                                                                                    |
| `preventIosInputZoom`   | `boolean`                |                           | 防止 iOS Safari 聚焦輸入框時自動放大頁面                                                                 |
| `targetElement`         | `string` 或 `HTMLElement` |                           | MaiGPT 模式專用：嵌入容器，見 [MaiGPT 模式](/tech/api-integration/web-chat-sdk/web-chat-maigpt-mode.md) |
| `maigptTitle`           | `string`                 |                           | MaiGPT 模式專用：側欄品牌標題，預設顯示 `MaiGPT`                                                           |

### 外觀 <a href="#config-appearance" id="config-appearance"></a>

尺寸類欄位接受數字（視為 px）、`'Npx'` 或 `'Nrem'` 字串。

| 欄位              | 型別                  | 預設值                                  | 說明                              |
| --------------- | ------------------- | ------------------------------------ | ------------------------------- |
| `primaryColor`  | `string`            | `#1890ff`                            | 主題色（按鈕與介面主色）                    |
| `buttonSize`    | `string` 或 `number` | `3rem`                               | 聊天按鈕尺寸                          |
| `buttonRadius`  | `string`            | `50%`                                | 聊天按鈕圓角                          |
| `buttonIcon`    | `string`            |                                      | 按鈕圖示的圖片 URL（優先於 `openIconHtml`） |
| `openIconHtml`  | `string`            | 內建 SVG                               | 按鈕「開啟」狀態的自訂 HTML                |
| `closeIconHtml` | `string`            | 內建 SVG                               | 按鈕「關閉」狀態的自訂 HTML                |
| `windowWidth`   | `string` 或 `number` | `24rem`                              | 漂浮視窗寬度                          |
| `windowHeight`  | `string` 或 `number` | `40rem`                              | 漂浮視窗高度                          |
| `windowRadius`  | `string`            | `0.75rem`                            | 漂浮視窗圓角                          |
| `boxShadow`     | `string`            | `0.125rem 0.125rem 0.5rem #00000044` | 按鈕與視窗陰影                         |

### 位置 <a href="#config-position" id="config-position"></a>

| 欄位                     | 型別                  | 預設值      | 說明                     |
| ---------------------- | ------------------- | -------- | ---------------------- |
| `buttonPositionBottom` | `string` 或 `number` | `16`（px） | 按鈕距視窗底部                |
| `buttonPositionRight`  | `string` 或 `number` | `16`（px） | 按鈕距視窗右側                |
| `windowPositionBottom` | `string`            | `5rem`   | 漂浮視窗距底部                |
| `windowPositionRight`  | `string`            | `1rem`   | 漂浮視窗距右側                |
| `windowPosition`       | `string`            |          | 設 `'center'` 時漂浮視窗置中顯示 |

聊天按鈕支援拖曳移動，位置會記憶在瀏覽器中；再次載入時若記憶位置超出目前視窗範圍，會自動回到安全位置。

## 五、SDK API <a href="#sdk-api" id="sdk-api"></a>

SDK 初始化後可透過全域 `MaiAgent` 物件操作。所有方法都應在 SDK 就緒後呼叫（見[疑難排解](#troubleshooting)的可用性檢查）。

### 視窗控制 `MaiAgent.control` <a href="#api-control" id="api-control"></a>

| 方法         | 說明                    |
| ---------- | --------------------- |
| `open()`   | 開啟聊天視窗                |
| `close()`  | 關閉聊天視窗                |
| `isOpen()` | 回傳聊天視窗是否開啟（`boolean`） |

另有等價的全域捷徑 `window.maiagentOpenChat()` / `window.maiagentCloseChat()`。

### 訊息 `MaiAgent.chat` <a href="#api-chat" id="api-chat"></a>

| 方法                  | 說明             |
| ------------------- | -------------- |
| `send(content)`     | 以使用者身份送出一則文字訊息 |
| `clearHistory()`    | 清除目前對話的歷史訊息    |
| `newConversation()` | 開始新對話          |

```javascript
MaiAgent.chat.send('你好，我想了解你們的服務')
MaiAgent.control.open()
```

### 事件 `MaiAgent.events` <a href="#api-events" id="api-events"></a>

| 方法                         | 說明                          |
| -------------------------- | --------------------------- |
| `on(eventType, callback)`  | 註冊事件監聽器                     |
| `off(eventType, callback)` | 移除事件監聽器（需傳入同一個 callback 參照） |

可監聽的事件：

| 事件             | 觸發時機              | callback 參數                                                                      |
| -------------- | ----------------- | -------------------------------------------------------------------------------- |
| `messageReply` | 收到 AI 助理回覆        | 已解析的物件：`{ content: string, sender?: { name, avatar }, timestamp?: number, ... }` |
| `sdkReady`     | SDK 初始化完成         | —                                                                                |
| `authReady`    | `auth.setup()` 完成 | —                                                                                |
| `iframeReady`  | 聊天視窗 iframe 就緒    | —                                                                                |

```javascript
// 建議使用 MaiAgent.EVENT_TYPES 常數，避免拼字錯誤
MaiAgent.events.on(MaiAgent.EVENT_TYPES.MESSAGE_REPLY, (data) => {
  console.log('收到回覆：', data.content)
})
```

### 語系與語音 <a href="#api-locale-speech" id="api-locale-speech"></a>

| 方法                                     | 說明                                                                                                                           |
| -------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| `MaiAgent.locale.set(lang)`            | 切換介面語系，如 `'zh-TW'`、`'zh-CN'`、`'en'`；支援清單見 [MaiGPT 模式頁第五節](/tech/api-integration/web-chat-sdk/web-chat-maigpt-mode.md#locale) |
| `MaiAgent.speech.set(lang, provider?)` | 設定語音辨識與合成的語言，`provider` 可指定語音服務供應商（如 `'azure'`）                                                                              |

`locale` 只影響介面文字，不影響 AI 回答的語言；AI 回覆語言的設定見[多國語言支援](https://docs.maiagent.ai/build/multi-language-support)。

### 身份 `MaiAgent.auth` <a href="#api-auth" id="api-auth"></a>

| 方法                  | 說明                                                                                                                                          |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `setup(authConfig)` | 建立或對應聯絡人並套用身份，回傳 `Promise<string \| null>`（成功時為 `contactId`）。`authConfig` 欄位同 config 的 `auth`                                               |
| `signOut()`         | 登出目前身份，回到匿名狀態並清除 `contextData`。只作用於前端；後端已綁定的工具憑證要另外註銷，見[登出與憑證註銷](/tech/authorization-integration/contact-credentials-sync.md#logout-revoke) |

config 有 `auth` 時 SDK 會自動呼叫 `setup()`，不需手動執行；SPA 中使用者登入／登出、或需要更新 `contextData` 時才需要手動呼叫。

## 六、完整範例 <a href="#full-example" id="full-example"></a>

```html
<!doctype html>
<html lang="zh-TW">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>MaiAgent Web Chat 整合範例</title>
  </head>
  <body>
    <h1>我的網站</h1>

    <button onclick="MaiAgent.control.open()">開啟客服</button>
    <button onclick="startNewChat()">新對話</button>

    <script>
      window.maiagentChatbotConfig = {
        webChatId: 'your-web-chat-id',
        baseUrl: 'https://chat.maiagent.ai/web-chats',
        primaryColor: '#007bff',
        enabledWindowModes: ['floating', 'sidebar'],
        locale: 'zh-TW',
        auth: {
          sourceId: 'user-12345',
          name: '王小明',
        },
      }
    </script>
    <script src="https://chat.maiagent.ai/js/embed.min.js" defer></script>

    <script>
      document.addEventListener('DOMContentLoaded', () => {
        MaiAgent.events.on(MaiAgent.EVENT_TYPES.MESSAGE_REPLY, (data) => {
          console.log('收到 AI 回覆：', data.content)
          // 可在此串接分析工具，例如 GA4：
          // gtag('event', 'chat_interaction', { event_label: 'bot_reply' })
        })
      })

      function startNewChat() {
        MaiAgent.chat.newConversation()
        MaiAgent.control.open()
      }
    </script>
  </body>
</html>
```

## 七、疑難排解 <a href="#troubleshooting" id="troubleshooting"></a>

| 症狀                                       | 檢查                                                                                |
| ---------------------------------------- | --------------------------------------------------------------------------------- |
| 按鈕沒出現                                    | `maiagentChatbotConfig` 是否在 SDK 腳本之前定義；`webChatId` / `baseUrl` 是否正確；console 是否有錯誤 |
| console 出現 `Unknown config options: ...` | 對照[配置選項參考](#config-reference)檢查欄位拼字（`auth` 的誤報可忽略）                                |
| `MaiAgent is not defined`                | SDK 尚未載入完成；在 `DOMContentLoaded` 之後再呼叫，或先檢查 `typeof MaiAgent !== 'undefined'`      |
| 事件監聽器沒觸發                                 | 確認事件名稱正確（建議用 `MaiAgent.EVENT_TYPES` 常數）；`off()` 需傳入與 `on()` 相同的函式參照               |
| 對話換裝置就不見                                 | 匿名狀態的對話以瀏覽器為單位；要跨裝置請設定 `auth` 或 `contactId`（見[識別使用者](#identify-users)）            |
| `auth` 設定後身份沒生效（400 錯誤）                  | Web Chat 若設定了「允許嵌入網域」，只有清單內網域的頁面能完成身份同步；請確認嵌入頁的網域已加入清單                            |
| 按鈕位置異常                                   | 檢查頁面 CSS 是否與按鈕樣式衝突；位置參數格式是否正確（數字、`px` 或 `rem`）                                    |

安全地呼叫 SDK：

```javascript
function safeOpenChat() {
  if (typeof MaiAgent !== 'undefined' && MaiAgent.control) {
    MaiAgent.control.open()
  }
}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.maiagent.ai/tech/api-integration/web-chat-sdk.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
