Aile 平臺整合(Integration)外部對接手冊
版本: v2.2
最後更新: 2026-06-26
適用對象: 第三方系統整合開發者
服務模組: aile-service-integration
程式碼分支: release
v2.2 保留 AIFF 寫入規格、
pictureUrl主資料與 setting 級圖片、訊息傳送、服務廣播與 Simulator 聯調說明。v2.2+ 變更摘要(2026-06-25 release):
- Breaking: OpenAPI 路徑重構 — 從
/integration/openapi/v1/<資源>改為/<資源>/v1/<動作>。- Breaking: 所有 OpenAPI 端點統一為 POST,不再支援 GET。
- Breaking: HMAC 簽名公式修正 —
integrationId + nonce + body(不含 method/path)。- Breaking: Authorization 頭字首從
HMAC-SHA256改為AILE。- 新增: AIFF 寫入介面(create/update/delete)。
- 新增: 訊息傳送介面(
POST /messages/v1/send)。- 新增: 群發廣播介面(
POST /messages/v1/broadcast/create)。- 修正: 事件資源域和事件型別列表(基於原始碼)。
目錄
- 概述
- 核心概念與模型
- 整合接入流程
- OpenAPI 安全機制(HMAC 簽名)
- 控制面 API(平臺管理端)
- OpenAPI(第三方呼叫 Aile)
- Webhook 事件推送(Aile → 第三方)
- 事件資源域與事件型別參考
- 接入實戰指南(第三方開發步驟)
- 參考實現:Simulator 模擬服務
- 常見問題與錯誤碼
1. 概述
Aile 平臺整合(Platform Integration)是一套標準化的第三方系統接入框架,允許外部 SaaS 平臺以租戶級別安裝 Aile 服務,並交換業務事件與資料。
1.1 架構全景
┌─────────────────────────────────────────────────┐
│ Aile 平臺 │
│ │
│ aile-service-integration │
│ ├── /integration/app/* 應用定義管理 │
│ ├── /integration/tenant/* 安裝生命週期管理 │
│ ├── /messages/* 訊息傳送 / 廣播 │
│ ├── /openapi/* 第三方 API(HMAC簽名)│
│ └── InternalEvent → Webhook → 第三方回撥 │
│ │
│ aile-service-tenant (事件釋出) │
│ └── InternalEventTrigger → 業務事件發布 │
└─────────────────────────────────────────────────┘
│ 控制面 (HTTP) │ OpenAPI (HMAC) │ Webhook (HMAC)
▼ ▼ ▼
┌─────────────────────────────────────────────────┐
│ 第三方整合平臺(你) │
│ ├── 安裝介面 (接收 Aile 安裝請求) │
│ ├── OpenAPI 呼叫 (查詢/傳送訊息/群發廣播) │
│ └── Webhook 接收 (接收 Aile 業務事件) │
└─────────────────────────────────────────────────┘
1.2 與舊版 TenantAppModel 的關係
注意: aile-service-job 模組中有一個舊的 TenantAppModel / TenantAppController 體系,以 /tenantapp、/webhook 為路徑字首。本手冊描述的是新的 Integration Platform 體系(基於 IntegrationAppModel / TenantIntegrationModel),路徑字首為 /integration/。新體系相較舊體繫有以下增強:
| 特性 | 舊 TenantAppModel | 新 Integration Platform |
|---|---|---|
| 應用定義 | 無全域性應用定義 | IntegrationApp(獨立於租戶) |
| 安裝生命週期 | 簡單 CRUD | 完整狀態機 Pending→Active→Suspended→Deleted |
| 金鑰管理 | 固定 secretKey | HMAC appSecret + rotate-secret |
| 事件訂閱 | webHookTypes | subscribedEvents(事件資源域粒度) |
| 第三方回撥 | 無 | install/update/rotateSecret/uninstall |
| OpenAPI 目錄 | 無 | catalog 端點自動發現 |
| 安全隔離 | 簽名+租戶繫結 | integrationId + body 一致性校驗 + nonce |
2. 核心概念與模型
2.1 IntegrationApp(平臺應用定義)
這是由 Aile 管理員建立的全域性應用註冊,描述一個第三方平臺的身份和能力。
{
"appId": "your-app-id", // 全域性唯一應用 ID
"appName": "Your Platform Name", // 應用名稱
"provider": "your-company", // 提供方
"supportedEvents": [ // 支援的事件資源域(*. 為通配)
"contact.*",
"service_number.*"
],
"authType": "HMAC_SHA256", // 鑑權型別
"secret": "platform-secret", // 平臺級金鑰(Aile 呼叫第三方時使用)
"installUrl": "https://your-platform.com/api/aile/install", // 第三方安裝 URL
"updateUrl": "https://your-platform.com/api/aile/update", // 第三方更新 URL
"rotateSecretUrl": "https://your-platform.com/api/aile/rotate", // 第三方輪換金鑰 URL
"uninstallUrl": "https://your-platform.com/api/aile/uninstall", // 第三方解除安裝 URL
"installAckMode": "Sync", // Sync(同步完成)或 Async(非同步受理)
"status": "Active" // Draft → Active → Suspended → Deleted
}
──→ 狀態機:
Draft → Active → Suspended → Active → Deleted
2.2 TenantIntegration(租戶安裝例項)
當一個 Aile 租戶安裝你的平臺應用時,會在 Aile 端建立一個安裝例項:
{
"integrationId": "ti_xxxxx", // 安裝例項唯一 ID(Aile 生成)
"appId": "your-app-id", // 關聯的應用 ID
"tenantId": "T001", // Aile 租戶 ID
"tenantType": "enterprise", // 租戶型別
"externalTenantId": "EXT-12345", // 第三方系統對應租戶 ID(由你指定)
"appSecret": "generated-secret", // 安裝級金鑰(用於 HMAC 簽名,由 Aile 生成)
"webhookUrl": "https://your-platform.com/webhook/events", // 事件接收地址
"subscribedEvents": [ // 實際訂閱的事件資源域
"contact.*",
"service_number.*"
],
"installAckMode": "Sync", // 受理模式
"status": "Active" // 安裝狀態
}
──→ 安裝狀態機:
Pending → Active → Suspended/Disabled → Active → Deleted
InstallFailed狀態表示安裝失敗。
2.3 租戶隔離模型
- 一個
IntegrationApp可以被多個租戶安裝(多個TenantIntegration) - 每個
TenantIntegration擁有獨立的appSecret和webhookUrl - OpenAPI 呼叫時,第三方只能訪問該安裝例項所屬租戶的資料
- 跨系統租戶對映透過
externalTenantId欄位管理(不存在獨立的 TenantMapping 模型)
3. 整合接入流程
3.1 整體流程圖
Step 0: Aile 管理員註冊 IntegrationApp(後臺操作)
│
Step 1: Aile 租戶發起安裝
POST /integration/tenant/system/v1/install
{ appId, tenantId, tenantType }
│
├── Aile 建立 TenantIntegration(狀態=Pending)
├── Aile 呼叫第三方 installUrl(傳遞 integrationId、appSecret 等)
│
Step 2: 第三方處理安裝
├── 驗證請求合法 性
├── 建立外部租戶關聯
├── 確認 webhookUrl 和 subscribedEvents
│
├── Sync 模式:直接返回 { status: "Active", externalTenantId, webhookUrl, subscribedEvents }
│ → Aile 更新狀態為 Active
│
└── Async 模式:先返回 { accepted: true, status: "Pending" }
→ 後續回撥 Aile
POST /integration/tenant/open/v1/install/callback
{ integrationId, status: "Active", externalTenantId, webhookUrl, subscribedEvents }
→ Aile 更新狀態為 Active
Step 3: 日常執行
├── 第三方呼叫 Aile OpenAPI(HMAC 簽名,查詢/同步資料)
└── Aile 推送業務事件到第三方 webhookUrl(HMAC 簽名)
Step 4: 解除安裝
POST /integration/tenant/system/v1/uninstall?integrationId=xxx
├── Aile 呼叫第三方 uninstallUrl
└── TenantIntegration 狀態 = Deleted
3.2 Aile 傳送給第三方的安裝請求
當租戶發起安裝後,Aile 會呼叫 IntegrationApp.installUrl,傳送的請求體:
{
"integrationId": "ti_xxxxx",
"appId": "your-app-id",
"tenantId": "T001",
"tenantType": "enterprise",
"operatorId": "emp_001",
"appSecret": "generated-secret-for-this-instance",
"installationCallbackUrl": "https://aile-api.com/integration/tenant/open/v1/install/callback",
"installAckMode": "Sync",
"subscribedEvents": ["contact.*", "service_number.*"]
}
3.3 第三方應返回的安裝響應
Sync 模式(installAckMode=Sync):
{
"status": "Active",
"externalTenantId": "EXT-12345",
"webhookUrl": "https://your-platform.com/webhook/events",
"subscribedEvents": ["contact.*", "service_number.*"]
}
Async 模式(installAckMode=Async):
{
"accepted": true,
"status": "Pending"
}
之後非同步回撥 Aile:
curl -X POST https://aile-api.com/integration/tenant/open/v1/install/callback \
-H "Content-Type: application/json" \
-d '{
"integrationId": "ti_xxxxx",
"status": "Active",
"externalTenantId": "EXT-12345",
"webhookUrl": "https://your-platform.com/webhook/events",
"subscribedEvents": ["contact.*", "service_number.*"]
}'
3.4 第三方更新 / 輪換金鑰 / 解除安裝介面
Aile 在以下場景會呼叫第三方對應 URL(定義在 IntegrationApp 中):
| 操作 | Aile 呼叫 | 傳遞引數 |
|---|---|---|
| 更新配置 | updateUrl | { integrationId, webhookUrl, subscribedEvents } |
| 輪換金鑰 | rotateSecretUrl | { integrationId, operatorId } |
| 解除安裝 | uninstallUrl | { integrationId } |
4. OpenAPI 安全機制(HMAC 簽名)
所有第三方呼叫 Aile OpenAPI 的請求都必須攜帶 HMAC 簽名。Aile 推送的 Webhook 事件也會使用相同簽名機制。
4.1 簽名演算法
演演算法: HMAC-SHA256
金鑰: appSecret(來自 TenantIntegration 安裝例項)
簽名內容: integrationId + nonce + requestBody
簽名結果: Base64( HMAC-SHA256(appSecret, 簽名內容) )
4.2 請求頭規範
| Header | 值 | 說明 |
|---|---|---|
Authorization | AILE {integrationId}:{signature} | 簽名身份與結果 |
X-Aile-Nonce | nonce_1718256000123 | 每次請求唯一的隨機字串 |
Content-Type | application/json | 請求體格式 |
4.3 簽名示例(Python)
import hmac
import hashlib
import base64
import time
import requests
def build_signature(integration_id: str, app_secret: str, nonce: str, body: str) -> str:
"""
計算 HMAC-SHA256 簽名。
簽名內容 = integrationId + nonce + body
"""
raw = integration_id + nonce + body
mac = hmac.new(
app_secret.encode('utf-8'),
raw.encode('utf-8'),
hashlib.sha256
)
return base64.b64encode(mac.digest()).decode('utf-8')
def build_auth_header(integration_id: str, signature: str) -> str:
return f"AILE {integration_id}:{signature}"
def call_aile_openapi(integration_id: str, app_secret: str,
method: str, path: str, body: dict = None) -> dict:
"""
呼叫 Aile OpenAPI。
path 格式: /tenants/v1/me
"""
base_url = "https://aile-api.com" # 替換為實際環境地址
body_str = json.dumps(body) if body else ""
nonce = f"nonce_{int(time.time() * 1000)}"
signature = build_signature(integration_id, app_secret, nonce, body_str)
authorization = build_auth_header(integration_id, signature)
response = requests.request(
method=method,
url=f"{base_url}{path}",
headers={
"Authorization": authorization,
"X-Aile-Nonce": nonce,
"Content-Type": "application/json"
},
data=body_str if body_str else None
)
return response.json()
4.4 簽名示例(JavaScript / Node.js)
import crypto from "crypto";
function buildSignature(integrationId, appSecret, nonce, bodyString) {
const raw = integrationId + nonce + (bodyString ?? "");
return crypto.createHmac("sha256", appSecret).update(raw).digest("base64");
}
function buildAuthHeader(integrationId, signature) {
return `AILE ${integrationId}:${signature}`;
}
async function callAileOpenApi(integrationId, appSecret, method, path, body) {
const bodyStr = body ? JSON.stringify(body) : "";
const nonce = `nonce_${Date.now()}`;
const signature = buildSignature(integrationId, appSecret, nonce, bodyStr);
const response = await fetch(`https://aile-api.com${path}`, {
method,
headers: {
"Authorization": buildAuthHeader(integrationId, signature),
"X-Aile-Nonce": nonce,
"Content-Type": "application/json"
},
body: bodyStr || undefined
});
return response.json();
}
4.5 簽名示例(Java)
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
public class AileHmacSigner {
public static String buildSignature(String integrationId, String appSecret,
String nonce, String body) {
String raw = integrationId + nonce + (body != null ? body : "");
try {
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(appSecret.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
return Base64.getEncoder().encodeToString(mac.doFinal(raw.getBytes(StandardCharsets.UTF_8)));
} catch (Exception e) {
throw new RuntimeException("HMAC signing failed", e);
}
}
public static String buildAuthHeader(String integrationId, String signature) {
return "AILE " + integrationId + ":" + signature;
}
}
4.6 簽名驗證流程(服務端)
Aile 服務端驗證流程:
- 過濾器攔截所有 OpenAPI 資源路徑(例如
/tenants/v1/me、/contacts/v1/list、/aiffs/v1/create) - 從
Authorization頭解析integrationId和requestSignature - 從請求體中解析
integrationId欄位,與簽名中的身份一致性校驗(防止冒用) - 根據
integrationId查詢TenantIntegrationModel,取得appSecret - 使用
appSecret對integrationId + nonce + body計算 HMAC-SHA256 - 使用
MessageDigest.isEqual()時間恆定比對簽名 - 校驗安裝例項狀態為
Active、所屬應用狀態為Active
5. 控制面 API(平臺管理端)
以下 API 供 Aile 內部管理面使用,第三方不需要呼叫這些介面。列於此處供理解完整流程。
5.1 IntegrationApp(應用定義)
| 方法 | 路徑 | 說明 |
|---|---|---|
POST | /integration/app/system/v1/create | 建立應用定義 |
POST | /integration/app/system/v1/update | 更新應用定義 |
GET | /integration/app/system/v1/detail?appId= | 查詢應用詳情 |
POST | /integration/app/system/v1/items | 分頁查詢應用列表 |
POST | /integration/app/system/v1/enable | 上架應用 |
POST | /integration/app/system/v1/disable | 下架應用 |
POST | /integration/app/system/v1/delete | 刪除應用 |
GET | /integration/app/system/v1/statistics/usage?appId= | 使用統計 |
5.2 TenantIntegration(安裝管理)
| 方法 | 路徑 | 說明 |
|---|---|---|
POST | /integration/tenant/system/v1/install | 發起安裝 |
POST | /integration/tenant/system/v1/update | 更新安裝配置 |
POST | /integration/tenant/system/v1/suspend?integrationId= | 暫停安裝 |
POST | /integration/tenant/system/v1/resume?integrationId= | 恢復安裝 |
POST | /integration/tenant/system/v1/uninstall?integrationId= | 解除安裝 |
POST | /integration/tenant/system/v1/rotate-secret?integrationId= | 輪換金鑰 |
GET | /integration/tenant/system/v1/detail?integrationId= | 查詢安裝詳情 |
GET | /integration/tenant/system/v1/items?tenantId= | 依租戶查詢列表 |
GET | /integration/tenant/system/v1/items/by-app?appId= | 依應用查詢列表 |
POST | /integration/tenant/open/v1/install/callback | 第三方安裝回撥(公開介面) |
5.3 安裝請求引數詳情
發起安裝:
{
"appId": "your-app-id", // 必填
"tenantId": "T001", // 必填
"tenantType": "enterprise" // 必填
}
安裝回撥(第三方 → Aile):
{
"integrationId": "ti_xxxxx", // 必填
"status": "Active", // 必填(Active 或 InstallFailed)
"externalTenantId": "EXT-12345", // 可選但不建議為空
"webhookUrl": "https://...", // 可選
"subscribedEvents": ["contact.*"], // 可選
"message": "安裝完成" // 可選
}
更新配置:
{
"integrationId": "ti_xxxxx",
"webhookUrl": "https://new-url.com/webhook",
"subscribedEvents": ["tenant.*", "contact.*"]
}
6. OpenAPI(第三方呼叫 Aile)
所有 OpenAPI 端點採用 /<資源>/v1/<動作> 路徑結構(例如 /contacts/v1/list),所有請求均為 POST 方法(含查詢請求),且必須攜帶 HMAC 簽名。舊版 /integration/openapi/v1/<資源> 路徑不再作為對外穩定契約。
6.1 通用請求格式
所有 OpenAPI 請求體都必須包含 integrationId:
{
"integrationId": "ti_xxxxx"
}
其餘欄位因 API 而異。詳見各端點說明。
6.2 通用響應格式
{
"code": 200,
"message": "success",
"data": { ... }
}
6.3 API 端點一覽
6.3.1 租戶資訊
| 方法 | 路徑 | 說明 |
|---|---|---|
POST | /tenants/v1/me | 查詢當前安裝例項的租戶資訊 |
請求:
{
"integrationId": "ti_xxxxx"
}
響應 data:
{
"tenantId": "T001",
"tenantName": "某某公司",
"tenantType": "enterprise",
"status": "Active"
}
6.3.2 服務號
| 方法 | 路徑 | 說明 |
|---|---|---|
POST | /service-numbers/v1/list | 查詢服務號列表 |
POST | /service-numbers/v1/detail | 查詢服務號詳情 |
POST | /service-numbers/v1/sync | 查詢服務號差異同步列表 |
列表請求:
{
"integrationId": "ti_xxxxx",
"current": 1,
"size": 20
}
詳情請求:
{
"integrationId": "ti_xxxxx",
"serviceNumberId": "SN001"
}
同步請求:
{
"integrationId": "ti_xxxxx"
}
6.3.3 員工
| 方法 | 路徑 | 說明 |
|---|---|---|
POST | /employees/v1/list | 查詢租戶員工列表 |
{
"integrationId": "ti_xxxxx",
"current": 1,
"size": 20
}
6.3.4 聯絡人(客戶)
| 方法 | 路徑 | 說明 |
|---|---|---|
POST | /contacts/v1/list | 查詢聯絡人列表 |
POST | /contacts/v1/detail | 查詢聯絡人詳情 |
POST | /contacts/v1/interactions | 查詢近期互動記錄 |
列表請求:
{
"integrationId": "ti_xxxxx",
"serviceNumberId": "SN001",
"current": 1,
"size": 20
}
詳情請求:
{
"integrationId": "ti_xxxxx",
"contactId": "C001",
"serviceNumberId": "SN001"
}
互動記錄請求:
{
"integrationId": "ti_xxxxx",
"serviceNumberId": "SN001",
"days": 30,
"current": 1,
"size": 20
}
6.3.5 群組(LineGroup)
| 方法 | 路徑 | 說明 |
|---|---|---|
POST | /groups/v1/list | 查詢群組列表 |
{
"integrationId": "ti_xxxxx",
"current": 1,
"size": 20
}
6.3.6 會話統計
| 方法 | 路徑 | 說明 |
|---|---|---|
POST | /sessions/v1/statistics | 查詢會話月統計 |
POST | /sessions/v1/statistics/detail | 查詢會話月統計詳情 |
{
"integrationId": "ti_xxxxx",
"serviceNumberId": "SN001",
"month": "2026-06"
}
6.3.7 AIFF 配置(應用內浮動框架)
v2.2 更新。 新增 create / update / delete 寫介面,支援主資料圖片 (
pictureUrl) 和 setting 級別配置。
| 方法 | 路徑 | 說明 |
|---|---|---|
POST | /aiffs/v1/list | 查詢 AIFF 列表(分頁) |
POST | /aiffs/v1/detail | 查詢 AIFF 詳情(含 settings) |
POST | /aiffs/v1/create | 建立 AIFF 主資料與設定 |
POST | /aiffs/v1/update | 更新 AIFF 主資料與設定 |
POST | /aiffs/v1/delete | 刪除 AIFF 主資料與全部設定 |
列表請求:
{
"integrationId": "ti_xxxxx"
}
詳情請求:
{
"integrationId": "ti_xxxxx",
"extraId": "your-app-id"
}
建立請求 OpenApiAiffCreateRequestDto:
| 欄位 | 型別 | 必填 | 說明 |
|---|---|---|---|
integrationId | String | ✅ | 租戶安裝例項 ID |
extraId | String | ✅ | 外部應用唯一識別(外部系統中的 AIFF ID) |
name | String | ✅ | AIFF 應用名稱 |
description | String | AIFF 應用描述 | |
pictureUrl | String | AIFF 主資料圖片地址,直接儲存外部傳入的 URL(不下載、不上傳) | |
settings | Object[] | 建立時同步寫入的 AIFF 設定列表(可選) |
更新請求 OpenApiAiffUpdateRequestDto:
| 欄位 | 型別 | 必填 | 說明 |
|---|---|---|---|
integrationId | String | ✅ | 租戶安裝例項 ID |
extraId | String | ✅ | 外部應用唯一識別 |
name | String | ✅ | AIFF 應用名稱 |
description | String | AIFF 應用描述 | |
pictureUrl | String | AIFF 主資料圖片地址 | |
settings | Object[] | 更新時同步維護的 AIFF 設定列表(可選) |
刪除請求:
{
"integrationId": "ti_xxxxx",
"extraId": "your-app-id"
}
刪除主資料時會連帶刪除該 AIFF 下的所有設定。
Setting 子結構 OpenApiAiffSettingRequestDto:
每個 setting 對應一組前端展示配置,可在建立/更新 AIFF 時一併提交。
| 欄位 | 型別 | 必填 | 說明 |
|---|---|---|---|
id | String | 既有設定 ID(更新既有設定時使用) | |
extraKey | String | 外部設定唯一識別 | |
displayName | String | 前端展示名稱 | |
pictureUrl | String | 設定級別圖片地址。未傳時查詢返回回退外層主資料 pictureUrl | |
serviceNumberIds | String[] | 設定生效的服務號 ID 列表 | |
displayType | String | 顯示型別,見下表 | |
roomType | String[] | 聊天室型別列表(僅 displayType=Room 時生效),見下表 | |
displayLocation | String | 嵌入位置(僅 displayType=Room 時生效),見下表 | |
endPointUrl | String | AIFF 跳轉目標地址 | |
supportDevice | String | 支援裝置型別,見下表 | |
popupSize | String | 彈窗尺寸,見下表 |
displayType 列舉值:
| 值 | 說明 |
|---|---|
Frame | 主框架 |
AppList | 應用列表 |
Room | 聊天室內嵌(此時需設定 roomType + displayLocation) |
ContactIndex | 客戶主頁 |
roomType 列舉值(可多選):
| 值 | 說明 |
|---|---|
One | 單人聊天室 |
Person | 個人聊天室 |
Friend | 好友聊天室 |
System | 系統聊天室 |
Discuss | 多人聊天室 |
Group | 社團聊天室 |
GroupOwner | 社團聊天室(擁有者) |
BusinessCustomer | 商務號聊天室(客戶角度) |
BusinessEmployee | 商務號聊天室(員工角度) |
BusinessSecretary | 商務號秘書群聊天室 |
ServiceNumberCustomer | 服務號聊天室(客戶角度) |
ServiceNumberEmployee | 服務號聊天室(員工角度) |
ServiceNumberAgent | 服務號聊天室(服務人員角度) |
ServiceNumberGroup | 服務號群內聊天室 |
Object | 物件聊天室 |
displayLocation 列舉值:
| 值 | 說明 |
|---|---|
Toolbar | 工具列 |
Extend | 擴充套件欄位 |
Embed | 下沉式(內嵌) |
MessageMenu | 訊息選單 |
supportDevice 列舉值:
| 值 | 說明 |
|---|---|
Desktop | 桌面端 |
Mobile | 手機端 |
popupSize 列舉值:
| 值 | 說明 |
|---|---|
Full | 全螢幕 |
Half | 半螢幕 |
詳情響應 data 結構 OpenApiAiffVO:
{
"id": "aiff-xxx",
"extraId": "your-app-id",
"tenantId": "T001",
"name": "外部應用名稱",
"description": "應用描述",
"pictureUrl": "https://example.com/image.png",
"settings": [
{
"id": "setting-001",
"extraId": "your-app-id",
"extraKey": "setting-key-1",
"displayName": "設定顯示名稱",
"pictureUrl": "https://example.com/setting-icon.png",
"endPointUrl": "https://example.com/aiff",
"serviceNumberIds": ["SN001", "SN002"],
"aiffId": "aiff-xxx"
}
]
}
重要說明:
- 圖片處理:
pictureUrl僅做字串透傳與儲存,不下載圖片、不上傳附件。setting 未傳pictureUrl時,寫入階段不自動補外層值,僅查詢返回時回退外層主資料圖片 - icon 檔案上傳:OpenAPI 僅承接結構化資料,不承接
icon檔案上傳(內部 job 服務的multipart/form-dataicon 欄位在 OpenAPI 鏈路中固定為空) - setting 定位:更新時依
extraKey定位既有 setting;若未傳可識別的標識,更新行為依賴既有業務約束 - 刪除級聯:刪除 AIFF 主資料時會一併刪除該
extraId下所有 setting
6.3.8 API 目錄(自動發現)
| 方法 | 路徑 | 說明 |
|---|---|---|
POST | /catalog/v1/business-objects | 查詢業務物件清單 |
POST | /catalog/v1/sync-resources | 查詢支援同步的資源清單 |
POST | /catalog/v1/event-types | 查詢支援的事件型別清單 |
POST | /catalog/v1/event-scopes | 查詢支援的事件資源域清單 |
所有目錄端點請求格式相同:
{
"integrationId": "ti_xxxxx"
}
6.3.9 傳送訊息
v2.1 新增功能。 供外部整合應用向指定聊天室傳送訊息。
| 方法 | 路徑 | 說明 |
|---|---|---|
POST | /messages/v1/send | 傳送訊息到指定聊天室 |
功能範圍:
- 當前穩定支援的訊息型別:
Text(文字訊息)、Template(模板訊息 / 卡片訊息) - 不支援
Image、File、Video、Audio、Voice、Sticker等需附件契約的型別(會返回請求非法) - 支援 5 種接收目標路由:
Room、System、User、ServiceNumber、ServiceMember - 支援 3 種傳送者身份:
System(系統訊息)、User(以使用者身份傳送)、ServiceNumber(以服務號身份傳送) - 可透過
sourceType控制單條訊息的顯示方式(System/User/Assistant)
請求 DTO 結構:
頂層請求 OpenApiMessageSendRequestDto:
| 欄位 | 型別 | 必填 | 說明 |
|---|---|---|---|
integrationId | String | ✅ | 租戶安裝例項 ID |
sender | Object | ✅ | 傳送者資料,見下表 |
to | Object | ✅ | 接收者資料,見下表 |
messages | Object[] | ✅ | 訊息列表(至少 1 條),見下表 |
傳送者 OpenApiMessageSenderDto:
| 欄位 | 型別 | 必填 | 說明 |
|---|---|---|---|
type | String | ✅ | 傳送者型別:System / User / ServiceNumber |
userType | String | 使用者型別:Employee / Contact(type=User 時使用,預設為 Employee) | |
code | String | openId 或服務號代號(type 非 System 時必填) | |
incoming | String | 進線標記(可選) |
接收者 OpenApiMessageReceiverDto:
| 欄位 | 型別 | 必填 | 說明 |
|---|---|---|---|
type | String | ✅ | 接收目標型別:Room / System / User / ServiceNumber / ServiceMember |
userType | String | 使用者型別:Employee / Contact / Visitor(type=User 時使用) | |
code | String | 接收者代號(openId 或 roomId) | |
serviceNumberId | String | 服務號 ID(type=ServiceNumber/ServiceMember 時使用) | |
channelType | String | 指定渠道:Line / Facebook / Webchat / Aiwow 等 |
單條訊息 OpenApiMessageItemDto:
| 欄位 | 型別 | 必填 | 說明 |
|---|---|---|---|
type | String | ✅ | 訊息型別:Text / Template |
altText | String | 替代文字(渠道不支援時的降級顯示) | |
sourceType | String | 訊息來源型別:User / System / Assistant / Broadcast。未傳時按 sender.type 推導:System→System,其餘→User | |
content | Object | ✅ | 訊息內容,見下表 |
訊息內容 OpenApiMessageContentDto:
| 欄位 | 型別 | 必填 | 說明 |
|---|---|---|---|
type | String | 模板型別(訊息為 Template 時使用):Buttons / Confirm / Process / Carousel | |
title | String | 標題 | |
text | String | ✅ | 文字內容(Text 訊息的主體;Template 訊息的內文) |
imageUrl | String | 圖片網址(Template 訊息使用) | |
orientation | String | 內容方向:Vertical(垂直)/ Horizontal(水平) | |
defaultAction | Object | 預設動 作(點選整張卡片的行為),結構:{ type, label, url } | |
actions | Object[] | 互動動作列表(按鈕等),每項結構同上 |
動作型別(defaultAction / actions[].type):
| 值 | 說明 |
|---|---|
Action | 前端本地行為 |
Postback | 提交到後端的回傳行為 |
Url | 前端開啟外部連結 |
Aiff | 前端開啟 Aiff 容器 |
響應格式:
{
"code": 200,
"message": "success",
"data": [
{
"id": "message-xxx",
"roomId": "room-001",
"tenantId": "T001",
"type": "Text",
"content": { "text": "Hello" },
"senderId": "U001",
"createdAt": "2026-06-23T10:30:00Z"
}
]
}
訊息路由規則說明:
傳送訊息時,系統根據 to.type 和 sender.type 的組合決定最終的目標聊天室:
| to.type | sender.type | 路由邏輯 |
|---|---|---|
Room | 任意 | 直接使用 to.code 作為 roomId |
System | 任意 | 透過 to.code(員工 openId)定位員工的系統聊天室 |
User | System | 以接收者 openId 定位其系統聊天室(系統通知場景) |
User | User(同一個 openId) | 查詢該使用者的個人聊天室 |
User | User(不同 openId) | 查詢傳送者的好友聊天室(非好友則報錯) |
User | ServiceNumber |