Install
openclaw skills install @tencent-adm/tencentcloud-sms-skill腾讯云短信(SMS)服务 Skill。当用户需要发送短信(验证码/通知/营销,单发或批量群发),管理短信签名与模板(查询、申请、跟踪审核状态),查询套餐包用量,统计发送量与回执送达率,或按手机号追踪短信下发/回复状态时使用。覆盖国内短信与国际/港澳台短信,基于腾讯云 SMS API。
openclaw skills install @tencent-adm/tencentcloud-sms-skill基于腾讯云短信(SMS)API,帮助用户完成短信发送(验证码/通知/营销,单发或批量群发)、签名与模板管理(查询、申请、跟踪审核状态)、套餐包用量查询、发送量与回执送达率统计,以及按手机号追踪短信下发/回复状态。覆盖国内短信与国际/港澳台短信。
官方文档:https://cloud.tencent.com/document/product/382
| 能力 | 脚本 | 说明 |
|---|---|---|
| 发送短信 | scripts/send_sms.py | 发送验证码/通知/营销短信,支持从群发模板批量发送 |
| 签名管理 | scripts/describe_sign.pyscripts/add_sign.py | 查询签名列表/状态、新增签名并提交审核 |
| 模板管理 | scripts/describe_template.pyscripts/add_template.py | 查询模板列表/状态、新增模板并提交审核 |
| 套餐包监控统计 | scripts/packages_statistics.py | 查询套餐包用量、剩余条数、到期时间等 |
| 发送短信统计 | scripts/send_status_statistics.py | 统计指定时间段内提交侧数据(提交量、提交成功量、计费条数) |
| 发送回执统计 | scripts/callback_status_statistics.py | 统计指定时间段运营商回执侧结果分布(成功/失败/无效号码/停机/免打扰/频率限制等) |
| 状态拉取 | scripts/pull_send_status_by_phone.pyscripts/pull_reply_status_by_phone.py | 按手机号拉取下发状态/回复状态,用于追踪单个号码的送达情况与上行回复 |
当用户需要批量群发短信时,使用 Skill 内置的群发 Excel 模板。
模板文件
| 模板文件 | 适用场景 | 手机号格式 |
|---|---|---|
assets/国内短信群发模板.xlsx | 国内短信群发 | 11 位手机号(如 15122261234),自动补 +86 前缀 |
assets/国际港澳台短信群发模板.xlsx | 国际/港澳台短信群发 | 国家码+手机号(如 8521414xxxx),自动补 + 前缀 |
模板格式说明
| 列 | 内容 | 说明 |
|---|---|---|
| A 列 | 客户手机号 | 必填,每行一个号码 |
| B 列 | 短信内容变量1 | 对应模板中的 {1},无变量时留空 |
| C 列 | 短信内容变量2 | 对应模板中的 {2},无变量时留空 |
| D 列 | 短信内容变量3 | 对应模板中的 {3},无变量时留空 |
注意:如果短信模板中没有变量,只需填写 A 列(客户手机号)即可。变量列可根据实际模板变量数量扩展。
配套脚本(分发 / 解析)
| 能力 | 脚本 | 说明 |
|---|---|---|
| 分发群发模板 | scripts/prepare_bulk_template.py | 复制空白群发模板到工作区(带时间戳)并作为附件下发,避免使用 Skill 内置原始文件残留旧数据;桌面端可选 --open 自动打开 |
| 解析群发模板 | scripts/parse_bulk_template.py | 解析群发 Excel 模板,提取手机号和模板变量,自动校验变量列数(可选调用 DescribeSmsTemplateList) |
当用户提出以下需求时触发此技能:
StatusCode=0 标识签名报备完成可用tencentcloud-sdk-python(脚本会自动检测并安装)TENCENTCLOUD_SECRET_ID:腾讯云 API 密钥 SecretIdTENCENTCLOUD_SECRET_KEY:腾讯云 API 密钥 SecretKey检查环境变量:
python3 scripts/check_env.py
使用前请确保:
QcloudSMSFullAccess 全量权限。详见下方「推荐权限配置」前往 CAM 策略管理 → 新建自定义策略 → 按策略语法创建,使用以下 JSON:
{
"version": "2.0",
"statement": [
{
"effect": "allow",
"action": [
"sms:SendSms",
"sms:DescribeSmsSignList",
"sms:DescribeSmsTemplateList",
"sms:AddSmsSign",
"sms:AddSmsTemplate",
"sms:SmsPackagesStatistics",
"sms:SendStatusStatistics",
"sms:CallbackStatusStatistics",
"sms:PullSmsSendStatusByPhoneNumber",
"sms:PullSmsReplyStatusByPhoneNumber"
],
"resource": "*"
}
]
}
上述 10 个 action 与本 Skill 的核心能力对应:
API Action 对应能力 sms:SendSms发送短信 sms:DescribeSmsSignList签名管理 - 查询 sms:AddSmsSign签名管理 - 新增 sms:DescribeSmsTemplateList模板管理 - 查询 sms:AddSmsTemplate模板管理 - 新增 sms:SmsPackagesStatistics套餐包监控统计 sms:SendStatusStatistics发送短信统计(提交侧) sms:CallbackStatusStatistics发送回执统计(运营商回执侧) sms:PullSmsSendStatusByPhoneNumber状态拉取 - 下发状态 sms:PullSmsReplyStatusByPhoneNumber状态拉取 - 回复状态
如果只需要发送短信(不需要管理签名/模板),可进一步缩小为:
{
"version": "2.0",
"statement": [
{
"effect": "allow",
"action": [
"sms:SendSms",
"sms:DescribeSmsTemplateList"
],
"resource": "*"
}
]
}
在方案 1 基础上增加 condition 限制来源 IP,仅允许从指定 IP 地址调用 API。参考 CAM 限制 IP 访问文档:
{
"version": "2.0",
"statement": [
{
"effect": "allow",
"action": [
"sms:SendSms",
"sms:DescribeSmsSignList",
"sms:DescribeSmsTemplateList",
"sms:AddSmsSign",
"sms:AddSmsTemplate",
"sms:SmsPackagesStatistics",
"sms:SendStatusStatistics",
"sms:CallbackStatusStatistics",
"sms:PullSmsSendStatusByPhoneNumber",
"sms:PullSmsReplyStatusByPhoneNumber"
],
"resource": "*",
"condition": {
"ip_equal": {
"qcs:ip": [
"YOUR_IP_ADDRESS"
]
}
}
}
]
}
将
YOUR_IP_ADDRESS替换为实际的公网 IP 或 CIDR 网段(如203.0.113.0/24),支持填写多个。
AskUserQuestion 工具提供交互式选择,而非纯文本编号列表。这样用户在 IDE / 桌面 Agent 中可以直接点选,避免来回打字。label + description 两字段:
label:简短中文名称(≤ 8 字),用作按钮文本description:解释说明,告诉用户该选项的实际含义或对应的接口取值{
"question": "请选择需要发送的短信类型",
"options": [
{"label": "国内短信", "description": "面向中国大陆 +86 手机号;--international 0"},
{"label": "国际/港澳台短信", "description": "面向中国港澳台与海外手机号;--international 1"}
]
}
AskUserQuestion 失败时,按以下规则降级:
编号) label —— description,末行提示"请回复编号或选项名称"。确认发送),禁止接受单字符 y,以避免误确认。describe_sign.py 分页查询获取真实 ID,不得随意填写 1~10 等序号--dry-run 预览请求参数,展示给用户确认后再执行AskUserQuestion 选项交互)describe_sign.py / describe_template.py 查询确认assets/ 下原始模板路径告知用户,必须调用 prepare_bulk_template.py 生成一份带时间戳的新副本(默认生成到当前工作区,作为附件下发;不要默认放桌面,桌面端如需可加 --open),确保用户每次拿到的是空白模板当用户需要发送短信时,按以下步骤引导:
逐步引导原则(必须遵守):
- 每次只展示当前步骤,等用户完成并回复后,再引导下一步
- 禁止在一条消息中同时展示多个步骤的内容或参数收集表
- 如果当前步骤包含子步骤(如 2.1、2.2),也要逐个引导,不要合并
- 用户主动提供了后续步骤所需的信息时,可以跳过对应步骤,但仍然只展示下一个待完成的步骤
首先运行环境变量检测脚本,自动检查密钥是否已配置:
python3 <SKILL_DIR>/scripts/check_env.py
如果检测结果为 "configured": true:说明已检测到环境变量已配置,直接进入步骤 2
如果检测结果为 "configured": false:使用 AskUserQuestion 工具询问用户当前状态,提供以下选项(不要再用纯文本数字列表):
{
"question": "未检测到腾讯云密钥,请告诉我您当前的情况",
"options": [
{"label": "已有密钥,未配置", "description": "已经在控制台拿到 SecretId/SecretKey,但还没写入 shell 环境变量"},
{"label": "没有密钥,待创建", "description": "还没创建过腾讯云 API 密钥,需要前往访问管理新建"},
{"label": "无法获取密钥", "description": "受限环境/无主账号权限,希望直接用控制台手动操作"}
]
}
用户选择后的引导:
~/.profile、~/.bashrc 或 ~/.zshrc 中:
export TENCENTCLOUD_SECRET_ID="你的SecretId"
export TENCENTCLOUD_SECRET_KEY="你的SecretKey"
等待用户确认密钥已配置后,再进入步骤 2。
提醒用户需要先开通短信服务,可参考:
使用 AskUserQuestion 工具询问用户需要发送的短信类型:
{
"question": "请选择需要发送的短信类型",
"options": [
{"label": "国内短信", "description": "面向中国大陆 +86 手机号;--international 0"},
{"label": "国际/港澳台短信", "description": "面向中国港澳台或海外手机号;--international 1"}
]
}
等待用户选择短信类型后,再进入 2.2。
根据用户选择的短信类型,引导用户提供对应参数:
国内短信参数:
| 参数 | 格式示例 | 说明 |
|---|---|---|
| 应用 ID | 1400006666 | 前往 应用管理 获取 |
| 签名内容 | 腾讯云 | 已审核通过的签名内容 |
| 模板 ID | 1110 | 已审核通过的模板 ID |
国际/港澳台短信参数:
| 参数 | 格式示例 | 说明 |
|---|---|---|
| 应用 ID | 1400006666 | 前往 应用管理 获取 |
| 签名内容(可选) | 腾讯云 | 已审核通过的签名内容,国际/港澳台短信可不提供 |
| 模板 ID | 1110 | 已审核通过的模板 ID |
| SenderId | Qsms | 国际/港澳台短信已申请独立 SenderId 时需填写 |
注意:应用 ID 可查询 应用列表。
等待用户提供基本参数后,再进入 2.3。
用户提供基本参数后,使用 AskUserQuestion 询问发送方式:
{
"question": "请选择发送方式",
"options": [
{"label": "单发", "description": "只给 1 个或少量手机号发送,直接在对话中提供号码"},
{"label": "群发/批量发送", "description": "通过 Excel 模板批量导入号码与变量,自动按 200 条/批分发"}
]
}
选择「单发」:引导用户提供接收手机号
| 参数 | 格式示例 | 说明 |
|---|---|---|
| 手机号 | +8618501234444 | E.164 格式,国内手机号前加 +86 |
选择「群发/批量发送」:跳转至 步骤 5:批量/群发特殊处理
等待用户确认发送方式并提供手机号后,再进入步骤 3。
如果用户无法提供签名内容或模板 ID,主动为用户查询可用列表。根据步骤 2.1 确认的短信类型,使用对应的 --international 参数:
--international 0--international 1describe_sign.py --international <0|1> --limit 10 --offset 0describe_template.py --international <0|1> --limit 10 --offset 0FailedOperation.NotEnterpriseCertification,告知用户:
等待用户确认签名和模板选择后,再进入步骤 4。
发送前必须先执行 --dry-run 预览,并将预览结果格式化展示给用户。
其中「发送内容」需要根据步骤 3 查询到的模板内容,将用户提供的模板参数按顺序替换模板中的变量(变量格式为 {1}、{2}、{3}……)生成实际发送文本。例如:
{1}为您的登录验证码,请于{2}分钟内填写,如非本人操作,请忽略本短信。128719 5128719为您的登录验证码,请于5分钟内填写,如非本人操作,请忽略本短信。根据步骤 2.1 确认的短信类型,使用对应的预览格式:
国内短信预览:
📋 短信发送预览(国内短信)
━━━━━━━━━━━━━━━━━━━━━━
📱 接收人: +8618501234444(共 1 个号码)
🔑 应用ID: 1400006666
📝 签名: 腾讯云
📄 模板ID: 1110
🔢 模板参数: ["128719", "5"]
📨 下发内容: 【腾讯云】128719为您的登录验证码,请于5分钟内填写,如非本人操作,请忽略本短信。
━━━━━━━━━━━━━━━━━━━━━━
国际/港澳台短信预览(有签名):
📋 短信发送预览(国际/港澳台短信)
━━━━━━━━━━━━━━━━━━━━━━
📱 接收人: +8521414xxxx(共 1 个号码)
🔑 应用ID: 1400006666
📝 签名: 腾讯云
📄 模板ID: 1110
🆔 SenderId: Qsms
🔢 模板参数: ["128719", "5"]
📨 下发内容: [腾讯云]128719为您的登录验证码,请于5分钟内填写,如非本人操作,请忽略本短信。
━━━━━━━━━━━━━━━━━━━━━━
国际/港澳台短信预览(无签名):
📋 短信发送预览(国际/港澳台短信)
━━━━━━━━━━━━━━━━━━━━━━
📱 接收人: +8521414xxxx(共 1 个号码)
🔑 应用ID: 1400006666
📄 模板ID: 1110
🆔 SenderId: Qsms
🔢 模板参数: ["128719", "5"]
📨 下发内容: 128719为您的登录验证码,请于5分钟内填写,如非本人操作,请忽略本短信。
━━━━━━━━━━━━━━━━━━━━━━
注意:
- 国际/港澳台短信的签名为可选项,如用户提供了签名,下发内容中使用英文中括号包裹签名(如
[腾讯云]);如未提供签名,则不展示签名相关行。- 如用户在步骤 2.2 提供了 SenderId,预览中需展示该字段;如未提供则不展示。
两步走,严禁合并:
第一步:将上述预览代码块正常输出给用户(作为 markdown 内容展示),不要询问、不要带 y/n。
第二步:单独调用 AskUserQuestion 发起确认,question 字段保持简短(如 "是否确认发送?"),禁止把整段预览塞进 question:
{
"question": "是否确认发送?",
"options": [
{"label": "确认发送", "description": "立即调用 SendSms 接口发送短信"},
{"label": "取消", "description": "终止本次发送,不调用接口"},
{"label": "修改参数", "description": "回到上一步重新调整签名/模板/接收人/参数"}
]
}
用户选择「确认发送」后才实际执行发送。
等待用户确认后,执行发送。如需群发,进入步骤 5。
当用户需要批量群发时,优先推荐使用群发 Excel 模板。以下子步骤也需逐步引导,每次只展示当前子步骤:
生成并下发空白模板:根据用户的短信类型,调用 prepare_bulk_template.py 生成一份带时间戳的全新空白模板到当前工作区(默认 cwd,不要默认放桌面),随后作为附件下发给用户。
# 国内短信(生成到当前工作区,默认不自动打开)
python3 <SKILL_DIR>/scripts/prepare_bulk_template.py --international 0
# 国际/港澳台短信
python3 <SKILL_DIR>/scripts/prepare_bulk_template.py --international 1
脚本输出 JSON 包含 destination(生成文件的绝对路径)和 opened(是否自动打开成功)字段。展示给用户时必须:
destination 字段,不要再说"在 Skill 目录下")。destination 作为附件直接发送给用户下载——这是默认且首选的下发方式。opened=false。--open 让脚本自动打开 Excel;此时根据 opened 字段提示:
opened=true:告知"已为您打开模板,请在弹出的 Excel 中填写"。opened=false:告知"请打开附件中的模板 <destination> 填写"。--dest-dir <用户指定路径>;否则保持默认工作区。禁止:不要直接使用
<SKILL_DIR>/assets/...下的原始模板路径下发或解析(那份模板可能残留之前会话填的旧数据)。每次群发都必须新建一份。
等待用户确认收到模板后,再引导填写。
等待用户上传填好的 Excel 后,再进行解析。
parse_bulk_template.py --template-id <模板ID> --international <0|1> 解析验证。脚本会自动完成以下流程:
解析完成后,展示解析结果(含变量校验信息),等待用户确认再进行预览。
send_sms.py --from-file 并加 --dry-run 预览群发参数展示预览结果,等待用户确认后再执行发送。
确认后发送:两步走——先把接收人总数/前 5 号码预览/分批情况作为 markdown 输出给用户;然后单独调用 AskUserQuestion 发起确认,question 字段保持简短,禁止把预览内容塞进 question:
{
"question": "是否开始群发?",
"options": [
{"label": "确认群发", "description": "立即发送,脚本将自动按每批 200 个号码分批发送"},
{"label": "取消", "description": "终止本次群发,不调用接口"}
]
}
群发(>10 个号码)时额外展示:
所有脚本均支持以下通用参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| --region | str | 否 | 腾讯云地域,默认 ap-guangzhou(国内站)。国际站账号请使用 ap-singapore |
| --dry-run | flag | 否 | 预览模式:仅验证参数并输出请求体,不实际调用 API |
关于
--region:默认ap-guangzhou适用于国内站账号。若接口返回错误码UnsupportedRegion(或错误信息提示当前地域不支持),通常意味着用户使用的是国际站账号,此时应通过AskUserQuestion询问用户是否改用ap-singapore(国际站标准地域)后重试;用户确认后所有后续调用都应带上--region ap-singapore。
scripts/send_sms.py发送验证码、通知类或营销短信。
python3 <SKILL_DIR>/scripts/send_sms.py \
--phone-number-set "+8618501234444" "+8618501234445" \
--sdk-app-id "1400006666" \
--template-id "1110" \
--sign-name "腾讯云" \
--template-param-set "4370"
# 预览模式(不实际发送)
python3 <SKILL_DIR>/scripts/send_sms.py \
--phone-number-set "+8618501234444" \
--sdk-app-id "1400006666" --template-id "1110" \
--sign-name "腾讯云" --template-param-set "4370" \
--dry-run
# 从群发 Excel 模板批量发送(每个号码可有独立模板变量)
python3 <SKILL_DIR>/scripts/send_sms.py \
--from-file "/path/to/群发模板.xlsx" \
--sdk-app-id "1400006666" --template-id "1110" \
--sign-name "腾讯云" --international 0 --dry-run
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| --phone-number-set | str[] | 二选一 | 手机号列表(E.164 格式,如 +8618501234444),单次最多 200 个 |
| --from-file | str | 二选一 | 群发 Excel 模板文件路径(.xlsx),与 --phone-number-set 互斥 |
| --sdk-app-id | str | 是 | 短信 SdkAppId |
| --template-id | str | 是 | 已审核通过的模板 ID |
| --sign-name | str | 否 | 已审核通过的签名(国内短信必填) |
| --template-param-set | str[] | 否 | 模板参数列表(使用 --from-file 时忽略,从 Excel 读取) |
| --international | int | 否 | 0=国内短信(默认),1=国际/港澳台短信(仅 --from-file 模式使用) |
| --extend-code | str | 否 | 短信码号扩展号 |
| --session-context | str | 否 | 用户 session 上下文,会原样返回 |
| --sender-id | str | 否 | 国际/港澳台短信 Sender ID |
scripts/describe_sign.py查询短信签名列表,辅助用户获取可用签名信息。
# 按 ID 精确查询
python3 <SKILL_DIR>/scripts/describe_sign.py \
--sign-id-set 1110 1111 \
--international 0
# 分页查询全部签名
python3 <SKILL_DIR>/scripts/describe_sign.py \
--international 0 --limit 10 --offset 0
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| --sign-id-set | int[] | 否 | 签名 ID 列表(空格分隔),不填则分页查询全部,最多 100 个 |
| --international | int | 是 | 0=国内短信,1=国际/港澳台短信 |
| --limit | int | 否 | 返回数量上限,默认 10,最大 100(仅分页模式) |
| --offset | int | 否 | 偏移量,默认 0(仅分页模式) |
| 状态码 | 含义 | 说明 |
|---|---|---|
| 0 | 已审核通过 | 签名报备完成,可用于发送短信 |
| 1 | 审核中 | 签名正在审核,通常 2 小时内完成 |
| 2 | 审核未通过 | 查看 ReviewReply 字段获取拒绝原因 |
| -1 | 已删除/无效 | 签名已被删除或失效 |
国内短信实名报备场景:新签名提交后,需等待审核通过(
StatusCode=0)才能用于发送短信。可通过定期调用此脚本查询签名状态,确认报备是否完成。
scripts/describe_template.py查询短信模板列表,辅助用户获取可用模板信息。
# 按 ID 精确查询
python3 <SKILL_DIR>/scripts/describe_template.py \
--international 0 \
--template-id-set 1110 1111
# 分页查询全部模板
python3 <SKILL_DIR>/scripts/describe_template.py \
--international 0 --limit 20 --offset 0
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| --international | int | 是 | 0=国内短信,1=国际/港澳台短信 |
| --template-id-set | int[] | 否 | 模板 ID 列表,空则查询全部 |
| --limit | int | 否 | 返回数量上限,默认 10,最大 100 |
| --offset | int | 否 | 偏移量,默认 0 |
| 状态码 | 含义 | 说明 |
|---|---|---|
| 0 | 已审核通过 | 模板可用于发送短信 |
| 1 | 审核中 | 模板正在审核,通常 2 小时内完成 |
| 2 | 审核未通过 | 查看 ReviewReply 字段获取拒绝原因 |
| -1 | 已删除/无效 | 模板已被删除或失效 |
scripts/add_sign.py创建短信签名并提交审核(企业认证用户)。
# 国内短信签名(需提供资质 ID)
python3 <SKILL_DIR>/scripts/add_sign.py \
--sign-name "腾讯云" \
--sign-type 0 \
--document-type 1 \
--international 0 \
--sign-purpose 0 \
--proof-image "/path/to/proof.jpg" \
--qualification-id 1000001
# 国际/港澳台短信签名(无需资质 ID)
python3 <SKILL_DIR>/scripts/add_sign.py \
--sign-name "腾讯云" \
--sign-type 0 \
--document-type 1 \
--international 1 \
--sign-purpose 0 \
--proof-image "/path/to/proof.jpg"
# 预览模式(不实际调用 API)
python3 <SKILL_DIR>/scripts/add_sign.py \
--sign-name "腾讯云" --sign-type 0 --document-type 1 \
--international 0 --sign-purpose 0 --proof-image "/path/to/proof.jpg" \
--qualification-id 1000001 --dry-run
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| --sign-name | str | 是 | 签名名称 |
| --sign-type | int | 是 | 签名类型:0=公司,4=商标,5=政府/机关事业单位/其他机构 |
| --document-type | int | 是 | 证明类型:0=三证合一,1=企业营业执照,2=组织机构代码证书,3=社会信用代码证书,7=商标注册书 |
| --international | int | 是 | 0=国内短信,1=国际/港澳台短信 |
| --sign-purpose | int | 是 | 签名用途:0=自用,1=他用 |
| --proof-image | str | 是 | 资质证明图片文件路径(自动 Base64 编码) |
| --commission-image | str | 否 | 委托授权证明图片路径(他用时需要) |
| --remark | str | 否 | 申请备注 |
| --qualification-id | int | 条件必填 | 已审核通过的国内短信资质 ID(国内短信需填写,国际短信无需填写)。前往 实名资质管理 查看 |
收集 --sign-type / --document-type / --sign-purpose 这三个枚举字段时,必须用 AskUserQuestion 工具,不要让用户打字数字:
{
"question": "请选择签名类型(对应 --sign-type)",
"options": [
{"label": "公司", "description": "企业、机构主体;--sign-type 0"},
{"label": "商标", "description": "已注册商标;--sign-type 4"},
{"label": "政府/事业单位", "description": "政府、机关事业单位、其他机构;--sign-type 5"}
]
}
{
"question": "请选择资质证明类型(对应 --document-type)",
"options": [
{"label": "三证合一", "description": "--document-type 0"},
{"label": "企业营业执照", "description": "--document-type 1"},
{"label": "组织机构代码证书", "description": "--document-type 2"},
{"label": "社会信用代码证书", "description": "--document-type 3"},
{"label": "商标注册书", "description": "--document-type 7"}
]
}
{
"question": "请选择签名用途(对应 --sign-purpose)",
"options": [
{"label": "自用", "description": "用于自有业务发送;--sign-purpose 0"},
{"label": "他用", "description": "代第三方发送,需额外提交委托授权证明;--sign-purpose 1"}
]
}
scripts/add_template.py创建短信正文模板并提交审核。
python3 <SKILL_DIR>/scripts/add_template.py \
--template-name "验证码" \
--template-content "您的验证码是{1},{2}分钟内有效。" \
--sms-type 3 \
--international 0 \
--remark "登录验证码"
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| --template-name | str | 是 | 模板名称 |
| --template-content | str | 是 | 模板内容,变量使用 {1}、{2} 等 |
| --sms-type | int | 是 | 短信类型:1=营销,2=通知,3=验证码 |
| --international | int | 是 | 0=国内短信,1=国际/港澳台短信 |
| --remark | str | 是 | 模板备注(申请原因、使用场景) |
收集 --sms-type 时,必须用 AskUserQuestion 工具:
{
"question": "请选择模板类型(对应 --sms-type)",
"options": [
{"label": "验证码", "description": "登录、注册、找回密码等场景;--sms-type 3"},
{"label": "通知", "description": "订单、状态、活动通知等服务类短信;--sms-type 2"},
{"label": "营销", "description": "促销、活动推广类短信,需用户授权;--sms-type 1"}
]
}
scripts/parse_bulk_template.py解析群发 Excel 模板文件,提取手机号和模板变量列表。支持通过 --template-id 自动查询模板实际变量数并校验。
# 解析国内短信群发模板(带变量校验)
python3 <SKILL_DIR>/scripts/parse_bulk_template.py \
--file "/path/to/国内短信群发模板.xlsx" --international 0 --template-id 1110
# 解析国际/港澳台短信群发模板(带变量校验)
python3 <SKILL_DIR>/scripts/parse_bulk_template.py \
--file "/path/to/国际港澳台短信群发模板.xlsx" --international 1 --template-id 1111
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| --file | str | 是 | 群发 Excel 模板文件路径 |
| --international | int | 否 | 0=国内短信(默认),1=国际/港澳台短信 |
| --template-id | str | 是 | 模板 ID,脚本会自动查询模板变量数并校验 Excel 变量列数(Excel 变量列 ≥ 模板变量数则兼容,< 则报错) |
scripts/packages_statistics.py查询短信套餐包用量统计。
python3 <SKILL_DIR>/scripts/packages_statistics.py \
--sdk-app-id "1400006666" \
--begin-time "2026010100" \
--end-time "2026033123"
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| --sdk-app-id | str | 是 | 短信 SdkAppId |
| --begin-time | str | 是 | 套餐包起始创建时间,格式 yyyymmddhh |
| --end-time | str | 是 | 套餐包结束创建时间,格式 yyyymmddhh |
| --limit | int | 否 | 返回数量上限,默认 100 |
| --offset | int | 否 | 偏移量,默认 0 |
scripts/send_status_statistics.py统计指定时间段提交侧数据(提交量 / 提交成功量 / 计费条数)。
python3 <SKILL_DIR>/scripts/send_status_statistics.py \
--sdk-app-id "1400006666" \
--begin-time "2026010100" \
--end-time "2026013123"
# 预览模式
python3 <SKILL_DIR>/scripts/send_status_statistics.py \
--sdk-app-id "1400006666" \
--begin-time "2026010100" --end-time "2026013123" --dry-run
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| --sdk-app-id | str | 是 | 短信 SdkAppId |
| --begin-time | str | 是 | 起始时间,格式 yyyymmddhh |
| --end-time | str | 是 | 结束时间,格式 yyyymmddhh,需 ≥ BeginTime(无 32 天上限) |
scripts/callback_status_statistics.py统计指定时间段运营商回执侧数据(回执成功/失败、无效号码、停机、免打扰、频率限制等)。
python3 <SKILL_DIR>/scripts/callback_status_statistics.py \
--sdk-app-id "1400006666" \
--begin-time "2026010100" \
--end-time "2026013123"
# 预览模式
python3 <SKILL_DIR>/scripts/callback_status_statistics.py \
--sdk-app-id "1400006666" \
--begin-time "2026010100" --end-time "2026013123" --dry-run
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| --sdk-app-id | str | 是 | 短信 SdkAppId |
| --begin-time | str | 是 | 起始时间,格式 yyyymmddhh |
| --end-time | str | 是 | 结束时间,格式 yyyymmddhh,需 ≥ BeginTime 且区间 ≤ 32 天 |
scripts/pull_send_status_by_phone.py按单个 E.164 手机号 + 时间区间拉取下发状态明细(SerialNo、ReportStatus、用户接收时间等)。
# 默认最近 24 小时
python3 <SKILL_DIR>/scripts/pull_send_status_by_phone.py \
--sdk-app-id "1400006666" --phone-number "+8618501234444"
# 指定 UNIX 秒时间区间
python3 <SKILL_DIR>/scripts/pull_send_status_by_phone.py \
--sdk-app-id "1400006666" --phone-number "+8618501234444" \
--begin-time 1715000000 --end-time 1715086400
# 指定本地时间字符串
python3 <SKILL_DIR>/scripts/pull_send_status_by_phone.py \
--sdk-app-id "1400006666" --phone-number "+8618501234444" \
--begin-datetime "2026-05-01 00:00:00" \
--end-datetime "2026-05-02 00:00:00"
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| --sdk-app-id | str | 是 | 短信 SdkAppId |
| --phone-number | str | 是 | E.164 格式手机号,必须以 + 开头(如 +8618501234444) |
| --begin-time / --end-time | int | 条件必填 | UNIX 秒时间区间;与 --begin-datetime/--end-datetime 互斥 |
| --begin-datetime / --end-datetime | str | 条件必填 | 本地时区字符串 YYYY-MM-DD HH:MM:SS;与上一组互斥。未传任一组时默认最近 24 小时 |
| --limit | int | 否 | 返回数量上限,默认 100,最大 100 |
| --offset | int | 否 | 偏移量,默认 0 |
时间窗口限制:最多可拉取当前时间往前 7 天。
scripts/pull_reply_status_by_phone.py按单个 E.164 手机号 + 时间区间拉取上行回复明细(SignName、ReplyContent、ReplyTime 等)。
# 默认最近 24 小时
python3 <SKILL_DIR>/scripts/pull_reply_status_by_phone.py \
--sdk-app-id "1400006666" --phone-number "+8618501234444"
# 指定 UNIX 秒时间区间
python3 <SKILL_DIR>/scripts/pull_reply_status_by_phone.py \
--sdk-app-id "1400006666" --phone-number "+8618501234444" \
--begin-time 1715000000 --end-time 1715086400
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| --sdk-app-id | str | 是 | 短信 SdkAppId |
| --phone-number | str | 是 | E.164 格式手机号,必须以 + 开头 |
| --begin-time / --end-time | int | 条件必填 | UNIX 秒时间区间;与 --begin-datetime/--end-datetime 互斥 |
| --begin-datetime / --end-datetime | str | 条件必填 | 本地时区字符串 YYYY-MM-DD HH:MM:SS;与上一组互斥。未传任一组时默认最近 24 小时 |
| --limit | int | 否 | 返回数量上限,默认 100,最大 100 |
| --offset | int | 否 | 偏移量,默认 0 |
时间窗口限制:最多可拉取当前时间往前 7 天。
scripts/prepare_bulk_template.py把 Skill 内置的群发 Excel 模板复制一份带时间戳的全新空白副本到目标目录(默认当前工作区 cwd,不是桌面),生成后作为附件下发给用户。每次群发都应调用此脚本,避免直接使用 assets/ 下原始模板(可能残留之前的填写数据)。
多 channel 设计:用户可能通过各类聊天 channel 使用 Agent,这类环境没有「桌面」概念、也不能在服务端打开文件。因此脚本默认生成到工作区且不自动打开,由宿主以附件下发;仅本地桌面端才追加
--open自动打开。
# 国内短信群发模板(默认生成到当前工作区,不自动打开 → 作为附件下发)
python3 <SKILL_DIR>/scripts/prepare_bulk_template.py --international 0
# 国际/港澳台短信群发模板
python3 <SKILL_DIR>/scripts/prepare_bulk_template.py --international 1
# 仅本地桌面端:复制后用系统默认程序打开 Excel
python3 <SKILL_DIR>/scripts/prepare_bulk_template.py --international 0 --open
# 用户显式指定目录(如桌面)
python3 <SKILL_DIR>/scripts/prepare_bulk_template.py \
--international 0 --dest-dir "~/Desktop"
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| --international | int | 否 | 0=国内短信(默认),1=国际/港澳台短信 |
| --dest-dir | str | 否 | 目标目录,默认当前工作目录(工作区);仅在用户显式需要时指定(如 ~/Desktop) |
| --open | flag | 否 | 仅本地桌面端使用:复制后尝试用系统默认程序打开。默认不打开(聊天 channel 下应由宿主以附件下发) |
输出 JSON 字段:
| 字段 | 说明 |
|---|---|
source | Skill 内置模板的绝对路径(仅用于审计) |
destination | 复制后新文件的绝对路径,应作为附件直接发给用户 |
opened | 是否成功调用系统命令打开(默认 false;仅在传 --open 且为桌面 GUI 环境时可能为 true) |
platform | 当前系统:darwin / linux / windows |
international | 模板对应的短信类型 |
所有脚本成功时以 JSON 格式输出 API 返回结果,例如发送短信成功:
{
"SendStatusSet": [
{
"SerialNo": "5000:1045710669157053657849499619",
"PhoneNumber": "+8618501234444",
"Fee": 1,
"Code": "Ok",
"Message": "send success",
"IsoCode": "CN",
"SessionContext": ""
}
],
"RequestId": "a0aabda6-cf91-4f3e-a81f-9198114a2279"
}
预览模式输出(--dry-run):
{
"dry_run": true,
"api": "SendSms",
"params": {
"PhoneNumberSet": ["+8618501234444"],
"SmsSdkAppId": "1400006666",
"TemplateId": "1110",
"SignName": "腾讯云",
"TemplateParamSet": ["4370"]
}
}
错误时输出结构化错误 JSON:
{
"error": "SMS_API_ERROR",
"code": "AuthFailure.SecretIdNotFound",
"message": "The SecretId is not found..."
}