全部产品
Search
文档中心

短信服务:SMS webhook

更新时间:Feb 04, 2026

可以通过轻量消息队列(原MNS)接收短信发送状态报告(SMS webhook)。

前提条件

  • 已经注册阿里云账号并生成访问密钥(AccessKey),详情请参见创建AccessKey

  • 确保运行MNS消息消费程序的网络环境可以访问到以下两个地址:dybaseapi.ap-southeast-1.aliyuncs.com或1493622401794734.mns.ap-southeast-1.aliyuncs.com。

重要

回执消息无法保证幂等性,因此需要自行处理幂等性的问题。我们建议在接收到回执消息后,采取适当的措施来确保数据的正确性和一致性。

短信回执消息SMS webhook消息体格式

名称

类型

示例

描述

To

String

8521234****

短信接收号码。

Status

String

1

发送状态。取值:

  • 1:成功

  • 2:失败

  • 6:失效

MessageId

String

123456789****

发送回执ID。

SmsSize

String

1

短信条数。

长短信将会被拆分为多条发送。

SendDate

String

Thu, 25 Nov 2021 10:27:00 +0800

提交给运营商的时间。

ReceiveDate

String

Thu, 25 Nov 2021 10:27:33 +0800

收到运营商回执的时间。

ErrorCode

String

success

错误码。

ErrorDescription

String

success

错误信息。

示例

{
    "To" : "8521234****",
    "SendDate" : "Thu, 25 Nov 2021 10:27:00 +0800",
    "ReceiveDate" : "Thu, 25 Nov 2021 10:27:33 +0800",
    "Status" : "1",
    "SmsSize":"1",
    "ErrorCode" : "success",
    "ErrorDescription" : "success",
    "MessageId" : "123456789****"
  }

Demo下载

请参见轻量消息队列(原MNS)消费Demo,根据需要的开发语言,完成Demo及SDK的下载。本文后续操作以Java语言为例。

说明
  • Demo下载成功后,部分jar包在lib目录下,需要单击Add as Library完成引入,具体如下图所示。

  • 可在pom.xml文件中查找Maven依赖并安装阿里云Java SDK。

lib

参数配置

使用该示例时,您需要先完成以下参数配置。

配置AccessKey

说明

为避免在代码中硬编码访问密钥(AccessKey)而造成泄露,请通过配置环境变量的方式获取AccessKey。环境变量配置方法,请参见在Linux、macOS和Windows系统配置环境变量

本文以环境变量名ALIBABA_CLOUD_ACCESS_KEY_IDALIBABA_CLOUD_ACCESS_KEY_SECRET为例,进行后续操作。通过环境变量获取AccessKey的代码示例如下:

String accessKeyId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
String accessKeySecret = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");

配置消息类型

请将messageType换成需要的消息类型,如短信回执(SmsReport)。短信服务支持的回执消息类型,请参见回执消息简介与配置流程

String messageType="<MESSAGE_TYPE>";

配置队列名称

请将queueName换成消息队列名称,可以在短信服务控制台,进入系统设置 > 通用设置 > 接口API页面查看。

String queueName="<QUEUE_NAME>";

image

完整示例

获取到的状态报告内容由dealMessage方法处理,可以将需要的下行信息内容的业务逻辑写在该方法中。

// 根据文档中具体的消息格式进行消息体的解析
String arg = (String) contentMap.get("arg");
// 编写您的业务代码

arg代表回执消息体中的参数,可填写的值为:To、Status、MessageId、SmsSize、SendDate、ReceiveDate、ErrorCode、ErrorDescription。

package com.alicom.mns.sample;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


import com.alicom.mns.tools.DefaultAlicomMessagePuller;
import com.alicom.mns.tools.MessageListener;
import com.aliyun.mns.model.Message;
import com.google.gson.Gson;

/**
 * 只能用于接收云通信的消息,不能用于接收其他业务的消息
 */
public class ReceiveDemo {

    private static Log logger=LogFactory.getLog(ReceiveDemo.class);

    static class MyMessageListener implements MessageListener{
        private Gson gson=new Gson();

        @Override
        public boolean dealMessage(Message message) {

            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            //消息的几个关键值
            System.out.println("message receiver time from mns:" + format.format(new Date()));
            System.out.println("message handle: " + message.getReceiptHandle());
            System.out.println("message body: " + message.getMessageBodyAsString());
            System.out.println("message id: " + message.getMessageId());
            System.out.println("message dequeue count:" + message.getDequeueCount());
            System.out.println("Thread:" + Thread.currentThread().getName());
            try{
                Map<String,Object> contentMap=gson.fromJson(message.getMessageBodyAsString(), HashMap.class);

                // 根据文档中具体的消息格式进行消息体的解析
                String arg = (String) contentMap.get("arg");

                // 这里开始编写您的业务代码

            }catch(com.google.gson.JsonSyntaxException e){
                logger.error("error_json_format:"+message.getMessageBodyAsString(),e);
                //理论上不会出现格式错误的情况,所以遇见格式错误的消息,只能先delete,否则重新推送也会一直报错
                return true;
            } catch (Throwable e) {
                //自己的代码部分导致的异常,应该return false,这样消息不会被delete掉,而会根据策略进行重推
                return false;
            }

            //消息处理成功,返回true, SDK将调用MNS的delete方法将消息从队列中删除掉
            return true;
        }

    }

    public static void main(String[] args) throws Exception, ParseException {

        DefaultAlicomMessagePuller puller=new DefaultAlicomMessagePuller();

        //设置异步线程池大小及任务队列的大小,还有无数据线程休眠时间
        puller.setConsumeMinThreadSize(6);
        puller.setConsumeMaxThreadSize(16);
        puller.setThreadQueueSize(200);
        puller.setPullMsgThreadSize(1);
        //和服务端联调问题时开启,平时无需开启,消耗性能
        puller.openDebugLog(false);

        // 从本地环境变量获取AccessKey ID和AccessKey Secret信息
        String accessKeyId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
        String accessKeySecret = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");

        /*
        *  将messageType和queueName替换成需要的消息类型名称和对应的队列名称
        *  云通信产品下所有的回执消息类型:
        *  1:短信回执:SmsReport,
        *  2:短信上行:SmsUp       
        *  3:国际短信回执:GlobeSmsReport
        */
        String messageType="<MESSAGE_TYPE>"; //此处应该替换成相应产品的消息类型,目前支持SmsReport。
        String queueName="<QUEUE_NAME>"; //在云通信页面开通相应业务消息后,就能在页面上获得对应的queueName,格式类似Alicom-Queue-******-SmsReport
        puller.startReceiveMsg(accessKeyId,accessKeySecret,messageType,queueName,new MyMessageListener());
    }
}

Demo运行后输出效果如下。

image