关于 spoke-generation
面向 ServiceNow 集成开发人员,指导构建可部署的 Integration Hub spoke,以连接外部服务。涵盖连接别名、动作及数据映射、错误处理和发布。
主要功能
- 01创建 spoke 容器和集成动作
- 02配置连接别名与凭据
- 03定义动作输入和输出
- 04设置 REST 调用与数据转换
- 05加入错误处理和重试逻辑
- 06打包、测试并发布 spoke
适用场景
- 01为外部 API 构建可复用连接器
- 02将集成逻辑封装为可部署 spoke
- 03为动作配置认证与请求响应字段
- 04为外部服务调用添加错误处理
MCP 相关
指导通过 ServiceNow MCP 工具查询现有 spoke,并创建和更新 spoke、动作、连接别名及步骤记录。
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ happy-technologies-llc/ happy-platform-skills --skill spoke-generation安装后在 Claude Code 中输入/spoke-generation确认已加载。
详细介绍
Integration Hub Spoke 生成
概述
此技能介绍如何生成 ServiceNow Integration Hub spoke,以连接外部服务:
- 创建 spoke 容器,以组织相关集成操作
- 使用 REST、SOAP 和脚本步骤构建 spoke 操作
- 配置连接别名,以安全地管理凭据
- 使用正确的数据类型定义操作输入和输出
- 在 ServiceNow 与外部格式之间实现数据转换
- 添加错误处理和重试逻辑,打造弹性集成
- 打包 spoke,以便在多个实例间部署
适用场景: 构建可复用的外部 API 集成、为第三方服务创建自定义连接器,或将集成逻辑打包到可部署的 spoke 中。
前提条件
- 角色:
integration_admin、flow_designer或admin - 插件:
com.glide.hub.flow_designer(Flow Designer)、com.glide.hub.integration(Integration Hub) - 访问权限: sys_spoke、sys_hub_action_type_definition、sys_connection_alias 表
- 相关知识: REST/SOAP API 基础知识、JSON/XML 数据格式、OAuth 和基本身份验证
- 相关技能: 使用
genai/flow-generation在工作流中调用 spoke
操作步骤
步骤 1:分析集成需求
解析集成请求,确定以下信息:
- 外部服务: 要连接的系统或 API(Slack、Jira、Salesforce、自定义 REST)
- 操作: spoke 应支持的操作(创建、读取、更新、删除、查询)
- 身份验证: 身份验证方式(OAuth 2.0、基本身份验证、API 密钥、双向 TLS)
- 数据格式: 请求/响应格式(JSON、XML、表单编码)
- 错误处理: 预期的错误代码和重试行为
步骤 2:查询现有 spoke,了解模式
MCP 方式:
Use SN-Query-Table on sys_spoke:
- query: active=true
- fields: sys_id,name,description,scope,logo,active
- limit: 20
查询现有 spoke 操作:
Use SN-Query-Table on sys_hub_action_type_definition:
- query: spoke=<spoke_sys_id>^active=true
- fields: sys_id,name,description,action_type,inputs,outputs
- limit: 20
REST 方式:
GET /api/now/table/sys_spoke
?sysparm_query=active=true
&sysparm_fields=sys_id,name,description,scope,active
&sysparm_limit=20
步骤 3:创建 spoke 记录
MCP 方式:
Use SN-Create-Record on sys_spoke:
- name: "Acme CRM Spoke"
- description: "Integration spoke for Acme CRM REST API - supports contacts, deals, and activities"
- scope: "x_acme_crm"
- logo: ""
- active: true
- version: "1.0.0"
REST 方式:
POST /api/now/table/sys_spoke
Body: {
"name": "Acme CRM Spoke",
"description": "Integration spoke for Acme CRM REST API - supports contacts, deals, and activities",
"scope": "x_acme_crm",
"active": true,
"version": "1.0.0"
}
步骤 4:创建连接别名
连接别名可安全地存储凭据,并在多个场景中复用。
连接别名类型:
| 类型 | 值 | 使用场景 |
|---|---|---|
| HTTP 连接 | http_connection | REST/SOAP API 凭据 |
| JDBC 连接 | jdbc_connection | 数据库连接 |
| LDAP 连接 | ldap_connection | 目录服务 |
| 自定义 | custom | 非标准身份验证 |
MCP 方式:
Use SN-Create-Record on sys_connection_alias:
- name: "Acme CRM API"
- connection_type: "http_connection"
- description: "Connection alias for Acme CRM REST API"
- active: true
- scope: "x_acme_crm"
- spoke: "<spoke_sys_id>"
REST 方式:
POST /api/now/table/sys_connection_alias
Body: {
"name": "Acme CRM API",
"connection_type": "http_connection",
"description": "Connection alias for Acme CRM REST API",
"active": true,
"scope": "x_acme_crm",
"spoke": "<spoke_sys_id>"
}
配置凭据(基本身份验证):
Use SN-Create-Record on sys_alias_credential:
- connection_alias: "<connection_alias_sys_id>"
- type: "basic_auth"
- user_name: "${connection.username}"
- password: "${connection.password}"
- active: true
配置凭据(OAuth 2.0):
Use SN-Create-Record on sys_alias_credential:
- connection_alias: "<connection_alias_sys_id>"
- type: "oauth2"
- oauth_profile: "<oauth_profile_sys_id>"
- active: true
步骤 5:创建 spoke 操作
每个操作代表 spoke 可执行的一项操作。
MCP 方式:
Use SN-Create-Record on sys_hub_action_type_definition:
- name: "Create Contact"
- description: "Creates a new contact in Acme CRM"
- spoke: "<spoke_sys_id>"
- action_type: "custom"
- category: "x_acme_crm"
- access: "public"
- active: true
- annotation: "Creates a contact record in external CRM system"
Use SN-Create-Record on sys_hub_action_type_definition:
- name: "Get Contact"
- description: "Retrieves a contact by ID from Acme CRM"
- spoke: "<spoke_sys_id>"
- action_type: "custom"
- category: "x_acme_crm"
- access: "public"
- active: true
Use SN-Create-Record on sys_hub_action_type_definition:
- name: "Search Contacts"
- description: "Searches contacts in Acme CRM by criteria"
- spoke: "<spoke_sys_id>"
- action_type: "custom"
- category: "x_acme_crm"
- access: "public"
- active: true
REST 方式:
POST /api/now/table/sys_hub_action_type_definition
Body: {
"name": "Create Contact",
"description": "Creates a new contact in Acme CRM",
"spoke": "<spoke_sys_id>",
"action_type": "custom",
"category": "x_acme_crm",
"access": "public",
"active": true
}
步骤 6:定义操作输入
MCP 方式:
Use SN-Create-Record on sys_hub_action_input:
- action_type: "<create_contact_action_sys_id>"
- name: "first_name"
- label: "First Name"
- type: "string"
- mandatory: true
- order: 100
Use SN-Create-Record on sys_hub_action_input:
- action_type: "<create_contact_action_sys_id>"
- name: "last_name"
- label: "Last Name"
- type: "string"
- mandatory: true
- order: 200
Use SN-Create-Record on sys_hub_action_input:
- action_type: "<create_contact_action_sys_id>"
- name: "email"
- label: "Email Address"
- type: "string"
- mandatory: true
- order: 300
Use SN-Create-Record on sys_hub_action_input:
- action_type: "<create_contact_action_sys_id>"
- name: "company_id"
- label: "Company ID"
- type: "string"
- mandatory: false
- order: 400
REST 方式:
POST /api/now/table/sys_hub_action_input
Body: {
"action_type": "<create_contact_action_sys_id>",
"name": "email",
"label": "Email Address",
"type": "string",
"mandatory": true,
"order": 300
}
步骤 7:向操作添加 REST 步骤
REST 步骤用于定义对外部服务执行的实际 HTTP 调用。
MCP 方式:
Use SN-Create-Record on sys_hub_rest_step:
- action_type: "<create_contact_action_sys_id>"
- name: "Call Create Contact API"
- order: 100
- connection_alias: "<connection_alias_sys_id>"
- http_method: "POST"
- resource_path: "/api/v2/contacts"
- content_type: "application/json"
- request_body: '{
"first_name": "${inputs.first_name}",
"last_name": "${inputs.last_name}",
"email": "${inputs.email}",
"company_id": "${inputs.company_id}"
}'
- headers: '[{"name":"Accept","value":"application/json"}]'
REST 方式:
POST /api/now/table/sys_hub_rest_step
Body: {
"action_type": "<create_contact_action_sys_id>",
"name": "Call Create Contact API",
"order": 100,
"connection_alias": "<connection_alias_sys_id>",
"http_method": "POST",
"resource_path": "/api/v2/contacts",
"content_type": "application/json",
"request_body": "{\"first_name\":\"${inputs.first_name}\",\"last_name\":\"${inputs.last_name}\",\"email\":\"${inputs.email}\"}"
}
GET 请求示例:
Use SN-Create-Record on sys_hub_rest_step:
- action_type: "<get_contact_action_sys_id>"
- name: "Call Get Contact API"
- order: 100
- connection_alias: "<connection_alias_sys_id>"
- http_method: "GET"
- resource_path: "/api/v2/contacts/${inputs.contact_id}"
- content_type: "application/json"
- headers: '[{"name":"Accept","value":"application/json"}]'
步骤 8:定义操作输出
MCP 方式:
Use SN-Create-Record on sys_hub_action_output:
- action_type: "<create_contact_action_sys_id>"
- name: "contact_id"
- label: "Contact ID"
- type: "string"
- order: 100
Use SN-Create-Record on sys_hub_action_output:
- action_type: "<create_contact_action_sys_id>"
- name: "status_code"
- label: "HTTP Status Code"
- type: "integer"
- order: 200
Use SN-Create-Record on sys_hub_action_output:
- action_type: "<create_contact_action_sys_id>"
- name: "response_body"
- label: "Response Body"
- type: "string"
- order: 300
步骤 9:使用脚本步骤添加错误处理
MCP 方式:
Use SN-Create-Record on sys_hub_script_step:
- action_type: "<create_contact_action_sys_id>"
- name: "Handle Response"
- order: 200
- script: |
(function execute(inputs, outputs) {
var statusCode = inputs.rest_step_status_code;
var responseBody = inputs.rest_step_response_body;
if (statusCode == 201) {
var response = JSON.parse(responseBody);
outputs.contact_id = response.id;
outputs.status_code = statusCode;
} else if (statusCode == 409) {
throw new Error('Contact already exists: ' + responseBody);
} else if (statusCode == 429) {
throw new Error('Rate limit exceeded. Retry after cooldown.');
} else {
throw new Error('API error ' + statusCode + ': ' + responseBody);
}
})(inputs, outputs);
步骤 10:测试并发布 spoke
MCP 方式:
Use SN-Update-Record on sys_spoke:
- sys_id: "<spoke_sys_id>"
- active: true
验证所有操作均已正确配置:
Use SN-Query-Table on sys_hub_action_type_definition:
- query: spoke=<spoke_sys_id>
- fields: sys_id,name,active,action_type
- limit: 50
验证连接别名可用:
Use SN-Query-Table on sys_connection_alias:
- query: spoke=<spoke_sys_id>
- fields: sys_id,name,connection_type,active
工具使用
| 工具 | 用途 | 使用时机 |
|---|---|---|
| SN-Query-Table | 查找现有 spoke 和操作 | 发现模式并进行验证 |
| SN-Create-Record | 创建 spoke、操作、输入、输出和步骤 | 构建 spoke 组件 |
| SN-Update-Record | 修改 spoke 设置、激活 spoke | 编辑和发布 |
| SN-Get-Table-Schema | 发现 spoke 表字段 | 了解可用配置 |
最佳实践
- 每个外部服务使用一个 spoke —— 避免在单个 spoke 中混用多个 API
- 为所有凭据使用连接别名 —— 切勿在脚本或 REST 步骤中硬编码密钥
- 定义全面的输入和输出,并使用清晰的标签和正确的数据类型
- 始终添加错误处理 —— 解析 HTTP 状态码并提供有意义的错误消息
- 为暂时性故障(429、503)实现重试逻辑,使用脚本步骤处理
- 对搜索和列表操作使用分页,以处理大量结果
- 在 resource_path 中为 API 路径添加版本号,以支持 API 演进
- 记录集成调用日志,以便使用适当的详细级别进行调试
- 在连接生产环境的外部服务之前,先使用模拟数据进行测试
- 在 spoke 描述中记录速率限制和限流行为
故障排除
| 问题 | 原因 | 解决方法 |
|---|---|---|
| 连接测试失败 | 连接别名中的凭据或 URL 无效 | 检查连接别名配置并测试连通性 |
| 401 未授权 | OAuth 令牌已过期或凭据无效 | 刷新 OAuth 令牌或更新凭据记录 |
| 403 禁止访问 | API 密钥缺少所需权限 | 检查外部服务为集成用户配置的权限 |
| REST 步骤超时 | 外部服务响应缓慢或无法访问 | 增加 REST 步骤的超时时间,或检查网络连通性 |
| 响应解析错误 | API 返回的响应格式异常 | 在脚本步骤中添加带 try/catch 的防御式 JSON 解析 |
| Flow Designer 中未显示操作 | 操作访问权限设为 private,或 spoke 未激活 | 将访问权限设为“public”,并确认 spoke 已激活 |
| 输入数据被截断 | 字符串字段长度限制 | 对大型负载使用多行文本类型 |
示例
示例 1:Slack 通知 Spoke
生成一个用于发送 Slack 消息的 spoke:
- 操作 1: 发送消息 —— 向 /api/chat.postMessage 发送 POST 请求,包含 channel、text、attachments
- 操作 2: 创建频道 —— 向 /api/conversations.create 发送 POST 请求,包含 name、is_private
- 操作 3: 上传文件 —— 向 /api/files.upload 发送 POST 请求,包含 channels、文件内容
- 连接: 使用 Slack Bot Token 进行 OAuth 2.0 身份验证
- 错误处理: 处理速率限制(429)和频道不存在(channel_not_found)
示例 2:Jira 集成 Spoke
生成一个用于 Jira Cloud 操作的 spoke:
- 操作 1: 创建问题 —— 向 /rest/api/3/issue 发送 POST 请求,包含 project、summary、description、issuetype
- 操作 2: 获取问题 —— 发送 GET /rest/api/3/issue/{issueKey},返回 status、assignee、priority
- 操作 3: 添加评论 —— 向 /rest/api/3/issue/{issueKey}/comment 发送 POST 请求,包含 body
- 操作 4: 转换问题状态 —— 向 /rest/api/3/issue/{issueKey}/transitions 发送 POST 请求
- 连接: 使用 API token 进行 Basic Auth 身份验证,base URL 可按实例配置
示例 3:自定义 REST API Spoke
生成一个用于自定义内部微服务的 spoke:
- 操作 1: 提交订单 —— 向 /api/v1/orders 发送 POST 请求,包含行项目、客户和送货地址
- 操作 2: 查询订单状态 —— 发送 GET /api/v1/orders/{orderId},返回状态和跟踪编号
- 操作 3: 取消订单 —— 向 /api/v1/orders/{orderId} 发送 DELETE 请求,包含原因
- 连接: 通过自定义标头使用 API Key 身份验证
- 数据转换: 将 ServiceNow 目录变量映射为 API 请求格式
相关技能
genai/flow-generation- 使用 spoke 操作的 Flow Designer 流程genai/playbook-generation- 将 spoke 操作作为活动调用的 Playbookcatalog/approval-workflows- 可能触发外部通知的审批流程admin/instance-management- 连接别名和凭据配置
评论
支持 Markdown