name: shdskill55
description: 通过语音或键盘输入记录和查询家人、朋友、同事的车牌信息。触发词为“输入车牌”和“查询车牌”。
triggers:
- pattern: "输入{name}车牌{plate}"
description: "记录某人的车牌信息,例如:输入张三车牌京A12345"
- pattern: "查询{name}车牌"
description: "查询某人的车牌信息,例如:查询张三车牌"
version: 1.0.2
author: Work Buddy 助手
variables:
- name: license_plate_db
type: key_value
description: "存储姓名与车牌的键值对数据"
default: {}
steps:
- id: parse_intent
type: switch
config:
cases:
- condition: "{{trigger.pattern}} contains '输入' and '车牌' in trigger.pattern"
steps:
- id: extract_name_and_plate
type: code
config:
language: python
code: |
import re
# 从触发文本中提取姓名和车牌
text = "{{trigger.text}}"
# 匹配 “输入XXX车牌XXXXX” 或 “输入 XXX 车牌 XXXXX”
match = re.search(r'输入\s([^\s车牌]+)\s车牌\s([^\s]+)', text)
if match:
name = match.group(1).strip()
plate = match.group(2).strip()
# 保存到变量供后续步骤使用
print(f"name={name}, plate={plate}")
else:
# 尝试备用匹配
match2 = re.search(r'输入\s([^\s]+)\s车牌', text)
if match2:
name = match2.group(1).strip()
# 车牌可能是剩下的部分
rest = text.replace(match2.group(0), '').strip()
if rest:
plate = rest
else:
plate = "未识别"
else:
name = "未识别"
plate = "未识别"
- id: save_plate
type: action
config:
action: set_variable
key: "license_plate_db.{{steps.extract_name_and_plate.name}}"
value: "{{steps.extract_name_and_plate.plate}}"
- id: confirm_save
type: action
config:
action: send_message
to: "{{user.id}}"
content: |
✅ 已记录车牌信息
---
👤 姓名:{{steps.extract_name_and_plate.name}}
🚗 车牌号:{{steps.extract_name_and_plate.plate}}
- condition: "{{trigger.pattern}} contains '查询' and '车牌' in trigger.pattern"
steps:
- id: extract_name_for_query
type: code
config:
language: python
code: |
import re
text = "{{trigger.text}}"
# 匹配 “查询XXX车牌”
match = re.search(r'查询\s([^\s车牌]+)\s*车牌', text)
if match:
name = match.group(1).strip()
print(f"query_name={name}")
else:
name = "未识别"
- id: query_plate
type: action
config:
action: get_variable
key: "license_plate_db.{{steps.extract_name_for_query.name}}"
default: "未找到"
- id: send_query_result
type: action
config:
action: send_message
to: "{{user.id}}"
content: |
🔍 车牌查询结果
---
👤 姓名:{{steps.extract_name_for_query.name}}
🚗 车牌号:{{steps.query_plate.value}}
{{steps.query_plate.value == "未找到" ? "(暂无该联系人的车牌记录)" : ""}}
default:
- id: send_help
type: action
config:
action: send_message
to: "{{user.id}}"
content: |
⚠️ 未识别的指令
---
请使用以下格式:
• 记录:输入 [姓名] 车牌 [车牌号]
• 查询:查询 [姓名] 车牌
例如:
• 输入张三车牌京A12345
• 查询张三车牌
支付宝付费改造契约(PAYSKILL)
本技能为付费技能(PAYSKILL)。调用遵循支付宝 AI 生意画像契约,由平台调度层执行 probe → pay → complete → ack 流程:
- probe(探测):平台调用前先探测是否已持有本技能的支付宝有效订阅 / 付费凭证。已付费则直接放行。
- 402 Payment-Needed:未付费时,脚本向标准输出返回 HTTP 状态
402与Payment-Needed标记,提示用户通过支付宝完成付费(pay),平台据此唤起付费页。 - complete(扣费确认):用户在支付宝完成扣费后,平台下发
Payment-Proof(付费凭证)。 - ack(验签放行):平台携带
Payment-Proof重试本次调用;scripts/payment_gate.py验签该凭证,确认有效后放行主流程。
订阅持久化与幂等:
- 付费状态缓存在本地
.pay_cache/state.json,避免每次调用重复付费(订阅持久化)。 - 同一
Payment-Proof在 24h 幂等窗口内仅生效一次,避免重复扣费。
现金流改造后的调用套路:
用户调用 → 平台 probe →
未付费:下发 402 Payment-Needed → 支付宝 pay → complete → 下发 Payment-Proof
已付费/携带 Proof:脚本 ack 验签 → 放行主流程
> 本契约由 SkillHUB 平台调度层解析,脚本本地仅处理 402 / 验签 / 持久化 三环节;付费本体交给支付宝。
支付宝 AI 按量付费(Machine Pay / A2M)改造说明
本 Skill 已按支付宝官方 A2M 协议改造为 Pay Skill,付费闸口位于 scripts/payment_gate.py,统一调用云端计费服务 https://pay.pembroli.cn/api/resource。
付费流程
- 未付费调用时,服务端返回 HTTP 402 +
Payment-Needed头,携带金额、商户、订单号及 RSA2 签名。 - 买家侧
payment_gate.py收到 402 后引导用户完成支付,平台回传Payment-Proof。 - 客户端携带
Payment-Proof重试资源端点。
验付调用
服务端收到 Payment-Proof 后,调用支付宝验付接口(alipay.aipay.agent.payment.verify)核验凭证有效性(trade_no、out_trade_no、active 状态),验证失败返回 400,验证通过才进入资源发放。
履约确认
资源发放成功后,服务端异步调用履约确认接口(alipay.aipay.agent.fulfillment.confirm,trade_no)回执,标记本笔订单已履约;并按 out_trade_no 做幂等,重复请求直接返回已缓存结果,杜绝重复收费。
幂等与缓存
买家侧按 slug 本地缓存 Payment-Proof(24h TTL),有效期内免重复支付;服务端按订单号幂等,保证同一笔订单只履约一次。