关于 webhook-template-builder
webhook-template-builder 是用于编写和迭代 Lytics webhook 模板的技能,供配置外部 webhook 目标的用户使用。它根据目标 API 文档和用户资料模式起草模板、调用测试流程,并在保存后输出任务配置蓝图。
主要功能
- 01研究目标 API 的请求要求
- 02生成 js1、jsonnet 或 Handlebars 模板
- 03使用资料或合成数据测试模板
- 04保存模板并生成任务配置蓝图
适用场景
- 01为外部 API 创建 webhook 模板
- 02验证模板输出是否符合目标格式
- 03为事件触发或资料增强配置模板
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ lytics/ agent-skills --skill webhook-template-builder安装后在 Claude Code 中输入/webhook-template-builder确认已加载。
详细介绍
Webhook 模板构建器
用途
编写和迭代 Lytics webhook 模板——在服务器端将用户资料转换为任意外部 webhook 目标所需的正文格式。主要模式是 build:用户指定目标(例如“Qualtrics”)或粘贴文档 URL,技能会获取目标的 API 文档,推断所需的负载、请求头和身份验证模型,起草模板,针对 /v2/template/{id}/test 进行迭代,保存模板,并生成可直接使用的 webhook 作业蓝图。
该技能不会自行创建身份验证、连接或作业。模板保存后,它会交接给 connection-manager skill(身份验证)和 job-manager skill(作业)——与 integration-setup skill 遵循相同的编排边界。
支持以下两种 webhook 工作流:
webhook_triggers(默认):基于事件;在用户进入或退出细分时触发。webhook_enrichment(--workflow=enrichment):请求/响应模式;发送用户资料,并将响应写入流。
环境
需要经过身份验证的 API 访问权限。凭据解析方式请参阅 ../references/auth.md。
调用
list # GET /v2/template
get <id-or-name> # GET /v2/template/{id}
create <name> --type=js1|jsonnet|handlebars [--desired-format=<json-sample>] # POST /v2/template (raw body); desired_format required for /test
update <id-or-name> # PUT /v2/template/{id} (PUT, not POST -- API reference is wrong)
delete <id-or-name> # DELETE /v2/template/{id}
test <id-or-name> [--profile=<field>=<value> | --synthetic | --json=<file-or-paste>]
build <destination-name | docs-URL> [--workflow=trigger|enrichment]
draft <destination-name | docs-URL> # alias for build that stops before save
读取操作(list、get)会立即执行。写入操作(create、update、delete)以及 build 中的最终保存操作,均使用确认门控模式(../references/confirmation-gate.md)。
默认模板语言
默认使用 js1(JavaScript)。Lytics 的 js1 运行时要求入口点为 function template(data) { ... }(而不是某些外部文档中出现、但与该运行时不匹配的 transformData)。全局变量:ly_auth_config 和 ly_job_config(均为 JSON 字符串;请谨慎地对其执行 JSON.parse——参见步骤 5)。辅助函数:用于签名请求的 hmacSha256(message, key)。
未经确认不得切换语言
如果 js1 返回非确定性错误(例如 /test 返回 500 且响应正文为空),不要悄悄切换到 jsonnet。请先进行诊断:
- 确认模板已设置
desired_format(参见“探查说明”——这是/test返回 500 且响应正文为空最常见的原因)。 - 确认函数名称为
template,而非transformData。 - 使用同一账户中的现有 js1 模板测试
/test,以排除平台问题。
只有在向用户说明故障并获得明确批准后,才能切换到 jsonnet。切换需要重写整个模板正文,用户必须同意更改语言。
以下情况使用 jsonnet:
- 用户明确提出要求
- 目标需要使用在 jsonnet 中更容易实现的模板功能(大量使用
event.inSeg、event.segSlug等) - 确认 js1 运行时存在问题后,用户批准切换
基于调研的编写流程(build)
步骤 1:识别目标
解析用户的输入。可分为三种形式:
- 名称(“Qualtrics”、“Slack”)
- 文档 URL(“https://api.qualtrics.com/...”)
- 自由描述(“当用户进入细分 X 时,向 #alerts 发送 Slack 消息”)
如果输入的是纯名称,请使用 WebSearch 搜索 <destination> webhook events API reference,并在继续之前与用户确认排名最高的结果。
步骤 2:获取目标文档
使用 WebFetch 获取目标的 API 参考文档。提取以下信息:
- HTTP 方法和 URL 模式(注意路径参数)
- 必需的请求头(身份验证请求头格式、
Content-Type,以及可能存在的签名/HMAC 请求头) - 请求正文结构——完整的 JSON 示例、嵌套结构、必需字段与可选字段
- 身份验证模型(请求头中的 API 密钥、Bearer token、HMAC 签名正文、OAuth)
- 速率限制和不可重试的状态码(用于填写
do_not_retry_for_http_status)
如果文档页面需要付费访问或内容为空,请让用户粘贴相关部分。
步骤 3:拉取示例档案上下文
根据真实架构确认字段引用。任选其一:
- 通过
entity-lookup skill使用真实档案(用户提供身份字段和值) - 通过
schema-discovery skill使用合成档案(从GET /v2/schema/user/field构建测试数据)
用此步骤确认草稿中引用的 Lytics 字段名称确实存在。
步骤 4:展示推断出的载荷和标头
在起草代码前,先展示摘要,供用户更正:
Destination: Qualtrics XM Events API
Method: POST
URL pattern: https://{datacenter}.qualtrics.com/eventsubscriptions/{subscription}/events
Headers:
- X-API-TOKEN: <secret> -> needs auth provider
- Content-Type: application/json
Body shape:
{ "events": [ { "type": "...", "user": { "email": "..." }, "data": { ... } } ] }
Auth model: API key in X-API-TOKEN header
Non-retry status codes: 400, 401, 403, 404
指出所有需要用户提供的信息(数据中心、订阅 ID、密钥值)。
步骤 5:起草模板
使用运行时要求的入口函数 function template(data) { ... } 生成 js1 源代码:
// Drafted by webhook-template-builder for <destination> on <YYYY-MM-DD>
function template(data) {
// Defensive: ly_auth_config / ly_job_config may be undefined globals at runtime
// (e.g., when /test is called with an empty job_config). Always guard with try/catch.
var auth = {};
var job = {};
try { if (typeof ly_auth_config === "string" && ly_auth_config) { auth = JSON.parse(ly_auth_config); } } catch (e) {}
try { if (typeof ly_job_config === "string" && ly_job_config) { job = JSON.parse(ly_job_config); } } catch (e) {}
return {
events: [
{
type: "user_segment_enter",
user: { email: data.email || "" },
data: {
first_name: data.first_name || "",
last_name: data.last_name || "",
ltv: data.ltv || 0
}
}
]
};
}
约定:
- 函数名必须是
template,而不是transformData。 如果缺少入口函数,Lytics js1 运行时会返回500和空响应体。平台上现有的 js1 模板始终使用template(data)。 - 对第 3 步确认存在的字段,使用
data.<field>引用。 - 默认值:字符串使用
|| "",数字使用|| 0,数组使用|| []。Webhook 目标很少能接受null。 - 始终使用
typeof === "string"检查和try/catch保护ly_auth_config和ly_job_config。 如果请求中对应的键为空或缺失,/test端点不会传入这些全局变量;若不加保护地使用JSON.parse(ly_job_config || "{}"),运行时将抛出ReferenceError。 - 如果目标会对请求签名,使用
hmacSha256(message, key)。 - 添加用于追踪的注释行。
向用户展示源代码。在内存中根据反馈迭代;此时不要写入 API。
步骤 6:/test 循环
/test 端点要求模板 ID 已存在,因此先保存草稿。草稿名称采用 _draft_<unix-ts>_<destination-slug> 格式,以便在 list 中轻松识别。创建时必须设置 desired_format——否则 /test 会返回 500 和空响应体。使用第 4 步推断出的响应结构(目标所需内容的示例);若无其他内容,可使用最简的 {}。
DRAFT_NAME="_draft_$(date +%s)_qualtrics"
# desired_format is a JSON sample of the destination payload; URL-encode it.
DESIRED_FORMAT=$(printf '%s' '{"firstName":"","lastName":"","email":"","embeddedData":{}}' \
| python3 -c "import sys,urllib.parse; print(urllib.parse.quote(sys.stdin.read()))")
# Save the draft
curl -s -X POST \
"${LYTICS_API_URL:-https://api.lytics.io}/v2/template?name=${DRAFT_NAME}&type=js1&description=Draft%20for%20${DESTINATION}&desired_format=${DESIRED_FORMAT}" \
-H "Authorization: ${LYTICS_API_TOKEN}" \
-H "Content-Type: text/plain" \
--data-binary @template.js
记录返回的 template_id。然后进行测试(参见下文的测试工作流)。收到反馈后,通过 PUT /v2/template/{id} 更新并重新测试。重复此过程,直到渲染输出符合要求。
告知用户 _draft_* 模板可能会显示在其 Lytics UI 列表中;它们将在第 7 步重命名。
步骤 7:保存(重命名)
测试通过后,提示用户提供最终名称和描述,然后运行 update 重命名草稿。写入前,通过确认关卡 (../references/confirmation-gate.md) 展示完整载荷。
步骤 8:输出作业蓝图并交接
打印完整的 webhook 作业配置载荷(参见下文的 Webhook 作业交接蓝图),其中包含:
- 已填入的
template_id - 推断出的值(第 4 步中的
headers、速率限制文档中的do_not_retry_for_http_status) - 其余字段使用占位符(
auth_ids: ["<TODO via connection-manager>"]、audiences: ["<segment_id>"])
然后明确进行交接:
“模板已保存为
<final_name>(<template_id>)。要配置此作业:
- 运行
connection-manager skill,为目标创建header_param_authprovider。将webhook_request_headers填入key: value行(每行一项),涵盖目标所需的所有内容(X-API-TOKEN、Content-Type等)。记录返回的auth_id。- 使用下方配置运行
job-manager skill,将auth_id填入auth_ids[]。Lytics 会在作业运行时自动将 auth 的标头注入每个发出的请求——作业配置本身没有headers字段。”
测试工作流
| 模式 | 标志 | 来源 |
|---|---|---|
| 真实档案 | --profile=<field>=<value> | 组合 entity-lookup skill(GET /api/entity/user/<field>/<value>);将返回的档案用作 entity |
| 合成样例 | --synthetic | 组合 schema-discovery skill(GET /v2/schema/user/field);根据每种类型构建样例 |
| 用户提供的 JSON | --json=<file-or-paste> | 接受字面量 JSON 实体块;验证其能否解析 |
测试请求正文为 {job_config, entity}。从最终 webhook 作业配置的精简版本合成 job_config(audience_trigger_events、webhook_url、标头等),确保模板针对生产环境中实际接收到的配置运行。渲染输出是一个字符串——该字符串就是将 POST 到目标位置的正文。
合成样例默认值
对于 GET /v2/schema/user/field 返回的每种类型,填入合理的值:
| 字段类型 | 默认值 |
|---|---|
string | "sample_value"。身份类字段使用逼真的替代值(email -> "[email protected]"、phone -> "+15555550100")。 |
int / number | 1 |
bool | false |
[]string | ["sample"] |
date / ts | 当前 ISO-8601 时间戳 |
_segments | ["test_segment"] |
_id、_uid | "sample-id" |
API 端点
列出模板
curl -s "${LYTICS_API_URL:-https://api.lytics.io}/v2/template" \
-H "Authorization: ${LYTICS_API_TOKEN}"
列表响应仅包含元数据,不含源正文。无法通过任何 GET 端点获取正文(参见探测说明);仅提供 name、type、description、desired_format 和时间戳。
获取模板
curl -s "${LYTICS_API_URL:-https://api.lytics.io}/v2/template/${TEMPLATE_ID}" \
-H "Authorization: ${LYTICS_API_TOKEN}"
仅返回元数据(id、name、type、description、target、field_filter、desired_format、created、updated、author_id)。无法通过任何 GET 路径获取源正文——参见探测说明。如果用户需要源级别的历史记录,建议他们将模板正文保存在自己的版本控制系统中。
创建模板
curl -s -X POST \
"${LYTICS_API_URL:-https://api.lytics.io}/v2/template?name=${NAME}&type=${TYPE}&description=${DESCRIPTION}&desired_format=${DESIRED_FORMAT}" \
-H "Authorization: ${LYTICS_API_TOKEN}" \
-H "Content-Type: text/plain" \
--data-binary @template.js
- 元数据(
name、type、description、可选的account_id、desired_format)放在查询字符串中。 - 模板源代码作为原始文本放在正文中。
type枚举值:js1、jsonnet、handlebars。Lytics API 参考页面遗漏了js1,但生产环境支持它。如果 API 拒绝该值(400 invalid type),请参见探测说明。- **
/test要成功,必须提供desired_format。**它是目标位置预期负载的示例(一个 JSON 字符串——请进行 URL 编码)。如果为空,/test会返回500和空正文。使用目标位置文档中推断出的正文结构(步骤 4);如果没有更合适的内容,最简单的{}也可以用作占位符。
更新模板
curl -s -X PUT \
"${LYTICS_API_URL:-https://api.lytics.io}/v2/template/${TEMPLATE_ID}?name=${NAME}&type=${TYPE}&description=${DESCRIPTION}&desired_format=${DESIRED_FORMAT}" \
-H "Authorization: ${LYTICS_API_TOKEN}" \
-H "Content-Type: text/plain" \
--data-binary @template.js
**更新使用 PUT /v2/template/{id},而不是 POST。**Lytics API 参考页面对此记录有误,将其写成了 POST;实时 API 对此路由上的 POST 响应为 405 Method Not Allowed,并返回 Allow: GET, OPTIONS, DELETE, PUT, HEAD。重构时不要把它“纠正”回 POST。
删除模板
curl -s -X DELETE "${LYTICS_API_URL:-https://api.lytics.io}/v2/template/${TEMPLATE_ID}" \
-H "Authorization: ${LYTICS_API_TOKEN}"
测试模板
curl -s -X POST "${LYTICS_API_URL:-https://api.lytics.io}/v2/template/${TEMPLATE_ID}/test" \
-H "Authorization: ${LYTICS_API_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"job_config": {
"audience_trigger_events": "enter",
"webhook_url": "https://example.com/webhook"
},
"entity": {
"email": "[email protected]",
"first_name": "Ada",
"last_name": "Lovelace",
"_segments": ["high_value_customers"]
}
}'
响应:{data: "<rendered string>", status: 200, request_id: "..."}。渲染出的字符串就是将 POST 到目标位置的正文。
需要了解的测试端点特性:
- 如果请求正文完全缺少
job_config,或者job_config为{},运行时不会将ly_job_config作为全局变量传入。未加保护的JSON.parse(ly_job_config || "{}")随后会抛出ReferenceError: ly_job_config is not defined。请始终使用try { if (typeof ly_job_config === "string" && ly_job_config) { ... } } catch (e) {}进行保护(步骤 5 的脚手架已这样处理)。 - 运行时错误会通过
{data: "<error message>", status: 200}返回——即使模板抛出错误,HTTP 状态码仍为200。检查data中是否包含前缀"evaluating snippet: RUNTIME ERROR"(jsonnet),或 JS 异常堆栈跟踪(js1)。 - 如果
/test返回 HTTP500且正文为空,最常见的原因是模板未设置desired_format。使用PUT设置后重试。
探查记录
模板 API 的若干细节与公开参考文档和在线运行环境不一致。以下发现已通过 api.lytics.io 确认。请以此为准;不要仅根据文档重新排序或“修正”。
| 未知项 | 结论 |
|---|---|
| js1 入口函数名称 | function template(data) { ... }(不是 transformData)。如果缺少入口函数,运行时会返回空正文的 500。平台上现有的 js1 模板一贯使用 template。 |
/test 是否需要 desired_format | 需要。 如果未设置,/test 会返回空正文的 500,且没有错误消息。创建时设置,或通过 PUT 更新。该值是目标位置预期载荷的 JSON 示例(将其作为查询参数进行 URL 编码)。最简的 {} 可用作备用值。 |
| 更新方法 | PUT /v2/template/{id}(不是 POST)。API 参考文档写的是 POST;在线端点会响应 405 Method Not Allowed,并返回 Allow: GET, OPTIONS, DELETE, PUT, HEAD。 |
/test 中的空 job_config | 如果测试正文中的 job_config 为 {} 或缺失,运行时不会将 ly_job_config 作为全局变量传入。模板必须使用以下方式进行防护:try { if (typeof ly_job_config === "string" && ly_job_config) { ... } } catch (e) {}。ly_auth_config 同样适用。 |
| 创建正文的 Content-Type | text/plain 对 js1 和 jsonnet 原始正文都有效。实际使用中无需备用的 415 处理;如果遇到此问题,可尝试 application/javascript 或 application/jsonnet。 |
是否接受 type=js1? | 接受,尽管它未出现在 API 参考文档的枚举中。jsonnet 和 handlebars 也同样接受。 |
| GET 响应中的源正文 | 无法检索。 已尝试 ?include_body=true、?show_body=true、?fields=body、/v2/template/{id}/source、/body、/code、/raw,结果都只有元数据或返回 405。模板创建后只能写入,无法读取;如果用户需要保留历史记录,请将源代码存放在自己的版本控制中。 |
hmacSha256 与 hmacSHA256 | 默认使用 hmacSha256(示例中最常见的写法)。读取现有模板时,两种写法都接受。 |
| Webhook 作业配置字段名和枚举值 | 公开文档和先前的蓝图示例与在线 API 不一致。此 API 接口的 GET /v2/provider 不会公开工作流 config_routes;最可靠的核验方法是列出已有的 webhook 作业(GET /v2/job?show_all=true,筛选 workflow ~= /webhook/),并查看其 config 结构。截至 2026-04-27,在线环境中的字段名为 webhook_triggers / webhook_enrichment(工作流 slug)、segment_ids(不是 audiences)、audience_events,其枚举为 ""/enters_only/exits_only(不是带有 enter/exit 的 audience_trigger_events)、do_not_retry 的类型为 array[int](不是 CSV 字符串)、withbackfill(不是 existing_users)。没有 headers 字段——标头来自通过 auth_ids[] 指定的身份验证提供方。 |
Webhook 作业交接蓝图
标签键约定:ASK USER、INFER FROM DOCS、FROM SKILL OUTPUT、RESOLVE(探查 Lytics)。
身份验证和标头的传递方式
Webhook 作业配置没有 headers 字段。标头(X-API-TOKEN、Authorization 等)和 URL 查询参数位于身份验证提供方上,而不是作业上。运行时,Lytics 会从 auth_ids[] 引用中提取这些内容,并自动将其合并到发出的请求中。
交接给 connection-manager skill 时,请指导用户创建类型为 header_param_auth 的身份验证提供方,并填写:
webhook_request_headers-- 以换行分隔的key: value文本。Qualtrics 示例:X-API-TOKEN: <secret> Content-Type: application/jsonwebhook_request_params-- URL 查询字符串格式(key=value&key2=value2),如果目标端需要通过查询参数进行身份验证。
对于 OAuth(oauth2_client_credentials 身份验证类型),Lytics 会自动注入 Authorization: Bearer <token>。若要自定义,请在身份验证的 webhook_request_headers 中放入字面量 {token} 占位符(单层花括号,不是 {{token}}),例如 Authorization: Token token={token};Lytics 会在请求时于服务端替换它。
模板还可以在模板正文中读取 ly_auth_config(身份验证的完整配置 blob,以 JSON 编码)——这用于 HMAC 签名或其他在正文中使用凭据的场景,与标头注入分开。
发出配置前验证工作流配置架构
截至 2026-04-27,已验证的 slug 为 webhook_triggers 和 webhook_enrichment,字段形状如下方蓝图所示。GET /v2/provider 会返回 webhook 提供方,但不会在此 API 接口上公开其工作流的 config_routes,因此没有可供探测的简洁机器可读架构端点。请改为根据目标账户中的现有 webhook 作业进行校验,再发出蓝图:
# List webhook jobs and inspect their config shape
curl -s "${LYTICS_API_URL}/v2/job?show_all=true" -H "Authorization: ${LYTICS_API_TOKEN}" \
| jq '.data[] | select(.workflow | test("webhook"; "i")) | {id, name, workflow, config}'
如果至少存在一个 webhook 作业,其 config 键就是真实依据。如果不存在,则使用下方蓝图——这些蓝图已根据一个线上 webhook_triggers 作业以及 lytics/lio 中的底层工作流定义(data/workflow/webhook_v2.json、data/workflow/webhook_enrichment.json,以及 src/api/v2/models/job_configs.go 中的 WebhookTriggers/WebhookEnrichment Go 结构体)完成验证。字段名称过去曾与公开文档不一致(例如,线上 API 使用 audience_events 而非 audience_trigger_events,使用 segment_ids 而非 audiences,do_not_retry 的类型为 array[int] 而非 CSV 字符串,而且完全没有 headers 字段)。如有疑问,请以现有线上作业为准,而非文档。
受众触发器(--workflow=trigger,默认)
对应 webhook_triggers 工作流。已验证的形状:
{
"name": "<ASK USER -- defaults to '<destination> trigger for <segment>'>",
"description": "<INFER>",
"workflow": "webhook_triggers",
"auth_ids": ["<FROM connection-manager hand-off -- the auth provider holds the credential headers>"],
"config": {
"segment_ids": ["<ASK USER -- segment hex id(s) (NOT slugs)>"],
"webhook_url": "<INFER FROM DOCS or ASK USER -- must be HTTPS>",
"http_method": "POST", // enum: GET|POST|PUT|PATCH|DELETE
"audience_events": "", // enum: "" (both, default), "enters_only", "exits_only"
"template_id": "<FROM SKILL OUTPUT -- omit for raw default Lytics payload>",
"user_fields": null, // optional: subset of profile fields to export; null = all
"field_changes": [], // optional: up to 75 field names whose changes also trigger
"withbackfill": false, // include users already in audience
"include_segs": false, // include profile's segment membership as `segments_all`
"batch_requests": false,
"batch_size": 10, // max 1000
"batch_flush_duration": 5, // seconds, max 300
"worker_count": 5, // max 20
"do_not_retry": [400, 401, 403, 404], // array[int] -- HTTP statuses to NOT retry
"cloudevents": false, // wrap payload in CloudEvents v1.0 envelope
"cloudevents_type": null, // default: com.lytics.audience.user.event
"cloudevents_source": null // default: /work/id
}
}
用户数据补充(--workflow=enrichment)
对应 webhook_enrichment 工作流。已验证的形状:
{
"name": "<ASK USER>",
"description": "<INFER>",
"workflow": "webhook_enrichment",
"auth_ids": ["<FROM connection-manager hand-off>"],
"config": {
"segment_ids": ["<ASK USER -- segment hex id(s)>"],
"stream": "webhook_enrichment", // optional; lands the response in stream of this name
"webhook_url": "<INFER FROM DOCS or ASK USER -- must be HTTPS>",
"http_method": "POST", // enum: GET|POST|PUT|PATCH (no DELETE for enrichment)
"template_id": "<FROM SKILL OUTPUT>",
"user_fields": null, // optional: subset of profile fields to send
"field_changes": [], // optional: trigger on field changes (up to 75)
"withbackfill": true, // NOTE: defaults to true for enrichment (false for triggers)
"audience_events": "", // enum: "" (both) | "enters_only" | "exits_only"
"worker_count": 5, // max 20
"do_not_retry": [400, 401, 403, 404] // array[int]
}
}
对于技能无法推断的任何字段,请标注 “请仔细检查”,以便用户在 job-manager 写入前注意到。注意: 两种工作流的配置中都没有 headers 字段——凭据通过 auth_ids[] 传递。请参阅上文“身份验证和标头的传递方式”。
行为
对于读取操作(list、get)
立即执行。以表格形式显示模板,列出:ID、名称、类型、描述、更新时间。
对于写入操作(create、update、delete、build 的保存步骤)
使用确认门模式。显示完整负载(原始来源加查询参数元数据)以及解析后的 curl 调用;写入前必须明确回复 yes。
对于 test
针对已保存模板进行测试时,无需确认——这只会读取目标端数据。直接内联显示响应。如果测试针对的是在 build 期间创建的草稿,则将该草稿视为已通过创建确认门。
错误处理
- 模板返回
404—— 根据list(对name执行不区分大小写的子字符串匹配)提供模糊匹配结果。 POST /v2/template/{id}返回405—— 更新操作使用的动词是PUT,而不是POST。请改用PUT重试。/test返回500且响应体为空 —— 几乎总是因为模板未设置desired_format,或者 js1 入口点的名称不是template。通过GET /v2/template/{id}检查这两项;如果缺少desired_format,请通过PUT设置;如果源代码中的函数不是template(data),请重命名该函数。HTTP 200,且data: "ReferenceError: ly_job_config is not defined"—— 模板执行了未加保护的JSON.parse(ly_job_config)。请用try { if (typeof ly_job_config === "string" && ly_job_config) { ... } } catch (e) {}包裹,并重新测试。HTTP 200,且data: "ReferenceError: <field>"(jsonnet)或 JS 异常堆栈(js1)——被引用的实体字段缺失。添加默认回退值,或从步骤 3 的架构发现结果中选择正确的字段名称。- 创建时
type=js1返回400—— API 可能不接受此账户使用该枚举值。请向用户明确说明错误;不要默默切换到jsonnet(参见“默认模板语言”部分)。 - 创建/更新时返回
415—— Content-Type 探测失败;请使用备用值重试(js1 使用application/javascript,jsonnet 使用application/jsonnet)。将可用值缓存到本次会话中。 - 目标端报告 HMAC 不匹配 ——
ly_auth_config中的密钥与目标端的预期不一致,或者hmacSha256的输入顺序/编码错误。请原样显示目标端的错误信息。 - WebFetch 未返回有用内容(付费墙、速率限制、由 JS 渲染)——请提示用户粘贴相关文档部分。
- 实时作业中目标端返回
401—— 此技能已保存可用的模板;问题出在身份验证。请引导用户使用connection-manager skill。
依赖项
- 组合使用:
entity-lookup skill、schema-discovery skill、connection-manager skill、job-manager skill - 使用:
../references/auth.md、../references/api-client.md、../references/confirmation-gate.md、../references/api-response-format.md - 相关:
integration-setup skill(编排器移交模式)、integration-advisor skill(研究驱动的顾问模式)