Alibabacloud Sms Send Short Message

Send short messages (SMS) to specified phone numbers via Alibaba Cloud Short Message Service. Supports verification codes, notification messages, and marketi...

alibabacloud

@sdk-team

Install

$ openclaw skills install @sdk-team/alibabacloud-sms-send-short-message

Critical CLI Compliance (Must Read First)

The following declarations apply to every aliyun CLI invocation in this Skill — they must be honored before any send / query operation, workflow step, or functional scenario described later in this document.

Pre-check: Aliyun CLI >= 3.3.3 required

Run aliyun version to verify the version is >= 3.3.3. If not installed or the version is too low, run curl -fsSL https://aliyuncli.alicdn.com/setup.sh | bash to install or update.

Pre-check: Aliyun CLI plugin update required

[MUST] run aliyun configure set --auto-plugin-install true to enable automatic plugin installation. [MUST] run aliyun plugin update to ensure that any existing plugins on your local machine are always up-to-date.

[MUST] Enable AI-Mode — AI-mode is required for Agent Skill execution. Run the following commands before any CLI invocation:

aliyun configure ai-mode enable
aliyun configure ai-mode set-user-agent --user-agent "AlibabaCloud-Agent-Skills/alibabacloud-sms-send-short-message"

[MUST] Disable AI-Mode at EVERY exit point — Before delivering the final response for ANY reason, always disable AI-mode first. This applies to ALL exit paths: workflow success, workflow failure, error/exception, user cancellation, session end, or any other scenario where no further CLI commands will be executed. AI-mode is only used for Agent Skill invocation scenarios and MUST NOT remain enabled after the skill stops running.

aliyun configure ai-mode disable

[MUST] CLI User-Agent — Every aliyun CLI command invocation in this Skill must include the flag: --user-agent AlibabaCloud-Agent-Skills/alibabacloud-sms-send-short-message


Overview

This Skill wraps the Alibaba Cloud Short Message Service (SMS) end-to-end on top of the aliyun CLI, exposing the following capabilities:

  • Send SMS: verification codes, notifications, or marketing messages (SendSms).
  • Batch send: different signatures / template params per phone number (SendBatchSms).
  • Signature management: query approval status and signature lists.
  • Template management: query approval status and template lists.
  • Send status query: query SMS send details and delivery receipts.
  • Send statistics query: aggregated send / success / fail counts in a date range (QuerySendStatistics).
  • SMS qualification query: list records (QuerySmsQualificationRecord) and single-record detail (QuerySingleSmsQualification) — see references/sms-qualification.md.

Interactive Parameter Confirmation (Must Read)

Before executing any send-class operation (send-sms / send-batch-sms), this Skill must collect these critical parameters first:

  • --sign-name (signature name)
  • --template-code (template code)
  • --template-param (template variables, when the template contains placeholders)
  • --phone-numbers / --phone-number-json (phone numbers)

Handling Rules

When the user does not explicitly provide the signature or template, the AI agent must not guess or fabricate them. Instead it should:

  1. Ask the user proactively: "Which signature/template should I use? If unsure, I can list approved ones from your account for you to pick from."
  2. After the user agrees, call list APIs:
    • aliyun dysmsapi query-sms-sign-list ... then aliyun dysmsapi get-sms-sign --sign-name <name> per candidate.
    • aliyun dysmsapi query-sms-template-list ...
    • Hard filter: keep only signs with SignStatus = 1 (approved) and templates with TemplateStatus = 1. Do NOT drop signs based on carrier registration alone — unregistered carriers may still deliver. Instead, surface SignIspRegisterDetailList[*].RegisterResult (per-carrier registration status) as an extra column in the candidate table and let the user decide. Columns: index / code / name / content / SignStatus / per-carrier registration.
  3. Resolve template variables: If the picked template contains ${xxx} placeholders, ask for each variable's value one by one and assemble them into --template-param JSON.
  4. Phone numbers: Always require explicit phone numbers from the user; never reuse placeholder numbers like 13800138000 from this document as the actual recipient.
  5. Final confirmation: Once all critical parameters are collected, restate the complete send plan and only call send-sms / send-batch-sms after the user gives an explicit confirmation (e.g. "confirm" / "send").

Quick Recovery When Signature / Template Is Invalid

If send-sms returns isv.SMS_SIGN_NAME_ILLEGAL / isv.SMS_TEMPLATE_ILLEGAL, the agent should proactively offer to "list existing signatures and templates" and, after the user agrees, call the list APIs instead of retrying blindly.

Prerequisites

1. Install aliyun CLI (>= 3.3.3)

# macOS
brew install aliyun-cli

# Linux
wget https://aliyuncli.alicdn.com/aliyun-cli-linux-latest-amd64.tgz
tar -xzf aliyun-cli-linux-latest-amd64.tgz && sudo mv aliyun /usr/local/bin/

aliyun version  # must be >= 3.3.3

2. Install the dysmsapi plugin

aliyun plugin install --names dysmsapi

3. Configure Credentials

The aliyun CLI default credential chain is recommended; it picks credentials in this priority order: env vars → ~/.aliyun/config.json → ECS RAM role → OIDC Token.

# Recommended for CI/CD: env vars
export ALIBABA_CLOUD_ACCESS_KEY_ID=<your-access-key-id>
export ALIBABA_CLOUD_ACCESS_KEY_SECRET=<your-access-key-secret>
export ALIBABA_CLOUD_REGION_ID=cn-hangzhou

# Verify
aliyun configure get

Important: Never hard-code AK/SK in code or commands. Always rely on the default credential chain. On ECS use a RAM role; in K8s use OIDC.

4. Activate the SMS Service

In the Alibaba Cloud SMS Console: activate the service, create an approved signature, and create an approved template.

Usage

Calling aliyun CLI directly

Send SMS:

aliyun dysmsapi send-sms \
  --api-version 2017-05-25 \
  --phone-numbers "13800138000" \
  --sign-name "AliyunDemo" \
  --template-code "SMS_123456" \
  --template-param '{"code":"123456"}' \
  --user-agent AlibabaCloud-Agent-Skills/alibabacloud-sms-send-short-message \
  --read-timeout 3

Batch send (different signatures / template params):

aliyun dysmsapi send-batch-sms \
  --api-version 2017-05-25 \
  --phone-number-json '["13800138000","13900139000"]' \
  --sign-name-json '["SignA","SignB"]' \
  --template-code "SMS_123456" \
  --template-param-json '[{"code":"111111"},{"code":"222222"}]' \
  --user-agent AlibabaCloud-Agent-Skills/alibabacloud-sms-send-short-message \
  --read-timeout 3

Query lists / status / details:

# Approved signatures / templates (use to populate user choices)
aliyun dysmsapi query-sms-sign-list      --api-version 2017-05-25 --page-index 1 --page-size 50 --user-agent AlibabaCloud-Agent-Skills/alibabacloud-sms-send-short-message --read-timeout 3
aliyun dysmsapi query-sms-template-list  --api-version 2017-05-25 --page-index 1 --page-size 50 --user-agent AlibabaCloud-Agent-Skills/alibabacloud-sms-send-short-message --read-timeout 3

# Single signature / template lookup
aliyun dysmsapi get-sms-sign     --api-version 2017-05-25 --sign-name "AliyunDemo"     --user-agent AlibabaCloud-Agent-Skills/alibabacloud-sms-send-short-message --read-timeout 3
aliyun dysmsapi get-sms-template --api-version 2017-05-25 --template-code "SMS_123456" --user-agent AlibabaCloud-Agent-Skills/alibabacloud-sms-send-short-message --read-timeout 3

# Per-message delivery details (use BizId for precise lookup)
aliyun dysmsapi query-send-details \
  --api-version 2017-05-25 \
  --phone-number "13800138000" --send-date "20260326" \
  --page-size 10 --current-page 1 \
  --user-agent AlibabaCloud-Agent-Skills/alibabacloud-sms-send-short-message --read-timeout 3

# Aggregated statistics (--is-globe: 1=domestic, 2=intl/HK-Macao-Taiwan)
aliyun dysmsapi query-send-statistics \
  --api-version 2017-05-25 --is-globe 1 \
  --start-date "20260301" --end-date "20260326" \
  --page-index 1 --page-size 10 \
  --user-agent AlibabaCloud-Agent-Skills/alibabacloud-sms-send-short-message --read-timeout 3

# Filter by signature name + template type (optional)
aliyun dysmsapi query-send-statistics \
  --api-version 2017-05-25 --is-globe 1 \
  --start-date "20260301" --end-date "20260326" \
  --page-index 1 --page-size 10 \
  --sign-name "AliyunDemo" --template-type 0 \
  --user-agent AlibabaCloud-Agent-Skills/alibabacloud-sms-send-short-message --read-timeout 3

# SMS qualification — list records (full detail in references/sms-qualification.md)
aliyun dysmsapi query-sms-qualification-record \
  --api-version 2017-05-25 --page-no 1 --page-size 20 \
  --user-agent AlibabaCloud-Agent-Skills/alibabacloud-sms-send-short-message --read-timeout 3

# SMS qualification — single detail by GroupId
aliyun dysmsapi query-single-sms-qualification \
  --api-version 2017-05-25 --qualification-group-id 10000123 \
  --user-agent AlibabaCloud-Agent-Skills/alibabacloud-sms-send-short-message --read-timeout 3

Full filter parameters, response schemas, and state enum mapping for the qualification APIs are documented in references/sms-qualification.md.

Using the wrapper script

scripts/send_sms.sh automatically applies --api-version, the compliant --user-agent, and --read-timeout:

# Send (single or comma-separated phones)
./scripts/send_sms.sh send -p "13800138000" -s "AliyunDemo" -t "SMS_123456" -tp '{"code":"123456"}'

# Send with signature/template pre-verification (recommended)
./scripts/send_sms.sh send -p "13800138000" -s "AliyunDemo" -t "SMS_123456" -tp '{"code":"123456"}' --verify

# List & inspect
./scripts/send_sms.sh list-signs
./scripts/send_sms.sh list-templates
./scripts/send_sms.sh query-sign     --sign-name "AliyunDemo"
./scripts/send_sms.sh query-template --template-code "SMS_123456"

# Status & statistics
./scripts/send_sms.sh query-status     -p "13800138000" --send-date "20260326" --biz-id "xxx^0"
./scripts/send_sms.sh query-statistics --start-date "20260301" --end-date "20260326"
./scripts/send_sms.sh query-statistics --start-date "20260301" --end-date "20260326" --is-globe 2

# Filter by signature name and/or template type
./scripts/send_sms.sh query-statistics --start-date "20260301" --end-date "20260326" --sign-name "AliyunDemo" --template-type 0

Parameters

aliyun dysmsapi send-sms

ParameterRequiredDescription
--api-versionYesAPI version, fixed to 2017-05-25
--phone-numbersYesPhone numbers, comma-separated, up to 1000
--sign-nameYesSMS signature name
--template-codeYesSMS template code
--template-paramNoTemplate variables JSON, e.g. '{"code":"123456"}'
--out-idNoExternal tracking ID
--user-agentYesFixed to AlibabaCloud-Agent-Skills/alibabacloud-sms-send-short-message
--read-timeoutYesRead timeout in seconds, recommended value 3

aliyun dysmsapi send-batch-sms (batch send)

ParameterRequiredDescription
--api-versionYesAPI version, fixed to 2017-05-25
--phone-number-jsonYesPhone numbers JSON array, up to 100, e.g. '["138xxx","139xxx"]'
--sign-name-jsonYesSignature names JSON array, must match the phone count
--template-codeYesTemplate code (all phones share the same template)
--template-param-jsonNoTemplate variables JSON array, must match the phone count
--sms-up-extend-code-jsonNoUpstream SMS extension codes JSON array
--out-idNoExternal tracking ID, less than 256 characters
--user-agentYesFixed to AlibabaCloud-Agent-Skills/alibabacloud-sms-send-short-message
--read-timeoutYesRead timeout in seconds, recommended value 3

SendSms vs SendBatchSms: send-sms shares one signature/template across up to 1000 numbers; send-batch-sms lets each phone use a different signature/template params (up to 100 numbers).

aliyun dysmsapi query-send-statistics

ParameterRequiredDescription
--api-versionYesAPI version, fixed to 2017-05-25
--is-globeYesScope: 1 = domestic; 2 = international / HK-Macao-Taiwan
--start-dateYesStart date in yyyyMMdd
--end-dateYesEnd date in yyyyMMdd
--page-indexYesCurrent page, starts from 1
--page-sizeYesPage size, 1~50
--template-typeNo0=verify code, 1=notification, 2=marketing(corp), 3=intl/HK-Macao-Taiwan(corp), 7=digital
--sign-nameNoFilter by signature name
--user-agentYesFixed to AlibabaCloud-Agent-Skills/alibabacloud-sms-send-short-message
--read-timeoutYesRead timeout in seconds, recommended value 3

Response: returns Data.TargetList[] (each entry has SendDate, TotalCount, RespondedSuccessCount, RespondedFailCount, NoRespondedCount) and Data.TotalSize.

Wrapper script options

OptionShortDescription
--phone-numbers-pPhone numbers
--sign-name-sSignature name
--template-code-tTemplate code
--template-param-tpTemplate variables (JSON)
--out-id-oExternal tracking ID
--verify—Verify signature/template before sending
--region-rRegion ID, defaults to cn-hangzhou
--profile—Use the given aliyun CLI profile

Output

Successful send response

{
  "BizId": "114814474505895421^0",
  "Code": "OK",
  "Message": "OK",
  "RequestId": "4C3D8B1B-B3D8-5673-B724-1F251799CE9A"
}

Approval status reference

ValueSignStatus / TemplateStatusDescription
0ReviewingSMS cannot be sent for now
1ApprovedAvailable for sending
2RejectedNeeds revision and resubmission
10CancelledSign/template has been cancelled

Error Handling

Common business error codes

Error codeDescriptionSuggested action
isv.SMS_SIGNATURE_SCENE_ILLEGALSignature/template scene mismatchMake sure signature and template scenes align
isv.SMS_TEMPLATE_ILLEGALTemplate missing or unapprovedVerify the template has been approved
isv.SMS_SIGN_NAME_ILLEGALSignature missing or unapprovedVerify the signature has been approved
isv.MOBILE_NUMBER_ILLEGALBad phone number formatCheck the number format
isv.AMOUNT_NOT_ENOUGHInsufficient account balanceTop up the SMS quota
isv.BUSINESS_LIMIT_CONTROLThrottling triggeredReduce the send rate
SignatureNotFoundSignature not foundCreate the signature in the console
TemplateNotFoundTemplate not foundCreate the template in the console

query-send-details ErrCode = Alibaba isv.*/isp.* (above) + carrier receipts (DELIVERED, MOBILE_NOT_ON_SERVICE, MOBILE_SEND_LIMIT, …). Full table + triage: references/sms-error-codes.md.

CLI configuration errors

Error messageCauseResolution
InvalidAccessKeyId.NotFoundWrong AccessKey IDCheck the AccessKey ID
SignatureDoesNotMatchWrong SecretCheck the AccessKey Secret
Forbidden.RAMInsufficient permissionVerify the RAM user has SMS permissions

Execution Flow

  1. Pre-check: aliyun CLI installed (>= 3.3.3) and dysmsapi plugin available; AI-Mode enabled; credentials configured.
  2. Validate required parameters (phone-numbers, sign-name, template-code). If signature or template is missing, ask the user; after consent call query-sms-sign-list / query-sms-template-list and present approved candidates.
  3. [Optional, --verify] Verify sign via get-sms-sign: require SignStatus=1; also surface SignIspRegisterDetailList[*].RegisterResult to the user as info (unregistered carriers may still deliver — do not block).
  4. [Optional, --verify] Verify template status via get-sms-template (TemplateStatus=1).
  5. Send via aliyun dysmsapi send-sms (or send-batch-sms for per-recipient personalization).
  6. Return result: Code=OK only confirms gateway acceptance — return BizId. To report final delivery to the user, always call query-send-details (Scenario 4); never use the send response as proof of delivery.
  7. [MUST] Disable AI-Mode at every exit (success / failure / cancellation).

Examples

Scenario 1: Send a verification code

# 1) Pull approved signatures & templates first (so the user can pick)
aliyun dysmsapi query-sms-sign-list     --api-version 2017-05-25 --page-index 1 --page-size 50 --user-agent AlibabaCloud-Agent-Skills/alibabacloud-sms-send-short-message --read-timeout 3
aliyun dysmsapi query-sms-template-list --api-version 2017-05-25 --page-index 1 --page-size 50 --user-agent AlibabaCloud-Agent-Skills/alibabacloud-sms-send-short-message --read-timeout 3

# 2) Send (after user confirmation)
aliyun dysmsapi send-sms \
  --api-version 2017-05-25 \
  --phone-numbers "13800138000" \
  --sign-name "YourSign" --template-code "SMS_xxx" \
  --template-param '{"code":"123456"}' \
  --user-agent AlibabaCloud-Agent-Skills/alibabacloud-sms-send-short-message --read-timeout 3

Scenario 2: Bulk-send with same signature & params

aliyun dysmsapi send-sms \
  --api-version 2017-05-25 \
  --phone-numbers "13800138000,13900139000,13700137000" \
  --sign-name "YourSign" --template-code "SMS_xxx" \
  --template-param '{"activity":"Double 11 Sale","discount":"50% OFF"}' \
  --user-agent AlibabaCloud-Agent-Skills/alibabacloud-sms-send-short-message --read-timeout 3

Scenario 3: Batch send with per-recipient personalization

aliyun dysmsapi send-batch-sms \
  --api-version 2017-05-25 \
  --phone-number-json '["13800138000","13900139000","13700137000"]' \
  --sign-name-json    '["BrandA","BrandB","BrandC"]' \
  --template-code "SMS_xxx" \
  --template-param-json '[{"name":"Alice","code":"111111"},{"name":"Bob","code":"222222"},{"name":"Charlie","code":"333333"}]' \
  --user-agent AlibabaCloud-Agent-Skills/alibabacloud-sms-send-short-message --read-timeout 3

Lengths of --phone-number-json, --sign-name-json, and --template-param-json must match and correspond one-to-one.

Scenario 4: Verify delivery & aggregate statistics

# Per-message delivery (uses BizId returned by send-sms)
aliyun dysmsapi query-send-details \
  --api-version 2017-05-25 \
  --phone-number "13800138000" --send-date "20260326" --biz-id "xxx^0" \
  --page-size 10 --current-page 1 \
  --user-agent AlibabaCloud-Agent-Skills/alibabacloud-sms-send-short-message --read-timeout 3

# Range-based aggregated statistics (1 row per send-day)
aliyun dysmsapi query-send-statistics \
  --api-version 2017-05-25 --is-globe 1 \
  --start-date "20260301" --end-date "20260326" \
  --page-index 1 --page-size 10 \
  --user-agent AlibabaCloud-Agent-Skills/alibabacloud-sms-send-short-message --read-timeout 3

QuerySendDetails vs QuerySendStatistics: query-send-details returns per-message records (delivery time, error code) — useful for troubleshooting. query-send-statistics returns aggregated daily counts — useful for trend reporting.

Multi-Environment / Multi-Account

aliyun CLI supports multiple profiles. Prefer env vars or RAM roles:

# Option 1: env vars (recommended)
export ALIBABA_CLOUD_ACCESS_KEY_ID=<your-access-key-id>
export ALIBABA_CLOUD_ACCESS_KEY_SECRET=<your-access-key-secret>

# Option 2: profiles (region only; credentials still come from env vars or RAM role)
aliyun configure set --profile prod --region cn-hangzhou
aliyun configure set --profile test --region cn-shanghai

aliyun dysmsapi send-sms --profile prod \
  --api-version 2017-05-25 \
  --phone-numbers "13800138000" --sign-name "Sign" --template-code "SMS_xxx" \
  --user-agent AlibabaCloud-Agent-Skills/alibabacloud-sms-send-short-message --read-timeout 3

Notes

  1. Plugin install: First-time use requires aliyun plugin install --names dysmsapi.
  2. API version: When calling the CLI directly, --api-version 2017-05-25 is mandatory.
  3. Parameter format: kebab-case (e.g. --phone-numbers, not --PhoneNumbers).
  4. Timeout: --read-timeout 3 is required. After a timeout, query the delivery receipt before deciding whether to retry.
  5. User-Agent: --user-agent AlibabaCloud-Agent-Skills/alibabacloud-sms-send-short-message is required so the server can identify the caller.
  6. Idempotency: SendSms/SendBatchSms are NOT idempotent — prevent duplicate sends at the business layer.
  7. Single vs batch: Prefer send-sms for verification codes; send-batch-sms is only needed when each recipient requires different signature or template params (≤ 100).
  8. Billing: Billing depends on carrier delivery; API success but carrier failure is not billed. QPS limit is 5000/s per user.
  9. Credential safety: Never hard-code AK/SK; always rely on the default credential chain (env vars / ~/.aliyun/config.json / ECS RAM role / OIDC).
  10. Parameter confirmation: Never guess signature/template — always ask the user, and after consent fetch query-sms-sign-list / query-sms-template-list (see "Interactive Parameter Confirmation").
  11. Send-result reporting: send-sms / send-batch-sms responses only confirm gateway acceptance (Code=OK + BizId); they are NOT proof of delivery. Whenever the user asks "did it arrive?" / "was it delivered?", always call query-send-details (use BizId for precise lookup) and surface SendStatus (1=in-flight, 2=failed, 3=delivered) and ErrCode — never reply based on the send-API response alone.

References

Top skills in this category