一:平台概述
二:应用类型说明
| 类型 | 说明 |
| 内部连接器 | 仅在企业内部使用,创建后实时上线无需审核 |
| 全网发布连接器 | 面向纷享销客全部用户,上线前需经过审核和测试 |
三:创建连接器


四:授权方式
- OAuth授权方式:
- 设置填写授权字段 (非必填,仅在OAuth2.0登录授权前需要额外参数时添加)
- 复制回调地址:将自动生成的集成平台授权回调地址添加到您的应用中
- 设置授权参数:一般为Client Key和 Client Secret
- 设置接口参数:配置授权接口需要的参数,Access Token换取和刷新参数等
- 账号授权测试 (模拟账户授权,测试是否可以调取成功)







其他授权方式
| 授权选择 | 授权机制 |
| OAuth2-AuthorizationCode | 三步授权流程:获取授权码 → 换取 Access Token → 使用 Refresh Token 自动刷新;支持 PKCE 自动处理,适用于需要用户登录授权的第三方平台 |
| OAuth2-ClientCredentials | 机器对机器授权,无需用户交互;平台直接使用 Client ID / Client Secret 获取 Token,并按过期时间重新申请 |
| APIKey | 通过 API Key 进行认证;可将 Key 注入到 Header、Query 参数,适用于 OpenAPI、Server API 等简单鉴权场景 |
| BasicAuth | HTTP Basic 认证;使用用户名 + 密码生成 Authorization Header 进行请求认证 |
| SessionAuth | 先调用登录接口获取 Session / Cookie,再携带 Session 信息访问后续接口;适用于传统 Web 系统或 Cookie 会话型接口 |
| DigestAuth | HTTP Digest 认证;基于服务端 challenge 机制完成摘要签名认证,适用于部分老系统或特定安全要求接口 |
| CustomAuth | 自定义认证;通过平台函数模式实现任意认证逻辑,可覆盖自定义签名、登录换票据、多步认证、混合认证等复杂场景 |
五:Trigger/Action类型







| 占位符 | 含义 | 取值说明 |
|---|---|---|
| path("['input_data']['pollingTimeArg']['startTime']") | 本次查询的时间窗口起点 | 毫秒时间戳(13 位数字)。取“上次拉到数据的时间”,没拉到过数据则往前回溯约 28 小时 |
| path("['input_data']['pollingTimeArg']['endTime']") | 本次查询的时间窗口终点 | 毫秒时间戳,即本次轮询的执行时刻 |
| path("['input_data']['pollingTimeArg']['limit']") | 每页条数 | 平台固定为 100,不需要你设置 |
| path("['input_data']['pollingTimeArg']['offset']") | 翻页偏移量 | 第一页从 0 开始,每翻一页自动 +100,框架持续翻页直到取完(单轮上限 100 万条) |
先搞懂:轮询时平台帮你做了什么
当你把一个连接器触发器配置成轮询触发(配置轮询间隔或 cron 表达式)后,平台的轮询框架每次执行时会自动算好一组查询参数,塞进一个叫 pollingTimeArg 的参数包里。你不需要自己填值,只需要在连接器的请求配置(URL、Query 参数、Header、请求体)里用占位符把它们“接”出来,传给目标系统的查询接口。
四个占位符的含义:
| 占位符 | 含义 | 取值说明 |
|---|---|---|
path("['input_data']['pollingTimeArg']['startTime']") |
本次查询的时间窗口起点 | 毫秒时间戳(13 位数字)。取“上次拉到数据的时间”,没拉到过数据则往前回溯约 28 小时 |
path("['input_data']['pollingTimeArg']['endTime']") |
本次查询的时间窗口终点 | 毫秒时间戳,即本次轮询的执行时刻 |
path("['input_data']['pollingTimeArg']['limit']") |
每页条数 | 平台固定为 100,不需要你设置 |
path("['input_data']['pollingTimeArg']['offset']") |
翻页偏移量 | 第一页从 0 开始,每翻一页自动 +100,框架持续翻页直到取完(单轮上限 100 万条) |
你只要按目标接口的要求,把这四个值摆到正确的位置就行——是放 Query 参数、放 Header 还是放 JSON 体,完全由目标接口决定。
四种典型写法(可直接抄)
写法 1:GET + Query 参数(最常用,推荐)
在“参数(Query Params)”列表里配置:
| 参数名 | 参数值 |
|---|---|
startTime |
path("['input_data']['pollingTimeArg']['startTime']") |
endTime |
path("['input_data']['pollingTimeArg']['endTime']") |
limit |
path("['input_data']['pollingTimeArg']['limit']") |
offset |
path("['input_data']['pollingTimeArg']['offset']") |
实际发出的请求等价于:
GET https://api.example.com/orders?startTime=1757337600000&endTime=1757341200000&limit=100&offset=0
写法 2:直接拼在 URL 里
https://api.example.com/orders?startTime=path("['input_data']['pollingTimeArg']['startTime']")&endTime=path("['input_data']['pollingTimeArg']['endTime']")&limit=path("['input_data']['pollingTimeArg']['limit']")&offset=path("['input_data']['pollingTimeArg']['offset']")
URL 里可以正常这样写,系统会把每个 path(...) 片段替换成实际值。
写法 3:POST + JSON 请求体(自动保持数字类型)
在“请求体(JSON)”里写 JSON 模板,path(...) 会作为 JSON 值被替换,类型不丢(时间戳和 limit/offset 保持为数字,不会变成带引号的字符串):
{
"query": {
"startTime": path("['input_data']['pollingTimeArg']['startTime']"),
"endTime": path("['input_data']['pollingTimeArg']['endTime']"),
"pageSize": path("['input_data']['pollingTimeArg']['limit']"),
"pageStart": path("['input_data']['pollingTimeArg']['offset']")
}
}
发送出去的真实请求体:
{"query":{"startTime":1757337600000,"endTime":1757341200000,"pageSize":100,"pageStart":0}}
写法 4:表单(form-urlencoded)请求体
在“请求体”键值对里配置,值填占位符,和写法 1 的参数表一样填即可。
几个容易踩的坑
-
时间单位是毫秒。如果目标接口要的是秒级时间戳,不能用 URL 直拼(URL 里只能做替换、不能做运算),要把参数放到 Query 参数或请求体的值里,用整条表达式做除法:
path("['input_data']['pollingTimeArg']['startTime']") / 1000或者目标接口要求格式化字符串时:
"查询时间:" + path("['input_data']['pollingTimeArg']['startTime']")只要这个“值”整体是一条合法表达式(且不是完整 URL),就支持运算和字符串拼接。
-
limit 不用也不能改,永远是 100。如果你的接口页大小写死,请在接口侧兼容 100。
-
调试模式的取值:在页面上点“调试”触发时,系统固定注入「过去 1 小时」窗口:
startTime = 当前时间-1小时、endTime = 当前时间、limit = 100、offset = 0,此时没有 conditions(见下文)。所以调试时引用 conditions 的占位符会得到空值,属正常现象。 -
参数名对不上接口没关系:占位符只负责取值,参数名叫
startTime、beginTime、pageSize还是别的,由你在参数名/JSON 字段名里自己定义。
conditions 自定义查询条件怎么用
“自定义查询条件”分两种完全不同的需求,配置方法也不一样,请对号入座:
需求 A:固定过滤条件(每次轮询都带上的筛选条件)
比如“只查已审核的订单”。这类条件不要用 pollingTimeArg,直接配置在触发器节点的输入参数里(固定值或表达式),然后在连接器请求配置中引用 input_data.<参数名>:
- 触发器输入参数里配置:
orderStatus= 固定值AUDITED - 连接器请求配置里引用:
path("['input_data']['orderStatus']")
如果筛选条件是一整个对象(由使用流程的用户填写),把输入参数定义成对象类型,可以整体引用并放进 JSON 体:
{
"queryFilter": path("['input_data']['queryFilter']"),
"startTime": path("['input_data']['pollingTimeArg']['startTime']"),
"endTime": path("['input_data']['pollingTimeArg']['endTime']")
}
queryFilter 会原样展开成嵌套 JSON 对象传给接口。
需求 B:游标式翻页(下一页要带上一页返回的“游标/条件”)
有些接口不是靠 offset 翻页,而是“本次响应里返回下一次查询要用的条件(如 nextCursor、scrollId)”。平台已经内置了这条自动接力通道,名字就叫 conditions:
工作流程(你只需做两件事):
-
让接口的响应能被正确解析——平台会从触发器查询接口的响应里找数据数组和条件,两种响应结构都支持:
- 结构一(推荐,最清晰):响应体直接返回标准结构,
dataItems是数据、conditions里放你下一页要用的任何字段:{ "dataItems": [ {"id": "1"}, {"id": "2"} ], "conditions": { "nextCursor": "abc123" } } - 结构二(普通业务响应,自动拆解):响应是
{code, msg, data:{list:[...], nextCursor}}这类结构时,平台自动把最浅层的对象数组(这里是data.list)当作数据,其余所有字段(去掉 list 后的code、msg、data.nextCursor……)整体作为 conditions。
- 结构一(推荐,最清晰):响应体直接返回标准结构,
-
在请求配置里引用下一页要用的字段:
- 响应用结构一时,引用路径为:
path("['input_data']['pollingTimeArg']['conditions']['nextCursor']") - 响应用结构二时,conditions 里保留了原始层级,路径要带全:
path("['input_data']['pollingTimeArg']['conditions']['data']['nextCursor']")
平台每拉完一页,就把上一页响应解析出的 conditions 自动注入下一页查询的
pollingTimeArg.conditions,你不用做任何额外配置。 - 响应用结构一时,引用路径为:
一个完整的游标分页触发器示例(POST + JSON 体):
{
"startTime": path("['input_data']['pollingTimeArg']['startTime']"),
"endTime": path("['input_data']['pollingTimeArg']['endTime']"),
"limit": path("['input_data']['pollingTimeArg']['limit']"),
"offset": path("['input_data']['pollingTimeArg']['offset']"),
"cursor": path("['input_data']['pollingTimeArg']['conditions']['nextCursor']")
}
配合约定响应:
{
"dataItems": [ ...本页数据... ],
"conditions": { "nextCursor": "平台会把这里原样带给下一页" }
}
第一页怎么办? 第一页(以及调试模式)没有 conditions,cursor 会被替换为 JSON 的 null(多数游标接口首次传 null 是合法的)。如果接口不接受 null 字段,在 HTTP 配置里打开“空值字段移除”(removeMissingValues,对 body/params 生效),第一页请求会自动丢掉这个字段。
两点边界要知道:
- conditions 是同一轮轮询内翻页的接力棒:本轮取完就结束,下一个轮询周期从新时间窗口的第一页重新开始(此时长期增量的起点由平台按“最后拉到数据的时间”自动推进,无需你配置)。
- 你也可以把固定筛选条件放进响应的 conditions 里返回,实现“首轮计算、后续每页复用”的动态条件——conditions 内容完全由你的接口决定,平台只负责透传。
['xxx']`,一个字符都不能差)
- 接口接受毫秒时间戳;要秒级时改用参数值表达式
/ 1000,而不是 URL 直拼 - 用了 conditions 时,响应结构符合约定,且引用路径与响应层级一致
- 先用“调试”跑一次(窗口=近 1 小时、limit=100、offset=0、无 conditions),确认请求和响应解析都正确,再启用正式轮询
一句话总结:startTime/endTime/limit/offset 是平台算好给你的“时间窗口 + 翻页坐标”,用 path("['input_data']['pollingTimeArg'][...]") 在请求配置任意位置取用(JSON 体里自动保数字类型);固定筛选条件配在触发器输入参数(input_data.<参数名>);游标式翻页则通过响应里的 conditions → 下一页 pollingTimeArg.conditions 的自动透传实现,路径多套一层 ['conditions'][...] 即可。
Action类型
六:字段说明:
| path("['auth_data']['access_token']") 集成平台用的表达式一定需要带有前缀path,后续就是具体参数路径 |






七:函数模式:



Map<String, Object> authData = (Map<String, Object>) syncArg.get("auth_data");
Map<String, Object> inputData = (Map<String, Object>) syncArg.get("input_data");
String tenantId = (String) syncArg.get("tenantId");
String connectorKey = (String) syncArg.get("connectorKey");
String operation = (String) syncArg.get("operation");
String connectionId = (String) syncArg.get("connectionId");
String type = (String) syncArg.get("type");
Map<String, Object> extra = (Map<String, Object>) syncArg.get("extra");
Map<String, Object> http = (Map<String, Object>) syncArg.get("http");函数返回值格式要求:
trigger返回格式要求,需要返回数据列表
字段说明:
dataItems:必须,触发出来的数据列表
privateKeys:推荐,去重主键字段
nameKeys:推荐,调试展示名称字段
conditions:推荐,下一次轮询继续查询用
return [
outputData: [
triggerOperation: "instant.created",
dataItems: [
[
id: "1",
event: "created",
name: "test order"
],
[
id: "2",
event: "created",
name: "test order 2"
]
],
privateKeys: ["id"],
nameKeys: ["name"],
conditions: [
nextCursor: "cursor_123"
]
]
]获取认证授权地址:
return [
outputData: [
authorizeUrl: "https://example.com/oauth/authorize?client_id=xxx&state=xxx&redirect_uri=xxx"
]
]
获取token
return [
outputData: [
access_token: "access_token_xxx",
refresh_token: "refresh_token_xxx",
token_type: "Bearer",
expires_in: 7200,
scope: "crm"
]
]刷新token
return [
outputData: [
access_token: "new_access_token_xxx",
refresh_token: "new_refresh_token_xxx",
token_type: "Bearer",
expires_in: 7200
]
]outputDatareturn [
outputData: [
id: "123",
name: "test",
status: "success"
]
]