您可以通過輕量消息隊列(原MNS)拉取短信上行消息(SmsUp)。
前提條件
已注冊阿里云賬號并生成訪問密鑰(AccessKey),詳情請參見創建RAM用戶的AccessKey。
確保可以在本地ping通以下地址:
dysmsapi.aliyuncs.com
或mns.cn-hangzhou.aliyuncs.com
或dybaseapi.aliyuncs.com
。已閱讀回執消息配置,了解回執消息模式、類型和配置流程。
SmsUp消息體格式
名稱 | 類型 | 示例 | 描述 |
dest_code | String | 123456 | 短信擴展號碼,系統后臺自動生成,不支持自定義傳入。 |
send_time | String | 2021-09-06 15:53:20 | 運營商推送上行時間。 |
sequence_id | Double | 123456 | 消息序列ID。 |
phone_number | String | 159****0532 | 短信接收號碼。 |
content | String | 123456 | 短信內容。 |
Demo下載
請參見輕量消息隊列(原MNS)消費Demo,根據您需要的開發語言,完成Demo及SDK的下載。本文后續操作以Java語言為例。
Demo下載成功后,部分jar包在lib目錄下,您需要單擊Add as Library完成引入,具體如下圖所示。
可在pom.xml文件中查找Maven依賴并安裝阿里云Java SDK。
參數配置
使用該示例時,您需要先完成以下參數配置。
配置AccessKey
為避免在代碼中硬編碼訪問密鑰(AccessKey)而造成泄露,請通過配置環境變量的方式獲取AccessKey。環境變量配置方法,請參見在Linux、macOS和Windows系統配置環境變量。
本文以環境變量名ALIBABA_CLOUD_ACCESS_KEY_ID
和ALIBABA_CLOUD_ACCESS_KEY_SECRET
為例,進行后續操作。通過環境變量獲取AccessKey的代碼示例如下:
String accessKeyId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
String accessKeySecret = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
配置消息類型
請將messageType
換成您需要的消息類型,如短信上行(SmsUp)。短信服務支持的回執消息類型,請參見回執消息配置。
String messageType="<MESSAGE_TYPE>";
配置隊列名稱
請將queueName
換成消息隊列名稱,您可以在短信服務控制臺,進入 頁面查看。
String queueName="<QUEUE_NAME>";
完整示例
您獲取到的上行信息內容由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;
/**
* 只能用于接收云通信的消息,不能用于接收其他業務的消息
*/
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>"; //此處應該替換成相應產品的消息類型
String queueName="<QUEUE_NAME>"; //在云通信頁面開通相應業務消息后,就能在頁面上獲得對應的queueName,格式類似Alicom-Queue-******-SmsUp
puller.startReceiveMsg(accessKeyId,accessKeySecret,messageType,queueName,new MyMessageListener());
}
}
Demo運行后輸出效果如下。