可以通過輕量訊息佇列(原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 | 發送狀態。取值:
|
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。

參數配置
使用該樣本時,您需要先完成以下參數配置。
配置AccessKey
完整樣本
擷取到的狀態報表內容由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運行後輸出效果如下。

