您可以通过MNS消息队列拉取短信上行消息(SmsUp)。

说明 为优化短信服务底层性能,减少队列调用对您业务的压力,超过3个月无发送量时,MNS消息队列将进入休眠状态,重新发送短信后,MNS队列将自动取消休眠。

前提条件

  • 您已经注册阿里云账号并生成访问密钥(AccessKey),详情请参见AccessKey
  • 确保您可以在本地成功Ping以下三个地址:dysmsapi.aliyuncs.com或mns.cn-hangzhou.aliyuncs.com或dybaseapi.aliyuncs.com。

上行短信消息SmsUp消息体格式

名称 类型 示例 描述
dest_code String 123456 扩展码,发送短信接口SendSms中的SmsUpExtendCode参数传递的值与本参数值相同。
send_time String 2021-09-06 15:53:20 时间。
sequence_id Double 123456 消息序列ID。
phone_number String 159*****532 短信接收号码。
content String 123456 短信内容。

Demo下载

如果使用Java或Node.js语言,请分别下载Java MNS SDK原Node.js MNS SDK。其他语言,请参见短信服务SDK简介

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

示例代码

使用该示例时,您需要注意如下信息。
  • 将AccessKey ID和AccessKey Secret换成您的AccessKey信息。
            String accessKeyId="accessKeyId";
            String accessKeySecret="accessKeySecret";
  • messageType替换适当的消息类型,目前支持:短信上行(SmsUp)、短信回执(SmsReport)。
    String messageType="messageType";
  • queueName是MNS消息队列名称,您可以在短信服务控制台系统设置 > 通用设置页面查到。
    String queueName="queueName";
    回执图片2
  • 以本文示例代码为例,您获取到的上行信息内容由dealMessage方法处理,您可以将需要的上行信息内容的业务逻辑写在该方法中。
    // 根据文档中具体的消息格式进行消息体的解析
    String arg = (String) contentMap.get("arg");
    // 编写您的业务代码
    arg代表回执消息体中的参数,可填写的值为:dest_code、send_time、sequence_id、phone_number、content。
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;

/**
 * 只能用于接收云通信的消息,不能用于接收其他业务的消息
 * 短信上行消息接收demo
 */

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);

        // 此处需要替换成开发者自己的AK信息
        String accessKeyId="accessKeyId";
        String accessKeySecret="accessKeySecret";

        /*
        *  将messageType和queueName替换成您需要的消息类型名称和对应的队列名称
        *云通信产品下所有的回执消息类型:
        *1:短信回执:SmsReport,
        *2:短信上行:SmsUp
        *3:语音呼叫:VoiceReport
        *4:流量直冲:FlowReport
        */
        String messageType="messageType";//此处应该替换成相应产品的消息类型
        String queueName="queueName";//在云通信页面开通相应业务消息后,就能在页面上获得对应的queueName,格式类似Alicom-Queue-xxxxxx-SmsReport
        puller.startReceiveMsg(accessKeyId,accessKeySecret,messageType,queueName,new MyMessageListener());
    }
}