一、自訂群組件UDF說明
自訂群組件簡稱 UDF(User-Defined Functions),取名於常用的資料開發平台所使用的使用者自訂函數。以下均以 UDF 代替自訂群組件。
UDF 接入分為配置和執行兩部分,配置用於介面管理、畫布配置組件,執行用於旅程執行過程中的回調(執行部分和 WebHook 相似)。
二、UDF配置接入文檔
為了與Quick Audience對接,您需要開發一個HTTP Server。注意是Post請求,請求逾時時間為10秒。Quick Audience發起的HTTP請求和接入方回執請求約定如下通用參數,為必傳項。
2.1 系統間的流轉介面圖

① 為“開發線下提供配置資訊”如下所示
② 為iframe頁面跳轉,跳轉到外部系統中
③ API 介面:通過令牌擷取使用者資訊;同時需要將結果返回給iframe頁面。
④ API 介面:通過令牌擷取標籤資訊;同時需要將結果返回給iframe頁面。
⑤ 前端提交資料到iframe嵌入頁面中的 API,由外部系統後台通過 ⑥ 提交資料到 QA
⑥ API 介面:將配置資訊提交到 QA,QA 根據選擇的標籤資訊進行流程執行
2.1.1 產品介面配置 UDF 組件資訊

欄位填寫限制:
欄位 | 限制 |
嵌入頁面地址 | 組件內需要iframe嵌入的連結地址,必須是合法的完整地址,包含使用的協議(如HTTP或HTTPS),建議使用HTTPS,提高資訊傳輸的安全性。 |
icon URL | 組件顯示icon,建議尺寸21 * 21px |
請求地址 | 要接受訊息推送的介面地址,必須是合法的完整地址,包含使用的協議(如HTTP或HTTPS),建議使用HTTPS,提高資訊傳輸的安全性。 |
回執設定 | 回執設定將以介面形式將營銷結果返回到QA,需要配置回執結果欄位,將在自動化營銷中可通過結果判斷基於回執結果分流。 |
AES密鑰 | AES密鑰長度可以為128、192或256位,對應字元為16、24、32位。 |
是否公開 | 是否公開開啟後,則當前組織下所有的空間都可以使用UDF組件; 是否公開關閉,則只能當前空間下可以使用UDF組件。 |
2.1.1.1 配置的原始 JSON 資訊
{
"name":"自訂群組件名稱",
"type":"marketing", //自訂群組件類別:當前只支援 marketing -> 營銷組件
"version":"版本號碼", // 預設 1.0
"endpoint":"自訂群組件目標網域名稱 以http或https開頭,如:http://demo.com/二級路徑 跳轉至 $endpoint/index.html",
"iconUrl":"icon地址",
"enable": true // true or false是否啟用
"accessKey":"組件鑒權accessKey",
"accessSecret":"組件鑒權accessSecret",
"metaData":{ // 中繼資料資訊,不通類型組件 metaData 格式不同
"allowIDType":"該組件支援使用者ID類型,如 mobile | email | idfa | imei等",
"encryptionMethod":"推送營銷訊息 密碼編譯演算法 null | encryptionMethod",
"sendParam":{
"batchSendUrl":"營銷任務推送地址 以http或httpss開頭,如 http://demo.com/send",
"batchLimit":100, //批量推送條數限制 1~1000, 預設100
"timeout": 10, //請求逾時時間(單位秒) 0 ~ 60, 預設10
"retryTimes":0, //失敗重試次數 0 ~ 3, 預設0
"retryPeriod":0, //重試時間間隔(單位秒) 0 ~ 3600, 預設 0
},
"callbackParam":{//營銷組件回執參數
"usableInHours": 3 * 24, //1 ~ 30 * 24,預設3 推送結果回執資料在多少天的時間內返回算有效,超過則丟棄
"clearInHours": 7 * 24, //1 ~ 365 * 24,預設 7 * 24 推送結果回執資料超過多少天后將被回收
"resultEnumList":[ //推送結果回執枚舉列表, 預設 success & fail
{
"code":"success",
"name":"成功"
},
{
"code":"fail",
"name":"失敗"
}
],
"extParams": {
"extParam1": "拓展參數列頭001", //在效果分析中展示的列名,拓展欄位01
"extParam2": "拓展參數列頭002", //在效果分析中展示的列名,拓展欄位02
"extParam3": "拓展參數列頭003" //在效果分析中展示的列名,拓展欄位03
}
}
}
}2.1.2 iframe 跳轉
需要外部系統提供一個 iframe 頁面,頁面連結在上一步配置的endpoint中填寫。
注意:會存在跨域問題,需要增加跨域支援,X-Frame-Options: allow-from https://example.com/
跳轉 URL
/endPoint?comeFrom=xxx&qaEndpoint=xxx&token=xxx
返回結果
{
"success":true,
"errorDesc":"錯誤資訊,可以為空白"
}2.1.3 API 介面:通過令牌擷取使用者資訊
API:/openapi/v3/account/query?token=xxx
傳回值:
{
"success": false,
"errorDesc": "",
"data": {
"organizationId":"組織 ID",
"organizationName":"組織名稱",
"userId":"使用者識別碼",
"nickName":"使用者暱稱",
},
"@comment": {
"success": "/**\n * 枚舉值:true | false\n */",
"errorDesc": "/**\n * 錯誤資訊描述\n */",
"data": "/**\n * 使用者資訊\n */"
}
}只有成功擷取到使用者資訊,才說明正常可用,如果未擷取到使用者資訊,渲染頁面時應該返回 token 失效錯誤資訊。
2.1.4 API 介面:儲存UDF選擇的人群、事件 id 等
API:/restapi/marketing/udf_component/genUdfComponentNode
入參:
{
"componentId": "1001",
"sourceId": "c1f5691dd5864479820c10c0089bece9 (這裡傳人群 id,事件 id)",
"sourceNodeId": "",
"nodeId": "83a2d328-030d-436a-b607-21da8ee2e34b",
"sourceType": 1 // 這裡傳類型,1是人群 2是事件
}傳回值:
{
"data": {
"nodeId": "83a2d328-030d-436a-b607-21da8ee2e34b",
"token": "zKBfv7flRQmhd+XP1l1uuKCjE6seEOq8l02cBFWWRr5xQoOUPxb3+tj+ZPctWDG4rM5vC2PMQLxG0Xw7Qw6TpsDfXSYFwD8kmTjpUOV4AjxQfZPfC5q0wPrEFhvgfjz9X1OKDu4V4p1oJnJcbt5nELidsVk6jxkbVwHEL8ezXcyXFRKbC+jVYxOwG5ElUhS0+hraAK5IiwR1XgZCarFgOGf5ZZo/Nacjrp5AP8HbF3tl4+thAjp8ZuMWTYXsBJbe"
},
"errorCode": null,
"errorDesc": null,
"exStack": null,
"opers": [],
"solution": null,
"success": true,
"traceId": "48d6e570-1918-47a4-83ee-27c3f32d3a99"
}2.1.5 API 介面:通過令牌擷取人群標籤列表/事件屬性列表 (依賴2.1.4)
API:/openapi/v3/udf_component/marketing/getNodeUsableLabels?token=xxx&nodeId=xxx&version=VERSION_2
傳回值:
[
{
"id": "標籤ID/屬性ID",
"name": "標籤名稱/屬性名稱"
}
]選擇的標籤/屬性會在最終外調三方系統的時候作為參數傳入。
2.1.6 前端提交資料到iframe嵌入頁面中的 API
該頁面參數由三方自行定義,最終執行時,由 QA 調用到三方後,三方自行執行。但需要將選中的 QA 標籤通過⑥的介面回傳給 QA。
2.1.7 提交 UDF 配置資訊(依賴2.1.5)
API:/openapi/v3/udf_component/marketing/saveOrUpdateNodeConfig?token=xxx
請求體:
{
"nodeId": "節點ID",
"nodeName": "節點名稱",
"labelIdList": [
"標籤ID.[name]",
"標籤ID.[name]"
]
}傳回值:無傳回值,判斷 HTTP 狀態200即可
三、UDF執行接入文檔
系統流轉圖如下所示

3.1 節點執行請求
為了與Quick Audience對接,您需要開發一個HTTP Server。注意是Post請求,請求逾時時間為10秒。Quick Audience發起的請求和接入方回執請求約定如下通用參數,為必傳項。
請求URL:{UDF配置的 sendParam.batchSendUrl }
請求Header資訊
Header資訊讀取後需要通過java.net.URLDecoder#decode(java.lang.String, java.lang.String),編碼為UTF-8。
v=4 // 固定參數,用於區分新老版本,新版本為4,老版本沒有這個欄位
請求體:
請求入參 | 備忘 | |||
參數 | 參數 | 類型 | 是否必須 | |
請求時間戳記 | time | Long | 是 | |
請求ID | requstId | String | 是 | |
組件ID | componentId | String | 是 | |
組件accessKey | accessKey | String | 是 | AES密鑰長度可以為128、192或256位,對應字元為16、24、32位。 |
訊息體密碼編譯演算法 | encryptionMethod | String | 否 | 預設不加密 null 目前僅支援AES 加密,加密和填充方式為:AES/ECB/PKCS5Padding |
簽名 | signature | String | 是 | time + componentId + accessKey + accessSecret 經過hmac 加密後 註:簽名演算法和 WebHook 一樣。 |
訊息體 | data | String | 是 | 經過encryptionMethod加密後訊息體:
|
請求體樣本:
{
"time": 0,
"requestId": "111",
"componentId": "111",
"accessKey": "111",
"signature": "111",
"encryptionMethod": [
"AES"
],
"data": "字串格式,詳細格式如下"
}
// data 的格式
{
"jobId": "",
"jobName": "",
"nodeId": "",
"nodeName": "",
"componentName": "",
"taskId": "",
"taskStartTimestamp": 0,
"nodeStartTimestamp": 0,
"data": {
"messageId": "",
"customerList": [
{
"customerId": "",
"featureMap": {
"回執欄位":"原樣帶回"
},
"idMappings": {
"mobile": "手機號碼",//舉例的ID類型,如果有其他類型也會一起下發
"qaid": "QA產生的QAID"
},
"labels": {},
"processInfo": {
"processInstanceId": "新版:旅程周期中,每個使用者的旅程執行個體ID",
"processInstanceStartTime": "新版:旅程周期中,每個使用者的旅程執行個體開始時間,時間戳記格式",
"processNodeInstanceId": "新版:旅程節點執行個體ID(每次不同)",
"processNodeInstanceStartTime": "新版:旅程周期中,每個使用者的旅程的節點執行個體開始時間,時間戳記格式",
"groupName":"nodeId:nodeName:groupResult(node.result),groupName(node.resultExt);nodeId:nodeName:groupResult(node.result),groupName(node.resultExt)",
"@comment":{
"groupName" : "節點id:節點名稱(介面配置的):分組結果(隨機分組的百分比數字,兩位小數):分組名稱(介面配置的);多個用分號隔開"
}
}
"@comment": {
"featureMap": "/**\n * 拓展欄位,非同步回執時下遊必須帶回\n */"
}
}
]
},
"activityId": "",
"activityName": "",
"subActivityId": "",
"subActivityName": "",
"processId": "",
"processName": "",
"processInstanceId": "",
"processInstanceName": "",
"processInstanceStartTime": "",
"processNodeId": "",
"processNodeName": "",
"processNodeInstanceId": "",
"processNodeInstanceStartTime": "",
"groupId": "",
"groupName": "",
"@comment": {
"activityId": "/**\n * 活動ID\n */",
"activityName": "/**\n * 活動名稱\n */",
"subActivityId": "/**\n * 子活動ID\n */",
"subActivityName": "/**\n * 子活動名稱\n */",
"processId": "/**\n * 旅程ID(自動化ID);活動ID\n */",
"processName": "/**\n * 旅程名稱(自動化名稱);活動名稱\n */",
"processInstanceId": "/**\n * 旅程執行個體ID;活動執行個體ID\n */",
"processInstanceName": "/**\n * 活動執行個體名稱(有執行個體的時間)\n */",
"processInstanceStartTime": "/**\n * 活動執行個體開始時間\n */",
"processNodeId": "/**\n * 活動節點ID\n */",
"processNodeName": "/**\n * 活動節點名稱\n */",
"processNodeInstanceId": "/**\n * 活動節點執行個體ID\n */",
"processNodeInstanceStartTime": "/**\n * 活動節點執行個體開始時間\n */",
"groupId": "/**\n * ABTest分組ID(暫未實現,為空白)\n */",
"groupName": "/**\n * ABTest分組名稱(暫未實現,為空白)\n */"
}
}傳回值:
{
"success": true,
"errorDesc": "錯誤資訊",
"customerList": [
{
"messageId": "訊息 ID",
"customerId": "客戶 ID",
"returnType": "回執結果,該結果和回執結果一樣,如果有則直接當做回執結果,如果不希望直接填寫回執結果,不要傳遞",
"returnMessage": "回執訊息,長度限制255,超過會自動截取掉"
}
]
}3.1.1 鑒權方式
簽名演算法
long sendTime = System.currentTimeMillis();
// 組件id
// 組件ak
// 組件sk
String sign = getSignatureByHmacSHA1(sendTime, componentModel.getComponentId(), componentModel.getAccessKey(), componentModel.getAccessSecret());
public static String getSignatureByHmacSHA1(long time, String prametersString, String accessKey, String accessSecret) {
String str = time + prametersString + accessKey;
return HmacUtils.hmacSha256Hex(accessSecret, str.replaceAll("\\s+", ""));
}
3.2回執上報
接入方執行營銷任務後,向Quick Audience上報回執,反饋營銷訊息的發送結果。
HTTP請求URL:
API:/restapi/marketing2/udfComponent/receiveCallback?
請求體:
{
"time": 0,
"componentId": "UDF組件ID",
"signature": "簽名",
"data": "加密後回執資訊,字串",
"@comment":{
"time":"回執時間戳記,毫秒"
}
}
// data的原始格式
{
"nodeId": "節點ID",
"taskId": "任務ID",
"customerList": [
{
"messageId": "訊息 ID",
"customerId": "客戶 ID",
"returnType": "回執結果",
"sendTimestamp": 0,
"featureMap": {
"請求參數": "原樣回傳回來"
}
"@comment": {
"messageId": "/**\n * 訊息ID,QA推送的時候 會帶上這個ID\n */",
"customerId": "/**\n * 使用者ID\n */",
"returnType": "/**\n * 回執結果\n */",
"sendTimestamp": "/**\n * 訊息推送時間\n */",
"featureMap": "發送請求時的參數,需要在回執時原樣帶回來"
},
"extParam1": "拓展參數001-自訂傳回值",
"extParam2": "拓展參數002-自訂傳回值",
"extParam3": "拓展參數003-自訂傳回值"
}
],
"@comment": {
"nodeId": "/**\n * 節點ID\n */",
"taskId": "/**\n * 任務ID\n */",
"customerList": "/**\n * 回執使用者/粉絲列表\n */"
}
}
傳回值:
{
"success": true,
"errorDesc": "",
"@comment": {
"success": "/**\n * 枚舉值:true | false\n */",
"errorDesc": "/**\n * 錯誤資訊描述\n */",
"data": "/**\n * 使用者資訊\n */"
}
}