更新时间:2018-12-29 13:49
当您使用隐私号码服务绑定一组AXB(或者AXN、以下统一以AXB为代表说明)隐私关系后,可以通过使用MNS的Queue模型来接收话单回执消息,话单回执消息时记录了AXB三元组发生的所有的通话记录行为。
云通信的所有业务消息都用过MNS消息服务向外发送。用户每订阅一个类别的消息(比如隐私号码话单回执消息(SecretReport),系统都会为用户分配一个独立的消息队列。用户可以通过阿里云账号拿到一个临时的token用于获取队列中的消息。用户可以下载demo,编写简单的消息处理类即可完成消息处理的任务。在页面上订阅消息,订阅完消息后,能拿到消息队列名称(queueName)。比如:Alicom-Queue-xxxxxx-SecretReport 。队列名字每个用户都不同。
呼叫发起时话单回执消息SecretStartReport
名称 | 类型 | 描述 | 示例 | 是否必须 |
---|---|---|---|---|
pool_key | String | 对应的号池Key | FC1234567 | 必须 |
sub_id | Long | 通话对应的三元组的绑定关系ID | 123456 | 必须 |
call_id | String | 唯一标识一通通话记录的ID | abcdef1234 | 必须 |
phone_no | String | AXB中的A号码 | 15000000000 | 必须 |
secret_no | String | AXB中的X号码 | 1700000000 | 必须 |
peer_no | String | AXB中的B号码或者N号码 | 1580000000 | 必须 |
called_display_no | String | 被叫显号 | 1580100000 | 必须 |
call_type | Interger | 呼叫类型 | 0:主叫(phone_no打给peer_no);1:被叫(peer_no打给phone_no);2:短信发送;3:短信接收; 4:呼叫拦截; 5:短信收发拦截 | 必须 |
call_time | String | 主叫拨打时间 | “2017-09-01 12:00:00” | 必须 |
out_id | String | 外部业务ID | 123456 | 可选 |
隐私号码目前提供一种消息类型,话单回执消息SecretReport
名称 | 类型 | 描述 | 示例 | 是否必须 |
---|---|---|---|---|
pool_key | String | 对应的号池Key | FC1234567 | 必须 |
sub_id | Long | 通话对应的三元组的绑定关系ID | 123456 | 必须 |
call_id | String | 唯一标识一通通话记录的ID | abcdef1234 | 必须 |
phone_no | String | AXB中的A号码 | 15000000000 | 必须 |
secret_no | String | AXB中的X号码 | 1700000000 | 必须 |
peer_no | String | AXB中的B号码或者N号码 | 1580000000 | 必须 |
called_display_no | String | 被叫显号 | 1580100000 | 必须 |
call_type | Interger | 呼叫类型 | 0:主叫(phone_no打给peer_no);1:被叫(peer_no打给phone_no);2:短信发送;3:短信接收; 4:呼叫拦截; 5:短信收发拦截 | 必须 |
call_time | String | 主叫拨打时间 | “2017-09-01 12:00:00” | 必须 |
start_time | String | 被叫接听时间 | “2017-09-01 12:01:00” | 必须 |
ring_time | String | 呼叫送被叫端局时,被叫端局响应的时间 | “2017-09-01 12:01:00” | 必须 |
free_ring_time | String | 被叫手机真实的振铃时间,free_ring_time > call_out_time代表被叫真实发生了振铃事件, 相等代表未振铃 | “2017-09-01 12:01:00” | 必须 |
release_time | String | 被叫挂断时间,release_time - start_time 代表通话时长 如果结果为0,代表呼叫未接通 | “2017-09-01 12:02:00” | 必须 |
sms_number | Interger | 短信长度 | “2017-09-01 12:01:00” | 可选 |
release_dir | Interger | 通话释放方向,0代表平台释放 1代表主叫挂断 2代表被叫挂断 | 0 | 必须 |
out_id | String | 外部业务ID | 123456 | 可选 |
release_cause | Interger | 释放原因 1:未分配的号码 2:无路由到指定的转接网 3:无路由到目的地 4:发送专用信息音 16:正常的呼叫拆线 17:用户忙 18:用户未响应 19:用户未应答 20:用户缺席 21:呼叫拒收 22:号码改变 27:目的地不可达 28:无效的号码格式(地址不全) 29:性能拒绝 31:正常—未指定 34: 无电路/通路可用 42: 交换设备拥塞 50:所请求的性能未预定 53:CUG中限制去呼叫 55: CUG中限制来呼叫 57:承载能力无权 58:承载能力目前不可用 65:承载能力未实现 69:所请求的性能未实现 87:被叫用户不是CUG的成员 88:不兼容的目的地 90:不存在的CUG 91:无效的转接网选择 95:无效的消息,未指定 97:消息类型不存在或未实现 99:参数不存在或未实现 102:定时器终了时恢复 103:参数不存在或未实现—传递 110:消息带有未被识别的参数—舍弃 111:协议错误,未指定 127:互通,未指定 |
1 | 可选 |
下载对应语音的消息DEMO工程,工程所需要的所有依赖jar包都放在DEMO工程的lib目录下,将对于的jar包引入到您的工程当中既可按照DEMO样例编写接收消息的程序。
SDK&DEMO【下载地址】
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Aliyun.Acs.Core;
using Aliyun.Acs.Core.Exceptions;
using Aliyun.Acs.Core.Profile;
using Aliyun.Acs.Dybaseapi.Model.V20170525;
//using Aliyun.Acs.Dybaseapi.Model.V20170525.QueryTokenForMnsQueueResponse.MessageTokenDTO_;
using Aliyun.MNS;
using Aliyun.MNS.Model;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApplication7
{
class Program
{
private static int maxThread = 2;
static String accessId = "yourAccessId";
static String accessSecret = "yourAccessSecret";
static String messageType = "SecretReport";//消息类型目前有4种. 短信回执:SmsReport; 短信上行:SmsUp; 语音回执:VoiceReport; 流量回执:FlowReport;小号话单回执:SecretReport
static String queueName = "Alicom-Queue-xxxxxxx-SecretReport";// 短信上行的队列名称. 格式是 "前缀(Alicom-Queue-)+阿里云uid+消息类型"
static String domainForPop = "dybaseapi.aliyuncs.com";
static String regionIdForPop = "cn-hangzhou";
static String productName = "Dybaseapi";
static IAcsClient acsClient = null;
public static IAcsClient InitAcsClient(String regionIdForPop, String accessId, String accessSecret, String productName, String domainForPop)
{
IClientProfile profile = DefaultProfile.GetProfile(regionIdForPop, accessId, accessSecret);
DefaultProfile.AddEndpoint(regionIdForPop, regionIdForPop, productName, domainForPop);
IAcsClient acsClient = new DefaultAcsClient(profile);
return acsClient;
}
// 初始化环境
private static void InitData()
{
acsClient = InitAcsClient(regionIdForPop, accessId, accessSecret, productName, domainForPop);
}
static void Main(string[] args)
{
InitData();
for (int i = 0; i < maxThread; i++)
{
TestTask testTask = new TestTask("PullMessageTask-thread-" + i, messageType, queueName, acsClient);
Thread t = new Thread(new ThreadStart(testTask.Handle));
//启动线程
t.Start();
}
Console.ReadKey();
}
}
class TestTask
{
private object o = new object();
private int sleepTime = 50;
public String name { get; private set; }
public String messageType { get; private set; }
public String queueName { get; private set; }
public int TaskID { get; private set; }
public IAcsClient acsClient { get; private set; }
public TestTask(String name, String messageType, String queueName, IAcsClient acsClient)
{
this.name = name;
this.messageType = messageType;
this.queueName = queueName;
this.acsClient = acsClient;
}
long bufferTime = 60 * 2;//过期时间小于2分钟则重新获取,防止服务器时间误差
String mnsAccountEndpoint = "https://1943695596114318.mns.cn-hangzhou.aliyuncs.com/";//阿里通信消息的endpoint,固定
Dictionary<string, QueryTokenForMnsQueueResponse.MessageTokenDTO_> tokenMap = new Dictionary<string, QueryTokenForMnsQueueResponse.MessageTokenDTO_>();
Dictionary<string, Queue> queueMap = new Dictionary<string, Queue>();
public QueryTokenForMnsQueueResponse.MessageTokenDTO_ GetTokenByMessageType(IAcsClient acsClient, String messageType)
{
QueryTokenForMnsQueueRequest request = new QueryTokenForMnsQueueRequest();
request.MessageType = messageType;
QueryTokenForMnsQueueResponse queryTokenForMnsQueueResponse = acsClient.GetAcsResponse(request);
QueryTokenForMnsQueueResponse.MessageTokenDTO_ token = queryTokenForMnsQueueResponse.MessageTokenDTO;
return token;
}
/// 处理消息
public void Handle()
{
while (true)
{
try
{
QueryTokenForMnsQueueResponse.MessageTokenDTO_ token = null;
Queue queue = null;
lock (o)
{
if (tokenMap.ContainsKey(messageType))
{
token = tokenMap[messageType];
}
if (queueMap.ContainsKey(queueName))
{
queue = queueMap[queueName];
}
TimeSpan ts = new TimeSpan(0);
if (token != null)
{
DateTime b = Convert.ToDateTime(token.ExpireTime);
DateTime c = Convert.ToDateTime(DateTime.Now);
ts = b - c;
}
if (token == null || ts.TotalSeconds < bufferTime || queue == null)
{
token = GetTokenByMessageType(acsClient, messageType);
IMNS client = new Aliyun.MNS.MNSClient(token.AccessKeyId, token.AccessKeySecret, mnsAccountEndpoint, token.SecurityToken);
queue = client.GetNativeQueue(queueName);
if (tokenMap.ContainsKey(messageType))
{
tokenMap.Remove(messageType);
}
if (queueMap.ContainsKey(queueName))
{
queueMap.Remove(queueName);
}
tokenMap.Add(messageType, token);
queueMap.Add(queueName, queue);
}
}
BatchReceiveMessageResponse batchReceiveMessageResponse = queue.BatchReceiveMessage(16);
List<Message> messages = batchReceiveMessageResponse.Messages;
for (int i = 0; i <= messages.Count - 1; i++)
{
try
{
byte[] outputb = Convert.FromBase64String(messages[i].Body);
string orgStr = Encoding.UTF8.GetString(outputb);
System.Console.WriteLine(orgStr);
//TODO 具体消费逻辑,待客户自己实现.
//消费成功的前提下删除消息
queue.DeleteMessage(messages[i].ReceiptHandle);
}
catch (Exception e)
{
System.Console.WriteLine("Hello World!", e);
}
}
}
catch (Exception e)
{
System.Console.WriteLine("Handle exception", e);
}
Thread.Sleep(sleepTime);
}
}
}
}
在文档使用中是否遇到以下问题
更多建议
匿名提交