---
doc_id: aiffjs-api-reference
title: AiffJS 介面說明手冊
description: AiffJS 1.0.19 的初始化、使用者資料、聊天室、訊息分享、視窗、裝置能力、事件回呼與各應用支援狀態參考。
slug: /products/aiff/aiffjs-api-reference
product: AIFF
category: api-reference
audience:
  - developer
  - partner
visibility: public
status: published
version: 1.0.0
owner: aile-platform
updated_at: 2026-06-16
tags:
  - AIFF
  - AiffJS
  - API
  - 開發參考
rendered_html: /rendered/products/aiff/aiffjs-api-reference/
download: true
sidebar_position: 2
---

# AiffJS 介面說明手冊

> 適用版本：`AiffJS.version = "1.0.19"`  
> 依據檔案：`aiff.js`、`aiff.min.js`、`README.md`、原 `AiffJs SDK 檔案說明.docx`

## 1. 概述

`AiffJS` 是 Aiff 頁面與 Aile 宿主之間的 JavaScript 介面封裝。Aiff 頁面透過全域物件 `AiffJS` 呼叫宿主提供的 `window.AileAPI` 能力，例如初始化、取得目前使用者資料、取得開啟來源、開啟聊天室、傳送訊息、分享內容、取得位置、掃碼、修改標題等。

目前原始碼會在腳本載入後自動執行：

```js
AiffJS._initEvent();
```

該初始化事件會註冊宿主側通知：

| 宿主事件 | AiffJS 回呼 | 說明 |
| --- | --- | --- |
| `closeAiff` | `AiffJS.onCloseWindow(cancelFun)` | 宿主要求關閉 Aiff 頁面時觸發 |
| `aiffEvent` | `AiffJS.onAiffEvent(args)` | 宿主主動傳送給 Aiff 頁面的事件 |

## 2. 快速開始

```html
<script src="./aiff.min.js"></script>
<script>
  AiffJS.init("your-aiff-id").then(function (ok) {
    if (!ok) {
      return;
    }

    const profile = AiffJS.getProfile();
    const opener = AiffJS.getOpener();
    console.log(profile, opener);
  });
</script>
```

使用約定：

- 大多數介面需要先呼叫 `AiffJS.init(aiffId)` 且返回 `true`。
- 若宿主未提供 `window.AileAPI`，`init` 會返回 `Promise<false>`。
- 部分介面未初始化時返回 `null`，部分介面返回 `{ code: "Aiff.NotInit" }`。具體以各介面說明為準。
- 返回內容最終由宿主端實現決定，本手冊中的欄位來自舊版說明書及當前原始碼封裝方式。

## 3. 版本記錄

| 版本 | 日期 | 說明 |
| --- | --- | --- |
| 1.0.1 | 2021-08-30 | 整理 Aiff 說明，並加入通知事件描述 |
| 1.0.2 | 2021-11-23 | 調整 `getOpener` 返回內容，加入服務號聊天室欄位 |
| 1.0.3 | 2022-03-21 | 加入 `openContactChat` 等定義 |
| 1.0.4 | 2022-03-22 | 取消前端傳送聯絡人訊息介面 |
| 1.0.5 | 2022-04-21 | 根據 AiPower 討論調整介面，加入 `openBossContactChat`、`shareTargetPicker` |
| 1.0.6 | 2022-06-25 | 新增 `openWindow` |
| 1.0.7 | 2022-07 | 調整 `getClientType`，加入客戶端實現介面 |
| 1.0.8 | 2022-08-02 | 加入使用者資訊相關介面和 `getRoomStatus` |
| 1.0.9 | 2022-08-16 | `sendMessage` 加入 `type` 引數，支援 `text` 和 `template` |
| 1.0.11 | 2022-09-22 | 加入 `getAiffItem` |
| 1.0.12 | 2023-02-16 | 加入 `scanCode`、`getCurrentPosition` |
| 1.0.13 | - | 加入 `shareMessage`、`sendCmd`、`openWindow` |
| 1.0.14 | - | 加入分享相關介面 |
| 1.0.15 | - | 加入 `getNative` |
| 1.0.16 | - | 調整 iframe 判斷，並加入 `sendData` |
| 1.0.17 | - | 修正日誌判斷邏輯 |
| 1.0.18 | - | 新增 `subscribeCurrentPosition`、`startEvent`、`stopEvent` |
| 1.0.19 | 2026-04-22 | 新增 `changeAiffTitle`，併相容歷史拼寫 `changeAiffTilte` |

## 4. 介面總覽與應用支援狀態

支援狀態口徑：目前僅已完成 AileAPP（原 `newaile`）逐介面整理，依據 AileAPP 宿主橋接實作、模組文件與測試覆蓋標示為 `已支援`、`有限制支援` 或 `暫不列入支援範圍`。AileDesktop 目前可確認有 AIFF 槽位與上下文注入方向，但尚未完成逐介面驗證；AileProAPP、AileProDesktop 也尚未完成逐介面盤點，因此先標示為 `待確認`，避免把未知狀態誤判為不支援。

狀態說明：

| 狀態 | 說明 |
| --- | --- |
| 已支援 | 目前產品已有對應宿主能力或測試覆蓋，可作為對外使用口徑 |
| 有限制支援 | 目前產品支援，但受入口、聊天室上下文、權限或 payload 條件限制 |
| 暫不列入支援範圍 | SDK 有介面或歷史相容入口，但目前產品支援矩陣不將其列為可用能力 |
| 待確認 | 尚未完成該產品逐介面驗證；不代表不支援 |

| 分類 | 介面 | 返回值 | 說明 | AileAPP | AileDesktop | AileProAPP | AileProDesktop | 備註 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 初始化 | `init(aiffId)` | `Promise<boolean>` | 初始化 Aiff | 已支援 | 待確認 | 待確認 | 待確認 |  |
| 初始化 | `getClientType()` | `string` | 取得目前載具型別 | 已支援 | 待確認 | 待確認 | 待確認 |  |
| 初始化 | `openDev()` | `void` | 開啟宿主開發工具 | 已支援 | 待確認 | 待確認 | 待確認 |  |
| 基本資料 | `getAuthToken()` | `string \| null` | 取得目前鑑權 token | 已支援 | 待確認 | 待確認 | 待確認 |  |
| 基本資料 | `getAiffConfig()` | `Object \| null` | 取得 Aiff 設定 | 已支援 | 待確認 | 待確認 | 待確認 |  |
| 基本資料 | `getProfile()` | `Object \| null` | 取得目前使用者資料 | 已支援 | 待確認 | 待確認 | 待確認 |  |
| 基本資料 | `getOpener()` | `Object \| null` | 取得目前開啟來源 | 已支援 | 待確認 | 待確認 | 待確認 |  |
| 基本資料 | `getAiffItem(aiffKey)` | `Promise<Object>` | 取得指定 Aiff 資料 | 已支援 | 待確認 | 待確認 | 待確認 |  |
| 聊天室 | `openChat(roomId)` | `Promise<Object \| null>` | 開啟指定聊天室 | 已支援 | 待確認 | 待確認 | 待確認 |  |
| 聊天室 | `openUserChat(openId)` | `Promise<Object \| null>` | 開啟指定同事聊天室 | 已支援 | 待確認 | 待確認 | 待確認 | 取決於宿主同事聊天室能力 |
| 聊天室 | `getUserRooms(openId)` | `Promise<Object \| null>` | 取得同事關聯聊天室 | 暫不列入支援範圍 | 待確認 | 待確認 | 待確認 | 目前不列入 AileAPP 對外支援能力 |
| 聊天室 | `getAllRooms()` | `Promise<Object \| null>` | 取得聊天室列表 | 暫不列入支援範圍 | 待確認 | 待確認 | 待確認 | 目前不列入 AileAPP 對外支援能力 |
| 聊天室 | `openContactChat(serviceNumberId, openId)` | `Promise<Object \| null>` | 開啟指定服務號下的客戶聊天室 | 已支援 | 待確認 | 待確認 | 待確認 |  |
| 聊天室 | `openBossContactChat(openId)` | `Promise<Object \| null>` | 開啟目前主管號下的客戶聊天室 | 已支援 | 待確認 | 待確認 | 待確認 |  |
| 聊天室狀態 | `getRoomStatus(roomId = "")` | `Promise<Object>` | 取得聊天室服務狀態 | 已支援 | 待確認 | 待確認 | 待確認 |  |
| 使用者資料 | `getUser(openId, type = "")` | `Promise<Object>` | 取得使用者資料 | 已支援 | 待確認 | 待確認 | 待確認 |  |
| 使用者資料 | `getAvatar(openId, type = "")` | `Promise<Object>` | 取得使用者頭像 | 已支援 | 待確認 | 待確認 | 待確認 |  |
| 訊息 | `sendMessage(msgObj, type)` | 宿主返回值或 `null` | 傳送訊息到目前來源聊天室 | 已支援 | 待確認 | 待確認 | 待確認 |  |
| 訊息 | `selectMessage(msgObj)` | 宿主返回值或 `null` | 將訊息放入輸入框等待傳送 | 已支援 | 待確認 | 待確認 | 待確認 |  |
| 訊息 | `shareTargetPicker(templateObj, type)` | `Promise<Object>` | 選擇聊天室或同事並分享模板訊息 | 有限制支援 | 待確認 | 待確認 | 待確認 |  |
| 訊息 | `shareMessage(message)` | `Promise<Object>` | 使用系統分享文字 | 已支援 | 待確認 | 待確認 | 待確認 |  |
| 訊息 | `sendCmd(cmd)` | `Promise<Object>` | 向宿主傳送命令 | 暫不列入支援範圍 | 待確認 | 待確認 | 待確認 | 目前不列入 AileAPP 對外支援能力 |
| 視窗 | `openWindow(args)` | 宿主返回值或 `null` | 開啟 URL | 已支援 | 待確認 | 待確認 | 待確認 |  |
| 視窗 | `closeWindow()` | `true \| null` | 關閉目前 Aiff | 已支援 | 待確認 | 待確認 | 待確認 |  |
| 視窗 | `changeAiffTitle(title)` | `Promise<Object>` 或宿主返回值 | 修改目前 Aiff 標題 | 已支援 | 待確認 | 待確認 | 待確認 |  |
| 視窗 | `changeAiffTilte(title)` | `Promise<Object>` 或宿主返回值 | 歷史拼寫相容介面 | 已支援 | 待確認 | 待確認 | 待確認 | 建議新程式碼使用 `changeAiffTitle` |
| 導航 | `navigateToTab(mainAiffId, args = null)` | `void` | 跳轉主框架內嵌 Aiff | 暫不列入支援範圍 | 待確認 | 待確認 | 待確認 | 目前不列入 AileAPP 對外支援能力 |
| 裝置能力 | `scanCode()` | `Promise<Object>` | 啟動掃碼 | 已支援 | 待確認 | 待確認 | 待確認 |  |
| 裝置能力 | `getCurrentPosition()` | `Promise<Object>` | 取得目前位置 | 已支援 | 待確認 | 待確認 | 待確認 |  |
| 裝置能力 | `subscribeCurrentPosition()` | `Observable` | 訂閱位置變化 | 暫不列入支援範圍 | 待確認 | 待確認 | 待確認 | 目前不列入 AileAPP 對外支援能力 |
| 裝置能力 | `startEvent(eventName)` | 目前實作無穩定返回值 | 通知宿主啟動事件 | 暫不列入支援範圍 | 待確認 | 待確認 | 待確認 | 目前不列入 AileAPP 對外支援能力 |
| 裝置能力 | `stopEvent(eventName)` | 目前實作無穩定返回值 | 通知宿主停止事件 | 暫不列入支援範圍 | 待確認 | 待確認 | 待確認 | 目前不列入 AileAPP 對外支援能力 |
| 狀態 | `sendAiffState(ibState)` | 宿主返回值或 `null` | 設定 Aiff 紅點狀態 | 已支援 | 待確認 | 待確認 | 待確認 |  |
| 狀態 | `sendAiffStateNumber(iNumber)` | 宿主返回值或 `null` | 設定 Aiff 未讀數 | 已支援 | 待確認 | 待確認 | 待確認 |  |
| 原生資訊 | `getNative()` | `Promise<Object \| null>` | 取得宿主原生資訊 | 暫不列入支援範圍 | 待確認 | 待確認 | 待確認 | 目前不列入 AileAPP 對外支援能力 |
| 擴充 | `sendData(data)` | `void` | 向宿主傳送擴充資料 | 已支援 | 待確認 | 待確認 | 待確認 |  |
| 事件 | `onCloseWindow(cancelFun)` | `void` | 關閉前回呼 | 已支援 | 待確認 | 待確認 | 待確認 |  |
| 事件 | `onAiffEvent(args)` | `void` | 宿主通知回呼 | 已支援 | 待確認 | 待確認 | 待確認 |  |

## 5. 初始化與執行環境

### 5.1 `AiffJS.version`

當前版本號：

```js
AiffJS.version // "1.0.19"
```

### 5.2 `init(aiffId)`

初始化當前 Aiff 頁面。

```js
AiffJS.init(aiffId).then(function (ok) {
  if (ok) {
    // 初始化成功
  }
});
```

引數：

| 引數 | 型別 | 必填 | 說明 |
| --- | --- | --- | --- |
| `aiffId` | `string` | 否 | 建立 Aiff 設定時生成的唯一值，可為空 |

返回值：`Promise<boolean>`

| 返回 | 說明 |
| --- | --- |
| `true` | 宿主返回 `code === "Aiff.OK"`，初始化成功 |
| `false` | 無宿主環境，或宿主返回非成功狀態 |

初始化成功後，原始碼會儲存：

| 內部欄位 | 來源 | 說明 |
| --- | --- | --- |
| `_iniData.data` | 宿主初始化結果 | 當前使用者資料 |
| `_iniData.aiffItem` | 宿主初始化結果 | Aiff 設定 |
| `_iniData.info` | 宿主初始化結果 | 當前開啟來源 |

### 5.3 `getClientType()`

獲取當前載具型別。

```js
const clientType = AiffJS.getClientType();
```

返回值：`string`

| 返回值 | 說明 |
| --- | --- |
| `iframe` | 當前頁面位於 iframe 中 |
| `client` | 未初始化，但存在 `window.AileAPI` |
| `other` | 未初始化，且不存在 `window.AileAPI` |
| 初始化結果中的 `data.clientType` | 初始化成功後直接返回宿主給出的載具型別 |

舊文件中列出的常見載具型別：

| 值 | 說明 |
| --- | --- |
| `aile` | Aile 客戶端 |
| `aiwowo` | Aiwowo 客戶端 |
| `uupon` | 點數客戶端 |
| `ios` | iOS Aile App |
| `android` | Android Aile App |

### 5.4 `openDev()`

開啟宿主開發工具。

```js
AiffJS.openDev();
```

返回值：無。若不存在 `window.AileAPI`，方法不執行宿主呼叫。

## 6. 當前使用者、Aiff 設定與開啟來源

### 6.1 `getAuthToken()`

獲取當前登入使用者的鑑權 token。

```js
const token = AiffJS.getAuthToken();
```

返回值：

| 狀態 | 返回 |
| --- | --- |
| 已初始化 | `_iniData.data.authToken` |
| 未初始化 | `null` |

### 6.2 `getAiffConfig()`

獲取當前 Aiff 設定。

```js
const config = AiffJS.getAiffConfig();
```

返回值：

| 狀態 | 返回 |
| --- | --- |
| 已初始化 | `_iniData.aiffItem` |
| 未初始化 | `null` |

常見欄位：

| 欄位 | 型別 | 說明 |
| --- | --- | --- |
| `id` | `string` | Aiff ID |
| `name` | `string` | Aiff 名稱 |
| `title` | `string` | Aiff 顯示標題 |
| `url` | `string` | Aiff Endpoint URL |
| `displayType` | `string` | 顯示大小，`All` 全屏，`Half` 半屏 |
| `userType` | `string` | 應用客戶端，`employee` 員工端，`contact` 客戶端 |
| `applyType` | `number` | 應用方式，`1` 彈出應用，`2` 內嵌應用 |
| `popupLocation` | `number` | 彈出位置，`0` 訊息選單，`1` 聊天室 Menu，`2` 聊天室 Toolbar，`3` 主框架 |
| `embedLocation` | `number` | 內嵌位置，`0` 主框架，`1` 聊天室 title 下沉，`2` 物件下沉 |

### 6.3 `getProfile()`

獲取當前登入使用者資料。

```js
const profile = AiffJS.getProfile();
```

返回值：

| 狀態 | 返回 |
| --- | --- |
| 已初始化 | `_iniData.data` |
| 未初始化 | `null` |

常見欄位：

| 欄位 | 型別 | 說明 |
| --- | --- | --- |
| `id` | `string` | 當前使用者 ID |
| `nickName` | `string` | 當前使用者暱稱 |
| `imgSrc` | `string` | 當前使用者頭像，Base64 圖片格式 |
| `userType` | `string` | `employee` 員工，`contact` 客戶 |
| `appType` | `string` | 載具型別，例如 `client`、`ios`、`android` |
| `department` | `string` | 當前使用者所屬部門 |
| `authToken` | `string` | 當前使用者鑑權 token |
| `openId` | `string` | 當前使用者 openId |
| `tenantCode` | `string` | 當前租戶編碼 |
| `accountId` | `string` | CP 層級賬號；不可取時為空 |
| `clientType` | `string` | 客戶端型別，例如 `aile`、`aiwowo`、`uupon` |

### 6.4 `getOpener()`

獲取當前觸發開啟 Aiff 的來源資訊。

```js
const opener = AiffJS.getOpener();
```

返回值：

| 狀態 | 返回 |
| --- | --- |
| 已初始化 | `_iniData.info` |
| 未初始化 | `null` |

頂層欄位：

| 欄位 | 型別 | 說明 |
| --- | --- | --- |
| `openerType` | `string` | 來源型別 |
| `openerSource` | `string` | 開啟位置 |
| `id` | `string` | 若來源為訊息，則為訊息 ID；否則通常為聊天室 ID；主框架觸發時為空 |
| `roomId` | `string` | 聊天室內觸發時為聊天室 ID，否則為空 |
| `content` | `string` | 訊息選單觸發時為訊息內容 |
| `senderId` | `string` | 訊息選單觸發時為傳送者 OpenID |
| `roomInfo` | `Object` | 聊天室內觸發時存在 |
| `objectInfo` | `Object` | 物件 title 下沉觸發時存在 |
| `userInfo` | `Object` | 指定來源型別下存在 |

`openerType` 常見值：

| 值 | 說明 |
| --- | --- |
| `mainFrame` | 主框架開啟 |
| `system` | 系統聊天室 |
| `self` | 個人聊天室 |
| `vistor` | 訪客聊天室 |
| `friend` | 同事聊天室 |
| `group` | 社團聊天室 |
| `discuss` | 多人聊天室 |
| `serviceMember` | 服務號成員聊天室 |
| `serviceSub` | 服務號訂閱者聊天室 |
| `serviceRoom` | 服務號成員視角下的客戶聊天室 |
| `unkonw` | 未知，保留舊文件拼寫 |

`openerSource` 常見值：

| 值 | 說明 |
| --- | --- |
| `roomToolbar` | 聊天室 toolbar 觸發 |
| `roomTitle` | 聊天室 title 下沉觸發 |
| `mainFrame` | 主框架觸發 |
| `objectTitle` | 物件聊天室點選物件下沉觸發 |
| `roomMenu` | 聊天室選單觸發 |
| `message` | 訊息選單觸發 |

`roomInfo` 欄位：

| 欄位 | 型別 | 說明 |
| --- | --- | --- |
| `roomName` | `string` | 聊天室顯示名稱 |
| `roomAvatar` | `string` | 聊天室頭像，Base64 格式；多人聊天室可能無效 |
| `roomMembers` | `string[]` | 聊天室成員 OpenId 陣列 |
| `roomOwnerId` | `string` | 服務號聊天室中代表客戶 OpenId，其他型別為空 |
| `serviceId` | `string` | 服務號聊天室對應服務號 ID |

`objectInfo` 欄位：

| 欄位 | 型別 | 說明 |
| --- | --- | --- |
| `businessCode` | `string` | 物件編碼 |
| `businessId` | `string` | 物件 ID |
| `name` | `string` | 物件名稱 |
| `description` | `string` | 物件描述 |
| `endTimestamp` | `string` | 系統記錄的預計結束時間戳 |
| `roomId` | `string` | 對應多人聊天室 ID |
| `businessManagerId` | `string` | 物件下達者 OpenId |
| `businessManagerImgSrc` | `string` | 下達者頭像，Base64 圖片格式 |
| `businessManagerName` | `string` | 下達者名稱 |
| `businessCustomerId` | `string` | 物件客戶 OpenId |
| `businessCustomerImgSrc` | `string` | 客戶頭像，Base64 圖片格式 |
| `businessCustomerName` | `string` | 客戶名稱 |
| `businessExecutorId` | `string` | 物件執行者 OpenId |
| `businessExecutorImgSrc` | `string` | 執行者頭像，Base64 圖片格式 |
| `businessExecutorName` | `string` | 執行者名稱 |

`userInfo` 在 `openerType` 為 `self`、`vistor`、`friend`、`serviceRoom` 時可能存在：

| 欄位 | 型別 | 說明 |
| --- | --- | --- |
| `openId` | `string` | 對應聊天室使用者 OpenId |
| `lastChannel` | `string` | 最後進線渠道關鍵字 |
| `userAvatar` | `string` | 對應使用者頭像，Base64 格式 |
| `alias` | `string` | 備註名 |
| `nickName` | `string` | 暱稱 |
| `tags` | `Object` | 個人標籤資料，舊文件標註為暫不支援 |

### 6.5 `getAiffItem(aiffKey)`

獲取指定 `aiffKey` 對應的 Aiff 資料。

```js
AiffJS.getAiffItem("some-aiff-key").then(function (res) {
  console.log(res);
});
```

引數：

| 引數 | 型別 | 必填 | 說明 |
| --- | --- | --- | --- |
| `aiffKey` | `string` | 是 | Aiff key |

返回值：`Promise<Object>`

未初始化時返回：

```json
{ "code": "Aiff.NotInit" }
```

常見返回欄位：

| 欄位 | 型別 | 說明 |
| --- | --- | --- |
| `code` | `string` | `Aiff.OK` 獲取成功；`Aiff.NotExist` 未找到對應 Aiff |
| `data.id` | `string` | Aiff ID |
| `data.name` | `string` | 應用名稱 |
| `data.title` | `string` | 應用 title |
| `data.aiffKey` | `string` | 應用 key |

## 7. 聊天室與使用者介面

### 7.1 `getRoomStatus(roomId = "")`

獲取聊天室服務狀態。舊文件說明該介面主要對客戶聊天室生效。

```js
AiffJS.getRoomStatus().then(function (res) {
  console.log(res);
});
```

引數：

| 引數 | 型別 | 必填 | 預設值 | 說明 |
| --- | --- | --- | --- | --- |
| `roomId` | `string` | 否 | `""` | 聊天室 ID；為空時由宿主按當前上下文處理 |

返回值：`Promise<Object>`

未初始化時返回：

```json
{ "code": "Aiff.NotInit" }
```

常見返回欄位：

| 欄位 | 型別 | 說明 |
| --- | --- | --- |
| `code` | `string` | `Aiff.OK` 獲取成功；`Aiff.NotSupport` 當前聊天室型別不支援；`Aiff.NotInit` 未初始化 |
| `data.status` | `string` | 服務狀態，例如 `online`、`offline`、`timeout` |
| `data.channel` | `string` | 當前進線渠道標識 |
| `data.channelList` | `string[]` | 當前進線客戶的渠道列表 |

### 7.2 `openChat(roomId)`

開啟指定聊天室。

```js
AiffJS.openChat(roomId).then(function (res) {
  if (res && res.code === "Aiff.OK") {
    console.log("opened");
  }
});
```

引數：

| 引數 | 型別 | 必填 | 說明 |
| --- | --- | --- | --- |
| `roomId` | `string` | 是 | 聊天室 ID |

返回值：`Promise<Object | null>`

| 狀態 | 返回 |
| --- | --- |
| 已初始化 | 宿主 `openRoom` 回撥資料 |
| 未初始化 | `null` |

常見 `code`：

| code | 說明 |
| --- | --- |
| `Aiff.OK` | 開啟成功 |
| `Aiff.NotExistUser` | 未找到對應使用者 |
| `Aiff.NotInit` | 未初始化 |

### 7.3 `openUserChat(openId)`（取決於宿主同事聊天室能力）

開啟指定同事的聊天室。

```js
AiffJS.openUserChat(openId).then(function (res) {
  console.log(res);
});
```

引數：

| 引數 | 型別 | 必填 | 說明 |
| --- | --- | --- | --- |
| `openId` | `string` | 是 | 同事 OpenId |

返回值：`Promise<Object | null>`

| 狀態 | 返回 |
| --- | --- |
| 已初始化 | 宿主 `openUserRoom` 回撥資料 |
| 未初始化 | `null` |

### 7.4 `getUserRooms(openId)`

獲取指定同事的關聯聊天室列表。

```js
AiffJS.getUserRooms(openId).then(function (res) {
  console.log(res);
});
```

引數：

| 引數 | 型別 | 必填 | 說明 |
| --- | --- | --- | --- |
| `openId` | `string` | 是 | 同事 OpenId |

返回值：`Promise<Object | null>`

| 狀態 | 返回 |
| --- | --- |
| 已初始化 | 宿主 `getUserRooms` 回撥資料 |
| 未初始化 | `null` |

### 7.5 `getAllRooms()`

獲取聊天室列表。

```js
AiffJS.getAllRooms().then(function (res) {
  console.log(res);
});
```

返回值：`Promise<Object | null>`

| 狀態 | 返回 |
| --- | --- |
| 已初始化 | 宿主 `getAllRooms` 回撥資料 |
| 未初始化 | `null` |

### 7.6 `openContactChat(serviceNumberId, openId)`

開啟指定服務號下某個客戶的聊天室。

```js
AiffJS.openContactChat(serviceNumberId, openId).then(function (res) {
  console.log(res);
});
```

引數：

| 引數 | 型別 | 必填 | 說明 |
| --- | --- | --- | --- |
| `serviceNumberId` | `string` | 是 | 服務號 ID |
| `openId` | `string` | 是 | 客戶 OpenId |

返回值：`Promise<Object | null>`

當前原始碼行為：

| 狀態 | 返回 |
| --- | --- |
| 已初始化 | 呼叫宿主 `openContactChat(serviceNumberId, openId)` 後立即返回 `{ "code": "Aiff.OK" }` |
| 未初始化 | `null` |

說明：當前封裝不會等待宿主回撥結果。

### 7.7 `openBossContactChat(openId)`

開啟當前使用者主管號下的客戶聊天室。舊文件說明：根據 `openId` 查詢當前主管號下的使用者並開啟對應聊天室；若該主管號不存在該客戶，則開啟該客戶主頁；若查無客戶則由宿主提示。

```js
AiffJS.openBossContactChat(openId).then(function (res) {
  console.log(res);
});
```

引數：

| 引數 | 型別 | 必填 | 說明 |
| --- | --- | --- | --- |
| `openId` | `string` | 是 | 客戶 OpenId |

返回值：`Promise<Object | null>`

當前原始碼行為：

| 狀態 | 返回 |
| --- | --- |
| 已初始化 | 呼叫宿主 `openContactChat(openId)` 後立即返回 `{ "code": "Aiff.OK" }` |
| 未初始化 | `null` |

### 7.8 `getUser(openId, type = "")`

獲取 OpenId 對應使用者資料。

```js
AiffJS.getUser(openId).then(function (res) {
  console.log(res);
});
```

引數：

| 引數 | 型別 | 必填 | 預設值 | 說明 |
| --- | --- | --- | --- | --- |
| `openId` | `string` | 是 | - | 使用者 OpenId |
| `type` | `string` | 否 | `""` | 傳給宿主的型別引數 |

返回值：`Promise<Object>`

未初始化時返回：

```json
{ "code": "Aiff.NotInit" }
```

常見返回欄位：

| 欄位 | 型別 | 說明 |
| --- | --- | --- |
| `code` | `string` | `Aiff.OK` 獲取成功；`Aiff.NotExistUser` 未找到對應使用者；`Aiff.NotInit` 未初始化 |
| `data.openId` | `string` | 使用者 OpenId |
| `data.nickName` | `string` | 使用者暱稱 |
| `data.alias` | `string` | 使用者別名 |
| `data.userType` | `string` | `contact` 客戶，`employee` 員工 |
| `data.image` | `string` | 使用者頭像，Base64 格式 |

### 7.9 `getAvatar(openId, type = "")`

獲取 OpenId 對應使用者的頭像資料。舊文件說明：頭像資料通常來自客戶端快取。

```js
AiffJS.getAvatar(openId).then(function (res) {
  console.log(res);
});
```

引數：

| 引數 | 型別 | 必填 | 預設值 | 說明 |
| --- | --- | --- | --- | --- |
| `openId` | `string` | 是 | - | 使用者 OpenId |
| `type` | `string` | 否 | `""` | 傳給宿主的型別引數 |

返回值：`Promise<Object>`

未初始化時返回：

```json
{ "code": "Aiff.NotInit" }
```

常見返回欄位：

| 欄位 | 型別 | 說明 |
| --- | --- | --- |
| `code` | `string` | `Aiff.OK` 獲取成功；`Aiff.NotExistUser` 未找到對應使用者；`Aiff.NotInit` 未初始化 |
| `data.image` | `string` | 頭像資料，Base64 格式 |

## 8. 訊息與分享介面

### 8.1 `sendMessage(msgObj, type)`

傳送訊息到當前來源聊天室。

```js
AiffJS.sendMessage("hello", "text");

AiffJS.sendMessage(JSON.stringify(templateObj), "template");
```

引數：

| 引數 | 型別 | 必填 | 說明 |
| --- | --- | --- | --- |
| `msgObj` | `string \| Object` | 是 | 訊息內容 |
| `type` | `string` | 是 | 訊息型別，舊文件列出 `text` 與 `template` |

返回值：

| 狀態 | 返回 |
| --- | --- |
| 已初始化 | 宿主 `sendMessage(msgObj, type)` 返回值 |
| 未初始化 | `null` |

### 8.2 `selectMessage(msgObj)`

將訊息內容傳遞到聊天室輸入框中，等待使用者傳送。

```js
AiffJS.selectMessage("hello");
```

引數：

| 引數 | 型別 | 必填 | 說明 |
| --- | --- | --- | --- |
| `msgObj` | `string` | 是 | 訊息內容，舊文件說明僅支援文字 |

返回值：

| 狀態 | 返回 |
| --- | --- |
| 已初始化且不在 iframe | 宿主 `selectMessage(msgObj)` 返回值 |
| 已初始化但在 iframe | `null` |
| 未初始化 | `null` |

### 8.3 `shareTargetPicker(templateObj, type)`

開啟宿主選擇介面，選擇聊天室或同事後分享一則模板訊息。

```js
AiffJS.shareTargetPicker(templateObj, "all").then(function (res) {
  console.log(res);
});
```

引數：

| 引數 | 型別 | 必填 | 說明 |
| --- | --- | --- | --- |
| `templateObj` | `Object \| string` | 是 | 模板訊息 |
| `type` | `string` | 否 | 選擇範圍。舊文件示例為 `all` |

返回值：`Promise<Object>`

未初始化時返回：

```json
{ "code": "Aiff.NotInit" }
```

常見 `code`：

| code | 說明 |
| --- | --- |
| `Aiff.OK` | 分享成功 |
| `Aiff.NotExistUser` | 未找到對應使用者 |
| `Aiff.NotInit` | 未初始化 |

### 8.4 `shareMessage(message)`

使用宿主分享能力分享一段文字。

```js
AiffJS.shareMessage("您的邀请码为：xxx").then(function (res) {
  console.log(res);
});
```

引數：

| 引數 | 型別 | 必填 | 說明 |
| --- | --- | --- | --- |
| `message` | `string` | 是 | 要分享的文字 |

返回值：`Promise<Object>`

未初始化時返回：

```json
{ "code": "Aiff.NotInit" }
```

### 8.5 `sendCmd(cmd)`

向宿主傳送命令。

```js
AiffJS.sendCmd({
  action: "active",
  data: {}
}).then(function (res) {
  console.log(res);
});
```

引數：

| 引數 | 型別 | 必填 | 說明 |
| --- | --- | --- | --- |
| `cmd` | `Object` | 是 | 命令物件，具體格式由業務和宿主約定 |

返回值：`Promise<Object>`

未初始化時返回：

```json
{ "code": "Aiff.NotInit" }
```

### 8.6 `sendData(data)`

向宿主傳送擴充套件資料。

```js
AiffJS.sendData({
  action: "setCallState",
  args: {
    state: "oncall"
  }
});
```

引數：

| 引數 | 型別 | 必填 | 說明 |
| --- | --- | --- | --- |
| `data` | `Object` | 是 | 擴充套件資料，具體格式由業務和宿主約定 |

返回值：無穩定返回值。

當前原始碼實現注意：

- 初始化成功且宿主存在 `sendData` 方法時，會呼叫 `AiffJS.aileAPI.sendData(data)`。
- 未初始化或宿主未實現 `sendData` 時，原始碼會引用未在當前作用域定義的 `res`。呼叫方不應依賴該分支返回值。

## 9. 視窗、導航與標題

### 9.1 `openWindow(args)`

開啟 URL。

```js
AiffJS.openWindow({
  url: "https://www.example.com",
  external: false
});
```

引數：

| 引數 | 型別 | 必填 | 說明 |
| --- | --- | --- | --- |
| `args.url` | `string` | 是 | 要開啟的 URL |
| `args.external` | `boolean` | 否 | `false` 表示用 Aiff 方式開啟；`true` 表示使用系統預設瀏覽器開啟 |

返回值：

| 狀態 | 返回 |
| --- | --- |
| 已初始化 | 宿主 `openWindow(args)` 返回值 |
| 未初始化 | `null` |

### 9.2 `closeWindow()`

關閉當前 Aiff 頁面。

```js
AiffJS.closeWindow();
```

返回值：

| 狀態 | 返回 |
| --- | --- |
| 已初始化 | 呼叫宿主 `closeAiff()` 後返回 `true` |
| 未初始化 | `null` |

### 9.3 `changeAiffTitle(title)`

修改當前 Aiff 會話標題。

```js
AiffJS.changeAiffTitle("新的标题").then(function (res) {
  console.log(res);
});
```

引數：

| 引數 | 型別 | 必填 | 說明 |
| --- | --- | --- | --- |
| `title` | `string` | 是 | 新標題 |

返回值：`Promise<Object>` 或宿主方法返回值。

當前原始碼呼叫順序：

1. 若已初始化且 `AiffJS.aileAPI.changeAiffTitle` 是函式，直接呼叫該方法並返回其結果。
2. 否則若 `window.AileAPI.request` 是函式，呼叫 `request("changeAiffTitle", { title })`。
3. 若宿主不支援，返回 `{ code: "Aiff.NotSupport" }`。
4. 未初始化時返回 `Promise.resolve({ code: "Aiff.NotInit" })`。

### 9.4 `changeAiffTilte(title)`

歷史拼寫相容介面，建議新程式碼使用 `changeAiffTitle`。

```js
AiffJS.changeAiffTilte("新的标题").then(function (res) {
  console.log(res);
});
```

當前原始碼呼叫順序：

1. 若已初始化且 `AiffJS.aileAPI.changeAiffTilte` 是函式，直接呼叫歷史拼寫方法。
2. 否則若 `AiffJS.aileAPI.changeAiffTitle` 是函式，呼叫標準拼寫方法。
3. 否則若 `window.AileAPI.request` 是函式，先呼叫 `request("changeAiffTilte", { title })`；若失敗，再嘗試 `request("changeAiffTitle", { title })`。
4. 若宿主不支援，返回 `{ code: "Aiff.NotSupport" }`。
5. 未初始化時返回 `Promise.resolve({ code: "Aiff.NotInit" })`。

### 9.5 `navigateToTab(mainAiffId, args = null)`

跳轉並開啟主框架中的內嵌 Aiff 應用。

```js  
AiffJS.navigateToTab("179f5470-fff0-00d9-21fb-000c29cfe318", {
  data: 1234567
});
```

引數：

| 引數 | 型別 | 必填 | 預設值 | 說明 |
| --- | --- | --- | --- | --- |
| `mainAiffId` | `string` | 是 | - | 要開啟的 Aiff 專案 ID |
| `args` | `Object` | 否 | `null` | 要傳給被開啟頁面的資料 |

返回值：無。

被開啟頁面可透過瀏覽器 `message` 事件接收資料：

```js
window.addEventListener("message", function (event) {
  console.log(event.data);
});
```

訊息格式：

```json
{
  "action": "aiffCall",
  "args": {}
}
```

當前原始碼實現注意：未初始化分支會引用未在當前作用域定義的 `res`。呼叫方應在初始化成功後再呼叫。

## 10. 裝置能力與事件控制

### 10.1 `scanCode()`

啟動掃碼器並取得結果。

```js
AiffJS.scanCode().then(function (res) {
  console.log(res);
});
```

返回值：`Promise<Object>`

未初始化時返回：

```json
{ "code": "Aiff.NotInit" }
```

舊文件說明：掃碼成功後返回識別結果；若取消或失敗，返回空值。當前原始碼會透傳宿主回撥資料。

### 10.2 `getCurrentPosition()`

獲取當前地理位置。

```js
AiffJS.getCurrentPosition().then(function (res) {
  console.log(res);
});
```

返回值：`Promise<Object>`

未初始化時返回：

```json
{ "code": "Aiff.NotInit" }
```

常見返回資料：

```json
{
  "longitude": 103.333,
  "latitude": 33.222
}
```

欄位：

| 欄位 | 型別 | 說明 |
| --- | --- | --- |
| `longitude` | `number` | 經度 |
| `latitude` | `number` | 緯度 |

### 10.3 `subscribeCurrentPosition()`

訂閱當前位置變化。

```js
const subscription = AiffJS.subscribeCurrentPosition();

subscription.subscribe({
  next: function (data) {
    console.log("position changed", data);
  },
  complete: function () {
    console.log("position complete");
  }
});
```

返回值：簡易 `Observable` 物件。

物件結構：

```js
{
  subscribe: function (observer) {}
}
```

`observer` 引數：

| 欄位 | 型別 | 必填 | 說明 |
| --- | --- | --- | --- |
| `next` | `Function` | 是 | 收到位置變化資料時呼叫 |
| `complete` | `Function` | 是 | 宿主通知訂閱結束時呼叫 |

當前原始碼事件：

| 監聽事件 | 行為 |
| --- | --- |
| `CurrentPositionChanged` + 隨機 key | 呼叫 `observer.next(data)` |
| `CurrentPositionComplete` + 隨機 key | 呼叫 `observer.complete()` |

未初始化時會依次呼叫：

```js
observer.next({ code: "Aiff.NotInit" });
observer.complete();
```

### 10.4 `startEvent(eventName)`

通知宿主啟動指定事件。

```js
AiffJS.startEvent("eventName");
```

引數：

| 引數 | 型別 | 必填 | 說明 |
| --- | --- | --- | --- |
| `eventName` | `string` | 是 | 事件名稱 |

當前原始碼行為：

- 已初始化時生成隨機 key，監聽 `startEvent` + key，並呼叫宿主 `startEvent(eventName, key)`。
- 當前方法沒有返回 `Promise` 或 `Observable`。
- 回撥中引用了未在當前作用域定義的 `res`。
- 未初始化分支引用了未在當前作用域定義的 `observer`。

呼叫方應將該介面視為通知型介面，不依賴返回值。

### 10.5 `stopEvent(eventName)`

通知宿主停止指定事件。

```js
AiffJS.stopEvent("eventName");
```

引數：

| 引數 | 型別 | 必填 | 說明 |
| --- | --- | --- | --- |
| `eventName` | `string` | 是 | 事件名稱 |

當前原始碼行為：

- 已初始化時生成隨機 key，監聽 `stopEvent` + key，並呼叫宿主 `stopEvent(eventName, key)`。
- 當前方法沒有返回 `Promise` 或 `Observable`。
- 回撥中引用了未在當前作用域定義的 `res`。
- 未初始化分支引用了未在當前作用域定義的 `observer`。

呼叫方應將該介面視為通知型介面，不依賴返回值。

## 11. Aiff 狀態顯示

### 11.1 `sendAiffState(ibState)`

設定當前 Aiff 圖示的紅點狀態。

```js
AiffJS.sendAiffState(true);
```

引數：

| 引數 | 型別 | 必填 | 說明 |
| --- | --- | --- | --- |
| `ibState` | `boolean` | 是 | `true` 顯示紅點，`false` 取消紅點 |

返回值：

| 狀態 | 返回 |
| --- | --- |
| 已初始化 | 宿主 `sendState(ibState)` 返回值 |
| 未初始化 | `null` |

### 11.2 `sendAiffStateNumber(iNumber)`

設定當前 Aiff 圖示的未讀數字。

```js
AiffJS.sendAiffStateNumber(10);
```

引數：

| 引數 | 型別 | 必填 | 說明 |
| --- | --- | --- | --- |
| `iNumber` | `number` | 是 | 未讀數字 |

返回值：

| 狀態 | 返回 |
| --- | --- |
| 已初始化 | 宿主 `sendNumber(iNumber)` 返回值 |
| 未初始化 | `null` |

## 12. 原生資訊介面

### 12.1 `getNative()`

獲取宿主原生資訊。

```js
AiffJS.getNative().then(function (res) {
  console.log(res);
});
```

返回值：`Promise<Object | null>`

| 狀態 | 返回 |
| --- | --- |
| 已初始化且宿主實現 `getNative` | 宿主 `getNative` 回撥資料 |
| 已初始化但宿主未實現 `getNative` | `null` |
| 未初始化 | `null` |

## 13. 事件回撥

### 13.1 `onCloseWindow(cancelFun)`

宿主要求關閉 Aiff 頁面時觸發。

預設實現：

```js
AiffJS.onCloseWindow = function (cancelFun) {
  cancelFun(false);
};
```

業務可覆寫：

```js
AiffJS.onCloseWindow = function (cancelFun) {
  cancelFun(true);

  if (window.confirm("Aiff Close?")) {
    AiffJS.closeWindow();
  }
};
```

引數：

| 引數 | 型別 | 說明 |
| --- | --- | --- |
| `cancelFun` | `Function` | 關閉控制回撥 |

`cancelFun(cancel)` 引數：

| 值 | 說明 |
| --- | --- |
| `true` | 阻止宿主立即關閉 Aiff 頁面 |
| `false` | 不阻止關閉 |

舊文件說明：該事件需要在 Aiff 設定中勾選“頁面控制 Aiff 關閉”後生效。

### 13.2 `onAiffEvent(args)`

宿主主動通知 Aiff 頁面時觸發。

```js
AiffJS.onAiffEvent = function (args) {
  console.log(args);
};
```

引數：

| 引數 | 型別 | 說明 |
| --- | --- | --- |
| `args` | `Object` | 宿主傳入的事件資料 |

常見格式：

```json
{
  "action": "active",
  "aiffId": "aiff-item-id",
  "args": {}
}
```

說明：`active` 表示側邊欄啟用 Aiff 時觸發。其他事件格式由業務和宿主約定。

## 14. Aiff 協議開啟規則

舊文件說明：Aile 客戶端可以透過以下 URL 形式開啟 Aiff 頁面：

```text
https://aiff.aile.com.tw/[aiffid]
https://aiff.aile.cloud/[aiffid]
```

流程：

1. 拆解 URL 中的 `[aiffId]`。
2. 獲取 Aiff 資料並確認是否存在對應設定。
3. 若不存在，由宿主提示。
4. 若存在，獲取對應 Endpoint URL，並以 Aiff 方式開啟。

協議開啟可以攜帶引數：

```text
https://aiff.aile.com.tw/[aiffid]?a=123&b=321
```

宿主開啟 Endpoint 時會附加 `aiff.query` 引數，內容為 URL 編碼後的 JSON 字串。

示例：

```text
AiffId: abcdef
EndpointURL: https://www.chainsea.com.tw/ecp.page
协议 URL: https://aiff.aile.com.tw/abcdef?a=123&b=321
实际打开: https://www.chainsea.com.tw/ecp.page?aiff.query=%7B%22a%22%3A123%2C%22b%22%3A321%7D
```

## 15. 內部輔助成員

以下成員存在於當前原始碼中，主要服務於 SDK 內部流程，不建議業務程式碼直接修改。

| 成員 | 型別 | 說明 |
| --- | --- | --- |
| `aileAPI` | `Object \| null` | 初始化成功後儲存 `window.AileAPI` 引用 |
| `_initSuccessed` | `boolean` | 初始化成功標記，當前原始碼保留該拼寫 |
| `_iniData` | `Object` | 儲存宿主初始化返回資料 |
| `_initEvent()` | `Function` | 註冊 `closeAiff` 與 `aiffEvent` 監聽，指令碼載入後會自動執行 |
| `_closeEvent(cancel)` | `Function` | `cancel` 為 `false` 時呼叫宿主 `closeAiff()` |
| `hasLog()` | `Function` | 當宿主存在 `isLog` 標記時返回該值，否則返回 `false` |
| `log(msg)` | `Function` | `hasLog()` 為 `true` 時輸出帶版本號的日誌 |

## 16. 常見返回碼

| code | 說明 |
| --- | --- |
| `Aiff.OK` | 操作成功 |
| `Aiff.NotInit` | 未初始化 |
| `Aiff.NotSupport` | 當前宿主不支援該能力 |
| `Aiff.NotExistUser` | 未找到對應使用者 |
| `Aiff.NotExist` | 未找到對應 Aiff |

## 17. 當前原始碼實現注意事項

以下說明來自 `aiff.js` 1.0.19 的實際實現：

- `openContactChat` 與 `openBossContactChat` 在已初始化時會立即返回 `{ code: "Aiff.OK" }`，不會等待宿主實際處理結果。
- `changeAiffTitle` 是標準拼寫；`changeAiffTilte` 是歷史拼寫相容介面。
- `selectMessage` 仍保留 iframe 判斷，在 iframe 中會直接返回 `null`。
- `startEvent`、`stopEvent` 當前沒有穩定返回值，且內部引用了未在當前作用域定義的變數；呼叫方不應依賴返回值。
- `navigateToTab`、`sendData` 的未初始化或宿主未實現分支也存在未定義變數引用；呼叫方應在初始化成功且宿主能力存在時呼叫。
- `getAllRooms`、`openChat`、`openUserChat`、`getUserRooms` 未初始化時返回 `Promise<null>`；而 `getRoomStatus`、`getAvatar`、`getUser`、`getAiffItem`、`scanCode`、`getCurrentPosition`、`shareMessage`、`sendCmd`、`shareTargetPicker` 未初始化時返回 `{ code: "Aiff.NotInit" }`。
