华为云消息&短信 MSGSMS 完整对接技术指南:从零基础到生产部署
一、消息&短信 MSGSMS 服务概述与前置条件
消息&短信(Message & SMS,MSGSMS)是华为云携手全球多家优质运营商和渠道,为企业用户提供的稳定通信服务。通过调用API或使用群发助手,可以快速实现验证码、通知类短信的发送。MSGSMS支持国内短信和国际/港澳台短信两类业务场景:国内短信支持三网合一专属通道,向中国大陆号码发送验证码、通知和推广短信;国际短信则支持向全球号码发送多种语言的验证码和通知消息,但不支持接收用户回复短信。使用该服务前,用户需完成企业实名认证,消息&短信服务仅面向企业用户开放。已完成实名认证的企业账号登录华为云控制台后,在消息&短信产品页面勾选同意服务协议即可完成开通。
需要先登录华为云控制台,点击:华为云控制台,还没有账号,点击:注册并关联,已有账号点击:登录后关联
二、短信应用、签名与模板的核心配置
MSGSMS的接入配置分为三个递进步骤:短信应用、短信签名、短信模板。三者之间存在严格的前置依赖关系,配置顺序不当会导致后续API调用失败。
2.1 创建短信应用
短信应用是用户使用华为云短信服务的载体,控制台路径为:国内短信 → 应用管理。登录短信控制台后,单击“添加应用”开始创建。应用名称用户自定义,支持中文、英文字母、数字及_.-@符号,最长64个字符,该名称仅用于控制台显示,与API调用无关。创建成功后,系统会自动分配全局唯一的Application Key和Application Secret,并提供APP接入地址。其中Application Key和Application Secret是用户身份的唯一标识,调用短信业务API时必须携带用于认证鉴权。中国大陆短信应用最多可创建2个,如有特殊业务需求需提交工单申请扩展。
创建应用时还可配置以下高级参数:
- 上行短信接收地址:用户收到短信后回复短信时,MSGSMS可通过该地址将上行内容推送给业务方,需配置能接收HTTP请求的公网URL
- 短信状态报告批量接收地址:业务方批量接收短信发送状态报告的回调地址
- IP白名单:最多配置100个IP,配置生效约10~15分钟,用于限制调用来源
- 推送AKSK鉴权:开启后平台的推送请求将携带鉴权字段,用于业务方校验推送来源
2.2 申请短信签名
国内短信必须携带签名,例如〖华为云〗,需提前申请并经运营商审核通过后方可使用。控制台路径为:国内短信 → 签名管理。签名类型包括验证码类、通知类和推广类,签名名称应与实际业务场景相符。签名申请提交后进入审核状态,审核通过后记录的签名通道号(如csms100000001)就是API调用时的sender参数。通道号对应的签名类型必须与模板ID对应的模板类型一致。
2.3 创建短信模板
短信模板由纯固定文本或固定文本加变量组成,创建后只有变量部分可按规则替换为指定内容。控制台路径为:国内短信 → 模板管理。华为云的变量格式与主流云平台相近,常用写法为${变量名},例如验证码模板内容:"验证码:${code},如非本人操作请忽略本短信"。模板审核通过后记录模板ID,API调用时作为template_id参数使用。创建模板时需要注意模板内容与签名类型的业务一致性,例如验证码模板不得包含营销推广内容。
三、短信发送的核心API详解
MSGSMS提供了REST风格API,支持使用HTTPS协议通过域名请求调用,调用方法可参考官方API文档。核心发送接口为/sms/batchSendSms/v1,采用POST方法,请求body中的参数需要urlencode编码。
3.1 请求参数详解
发送短信API的主要请求参数如下:
- to:目标手机号,支持单个或多个号码,多个号码以英文逗号分隔,每个号码最大长度21位,最多允许携带500个号码
- template_id:短信模板ID,从模板管理中获取
- template_params:模板变量参数数组,按照模板中变量出现的顺序传入实际值
- signature:签名通道号(中国大陆短信必填),从签名申请中获取
- from:通道号(可选),未填写时默认取模板所属签名通道号
值得注意的是,当to参数携带的号码中包含除数字和+之外的其他字符时,则无法向该参数携带的所有号码发送短信。如果超过500个号码,则全部号码都会发送失败。此外,根据短信内容长度,一条长短信可能会被拆分为多条短信发送,收费按拆分后的实际条数计算。
3.2 WSSE鉴权方式
MSGSMS支持X-WSSE和特殊AK/SK两种鉴权方式。WSSE鉴权方式的Authorization请求头取值为WSSE realm="SDP",profile="UsernameToken",type="Appkey"。同时需要携带X-WSSE头,取值为UsernameToken Username="app_key的值", PasswordDigest="PasswordDigest的值", Nonce="随机数", Created="随机数生成时间"。
PasswordDigest的计算规则为:PasswordDigest = Base64(SHA256(Nonce + Created + Password)),直接使用Nonce、Created、Password拼接后的字符串进行SHA256加密,字符串中无需包含+号和空格。其中Password为app_secret的值。使用WSSE方式鉴权时,生成随机数的时间与发送请求时的本地时间的差值不能超过24小时,否则会导致鉴权失败。
3.3 特殊AK/SK鉴权方式
使用特殊AK/SK鉴权时,Authorization请求头取值为SDK-HMAC-SHA256 Access=app_key的值, SignedHeaders=参与签名的头域(小写), Signature=经过签名算法计算得到的值。具体计算方式可参考华为云API签名算法文档。这种方式需要携带X-Sdk-Date头,生成随机数的时间与发送请求时的本地时间的差值不能超过15分钟。建议开发者优先选择WSSE方式,其实现相对简洁且不易出现时间同步问题。
3.4 Python代码示例
# -*- coding: utf-8 -*-
import requests
import base64
import hashlib
import uuid
import datetime
import urllib.parse
def send_sms(api_addr, app_key, app_secret, sender, template_id, signature, to, template_params):
url = f"{api_addr}/sms/batchSendSms/v1"
# 生成WSSE鉴权参数
nonce = str(uuid.uuid4()).replace('-', '')
created = datetime.datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%SZ')
password_digest_base64 = base64.b64encode(
hashlib.sha256((nonce + created + app_secret).encode('utf-8')).digest()
).decode('utf-8')
# 构建请求头
headers = {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'WSSE realm="SDP",profile="UsernameToken",type="Appkey"',
'X-WSSE': f'UsernameToken Username="{app_key}", PasswordDigest="{password_digest_base64}", Nonce="{nonce}", Created="{created}"'
}
# 构建请求体
body = {
'from': sender,
'to': to,
'templateId': template_id,
'templateParas': template_params,
'signature': signature
}
response = requests.post(url, data=body, headers=headers)
return response.json()
# 调用示例
api_addr = "https://smsapi.cn-north-4.myhuaweicloud.com:443"
app_key = "your_app_key"
app_secret = "your_app_secret"
sender = "csms100000001" # 通道号
template_id = "your_template_id"
signature = "your_signature"
to = "138****0000"
template_params = ["123456"] # 对应模板中的变量值
result = send_sms(api_addr, app_key, app_secret, sender, template_id, signature, to, template_params)
print(result)
上述代码展示了使用Python语言调用发送短信API的完整流程。需要注意的是,API接入地址必须与应用所在区域保持一致。华北-北京四区域的接入地址示例为https://smsapi.cn-north-4.myhuaweicloud.com:443。对于生产环境,建议将app_key和app_secret存放在环境变量或配置文件中,避免硬编码造成的安全风险。
3.5 Java代码示例
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.MessageDigest;
import java.util.Base64;
import java.util.UUID;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
public class SmsSender {
public static String sendSms(String apiAddr, String appKey, String appSecret,
String sender, String templateId, String signature,
String to, String templateParams) throws Exception {
String urlString = apiAddr + "/sms/batchSendSms/v1";
URL url = new URL(urlString);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
// 生成WSSE鉴权参数
String nonce = UUID.randomUUID().toString().replace("-", "");
String created = ZonedDateTime.now().format(DateTimeFormatter.ISO_INSTANT);
String passwordDigestBase64 = Base64.getEncoder().encodeToString(
MessageDigest.getInstance("SHA-256").digest((nonce + created + appSecret).getBytes("UTF-8"))
);
// 设置请求头
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.setRequestProperty("Authorization", "WSSE realm=\"SDP\",profile=\"UsernameToken\",type=\"Appkey\"");
conn.setRequestProperty("X-WSSE", String.format(
"UsernameToken Username=\"%s\", PasswordDigest=\"%s\", Nonce=\"%s\", Created=\"%s\"",
appKey, passwordDigestBase64, nonce, created
));
// 构建请求体
String body = String.format("from=%s&to=%s&templateId=%s&templateParas=%s&signature=%s",
sender, to, templateId, templateParams, signature);
try (OutputStream os = conn.getOutputStream()) {
os.write(body.getBytes("UTF-8"));
}
// 读取响应
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder response = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
response.append(line);
}
br.close();
return response.toString();
}
public static void main(String[] args) throws Exception {
String result = sendSms(
"https://smsapi.cn-north-4.myhuaweicloud.com:443",
"your_app_key",
"your_app_secret",
"csms100000001",
"your_template_id",
"your_signature",
"138****0000",
"[\"123456\"]"
);
System.out.println(result);
}
}
上述Java代码使用了标准的HttpURLConnection实现,未依赖第三方HTTP库,便于在各种Java环境中运行。如果希望使用发送短信SDK进行短信发送,需在pom.xml中引入huaweicloud-sdk-msgsms依赖,SDK版本号可从华为云SDK开发中心获取。使用SDK可以简化认证流程,并自动处理请求重试和错误重试策略。
四、SDK集成与API Explorer调试工具
华为云官方为MSGSMS提供了Java、Python、Go、Node.js、.NET等多语言服务端SDK。开发者可以直接集成SDK来调用MSGSMS的应用、签名、模板、发送短信相关API,从而实现对MSGSMS服务的快速操作。
Node.js SDK安装命令示例:
npm install @huaweicloud/huaweicloud-sdk-core
npm install @huaweicloud/huaweicloud-sdk-msgsms
Node.js SDK代码示例:
const core = require('@huaweicloud/huaweicloud-sdk-core');
const msgsms = require('@huaweicloud/huaweicloud-sdk-msgsms/v2/public-api');
const ak = process.env.CLOUD_SDK_AK;
const sk = process.env.CLOUD_SDK_SK;
const auth = new core.BasicCredentials().withAk(ak).withSk(sk);
const client = msgsms.MsgsmsClient.newBuilder()
.withCredential(auth)
.withRegion("cn-north-4")
.build();
const request = new msgsms.CreateAppRequest();
request.body = new msgsms.SmsAppAddReq();
client.createApp(request).then(result => {
console.log(JSON.stringify(result));
}).catch(err => {
console.error(err);
});
推荐开发者使用API在线调试工具API Explorer。该工具支持快速调试和检索,调试API的同时,可以根据您的参数实时生成各种开发语言的SDK示例代码,方便您直接根据示例代码使用SDK。对于初次接触MSGSMS的开发者来说,这是一个快速上手的利器。
五、群发助手使用指南
除了代码调用API发送短信外,MSGSMS还提供群发助手功能,适用于无需编程的批量短信发送场景。通过群发助手发送短信时,请登录短信控制台,选择“群发助手 > 任务管理 > 发送任务记录”查看发送详情。群发助手的优势在于:无需编写代码、支持Excel模板批量导入接收号码、可视化操作界面、实时查看发送进度和结果统计。但需要注意的是,群发助手不支持动态变量替换,建议用于内容固定不变的通知类短信场景。
六、上行短信接收与状态报告回调
6.1 上行短信接收
用户收到短信后可以回复内容,MSGSMS平台可以将用户回复的短信通过回调推送给业务方。要使用此功能,必须在创建或修改短信应用时正确配置上行短信接收地址。当用户回复短信时,平台会主动向配置的公网URL推送HTTP请求,业务方需开发对应的接口来接收和解析这些上行内容。
目前暂不支持在控制台查询上行短信记录,因此对于需要处理用户回复的业务场景(如短信互动、问卷调查),必须提前配置好接收地址。接收上行短信的接口示例:
@RestController
@RequestMapping("/sms")
public class SmsCallbackController {
@PostMapping("/upstream")
public String receiveUpstream(@RequestBody String requestBody) {
// 解析URL编码后的请求体
// 参数包含:mobile(发送方号码)、content(回复内容)、sign(签名)、sendTime等
// 业务逻辑处理
return "success";
}
}
6.2 状态报告批量接收
如果业务方需要批量接收短信发送状态报告,则需在控制台的应用管理中设置短信状态报告批量接收地址。配置后,MSGSMS平台会主动推送每条短信的发送状态,包括成功、失败、运营商返回的错误码等信息。用户服务器若有IP白名单配置,请联系运营经理获取短信平台IP地址并加入白名单。
状态报告回调接口需要注意:MSGSMS平台会对状态报告进行批量推送,业务方的接收接口应支持批量处理逻辑,接收后需尽快返回HTTP 200响应以避免超时重试。同时建议开启推送AKSK鉴权功能,对平台发送的HTTP消息进行身份校验,防止恶意伪造请求。开启推送AKSK鉴权时,必须配置推送AK和推送SK,配置后生效时间约需5分钟。
七、业务统计分析与费用计费规则
7.1 业务统计查询
MSGSMS支持查看和导出全球短信的业务统计详情,控制台路径:左侧导航树中的业务统计页面。可按国家/地区、短信应用、短信类型、短信模板等维度进行筛选。查询一天的数据时业务统计以小时为单位呈现;查询大于1天的数据时以天为单位呈现。统计指标包括合计提交总数、合计提交成功数、合计提交失败数、合计发送成功数、合计发送失败数及对应的成功率。如果统计数据有发送失败记录,可以单击查看失败详情,根据发送结果和状态码排查故障原因。
7.2 计费规则详解
短信服务采用发送即计费的规则,即调用接口或群发助手成功则计费。以下情况不收费:status或状态码为华为平台错误码(如认证失败、参数校验失败)。当华为云账户余额为零但状态正常时,仍可成功发送短信。如果未购买短信套餐包或已发送短信的业务类型与已购买的短信套餐包类型不符,发送成功的短信将产生按需计费,费用从华为云账户余额中划扣。购买套餐包后发送短信优先扣除套餐包额度,超出部分按需计费,套餐包额度计算在阶梯内。
计费注意事项:当华为云账户处于欠费冻结状态时,将无法使用短信服务,也无法使用短信套餐包剩余额度。若用户发送的是一条长短信,运营商会依照标准短信协议对其进行拆分,按拆分后的短信条数收费。因此对于长短信应用场景,需要提前评估拆条数对成本的影响。
八、常见问题解答
问1:IAM用户能否使用消息&短信服务?
答:可以。主账号可在IAM中创建用户并授予MSGSMS相关权限,IAM用户即可使用消息&短信服务。建议采用最小权限原则,按需分配短信发送和查询权限,避免主账号密钥泄露风险。
问2:短信接口是否支持ECS服务器内网调用?
答:不支持。短信接口不支持内网调用。如果使用华为云弹性云服务器发送短信,需申请绑定弹性IP地址,通过公网访问短信服务。
问3:签名和模板审核需要多长时间?
答:审核时间一般为1~2个工作日,具体时长取决于提交材料的完整性和运营商审核排期。建议提前规划业务上线时间,优先完成签名和模板的审核流程。
问4:如何快速测试API是否配置正确?
答:推荐使用API Explorer在线调试工具。该工具支持快速调试和检索,调试API的同时,可以实时生成多种开发语言的SDK示例代码,方便直接复制使用。调试通过后再集成到业务系统中。
问5:发送成功但用户收不到短信,如何排查?
答:首先在控制台业务统计页面查看短信发送状态和错误码,区分是发送成功但运营商未送达,还是发送即失败。若发送成功但用户未收到,建议检查用户手机信号、黑名单拦截、号码携号转网等情况,或提交工单联系华为云客服获取运营商侧的状态详情。



