更新时间:2024-09-24 GMT+08:00
C#
|
样例 |
|
|---|---|
|
环境要求 |
.NET Core 2.0及以上版本或.NET Framework 4.7.1及以上版本。 |
|
引用库 |
Newtonsoft.Json 11.0.2,请参考https://www.newtonsoft.com/json获取。 |
- 本文档所述Demo在提供服务的过程中,可能会涉及个人数据的使用,建议您遵从国家的相关法律采取足够的措施,以确保用户的个人数据受到充分的保护。
- 本文档所述Demo仅用于功能演示,不允许客户直接进行商业使用。
- 本文档信息仅供参考,不构成任何要约或承诺。
“语音通知API”代码样例
using Newtonsoft.Json;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Security.Cryptography;
using System.Text;
namespace voicecall_csharp_demo_x_aksk_
{
class VoiceNotify
{
string base_url = "https://{domain}:{port}"; //APP接入地址,购买服务时下发,,请替换为实际值
string appKey = "***appKey***"; //语音通知应用的appKey,购买服务时下发,请替换为实际值
string appSecret = "***appSecret***"; //语音通知应用的appSecret,购买服务时下发,请替换为实际值
static void Main(string[] args)
{
//构造放音列表,此处取值仅为样例,请替换为实际值
ArrayList playInfoList = getPlayInfoList("notifyvoice.wav", "xxxxxx", ["3", "人民公园正门"]);
//固话号码从控制台号码管理页获取,被叫号码请替换为实际号码.
voiceNotifyAPI("+86531*******4", "+86135*******1", playInfoList);
}
static void voiceNotifyAPI(string displayNbr, string calleeNbr, ArrayList playInfoList)
{
if (String.IsNullOrEmpty(displayNbr) || String.IsNullOrEmpty(calleeNbr) || Count(playInfoList) < 1)
{
return;
}
string apiURI = "/rest/httpsessions/callnotify/v2.0"; //接口URI, v1.0 or v2.0
string requestUrl = base_url + apiURI;
try
{
//为防止因HTTPS证书认证失败造成API调用失败,需要先忽略证书信任问题
//.NET Framework 4.7.1及以上版本,请采用如下代码
var sslHandler = new HttpClientHandler()
{
ServerCertificateCustomValidationCallback = (message, cert, chain, err) => { return true; }
};
HttpClient client = new HttpClient(sslHandler, true);
//低于.NET Framework 4.7.1版本,请采用如下代码
//HttpClient client = new HttpClient();
//ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
//请求Headers
client.DefaultRequestHeaders.Add("Authorization", "AKSK realm=\"SDP\",profile=\"UsernameToken\",type=\"Appkey\"");
client.DefaultRequestHeaders.Add("X-AKSK", buildAKSKHeader(appKey, appSecret));
//请求Body
var body = new Dictionary<string, object>() {
/*必填参数*/
{"displayNbr", displayNbr},//主叫用户手机终端的来电显示号码。
{"calleeNbr", calleeNbr},//发起呼叫时所拨打的被叫号码。
{"playInfoList", playInfoList}//播放信息列表,最大支持5个,每个播放信息携带的参数都可以不相同。
/*选填参数*/
//{"statusUrl", ""}, //设置SP接收状态上报的URL,要求使用BASE64编码
//{"feeUrl", ""}, //设置SP接收话单上报的URL,要求使用BASE64编码
//{"returnIdlePort", "false"}, //指示是否需要返回平台空闲呼叫端口数量
//{"userData", "customerId123"} //设置用户的附属信息
};
HttpContent content = new StringContent(JsonConvert.SerializeObject(body));
//请求Headers中的Content-Type参数
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
var response = client.PostAsync(requestUrl, content).Result;
Console.WriteLine(response.StatusCode);
var res = response.Content.ReadAsStringAsync().Result;
Console.WriteLine(res); //打印响应结果
}
catch (Exception e)
{
Console.WriteLine(e.StackTrace);
Console.WriteLine(e.Message); //打印错误信息
}
}
static string buildAKSKHeader(string appKey, string appSecret)
{
string now = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssZ"); //Created
string nonce = Guid.NewGuid().ToString().Replace("-", ""); //Nonce
String str = nonce + now;
byte[] keyByte = Encoding.UTF8.GetBytes(appSecret);
byte[] messageBytes = Encoding.UTF8.GetBytes(str);
using (var hmacsha256 = new HMACSHA256(keyByte))
{
byte[] hashmessage = hmacsha256.ComputeHash(messageBytes);
string base64 = Convert.ToBase64String(hashmessage);
return String.Format("UsernameToken Username=\"{0}\",PasswordDigest=\"{1}\",Nonce=\"{2}\",Created=\"{3}\"",
appKey, base64, nonce, now);
}
}
static ArrayList getPlayInfoList(string notifyVoice, string templateId, string[] templateParas)
{
ArrayList playInfoList = new ArrayList(); //播放信息列表,最大支持5个
/*此处以构建一个playInfoDic,添加到playInfoList为例,请按需构建多个*/
Dictionary<string, object> playInfoDic = new Dictionary<string, object>();
playInfoDic.Add("notifyVoice", notifyVoice);
playInfoDic.Add("templateId", templateId);
playInfoDic.Add("templateParas", templateParas);
//playInfoDic.Add("collectInd", 0); //是否进行收号
//playInfoDic.Add("replayAfterCollection", "false"); //设置是否在收号后重新播放notifyVoice或templateId指定的放音
//playInfoDic.Add("collectContentTriggerReplaying", "1"); //设置触发重新放音的收号内容
playInfoList.Add(playInfoDic); //playInfoList添加元素
return playInfoList;
}
//低于.NET Framework 4.7.1版本,启用如下方法
//static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
//{
// return true;
//}
}
}
“呼叫状态通知API”代码样例
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
namespace voicecall_csharp_demo_x_aksk_
{
class CallEventImpl
{
static void Main(string[] args)
{
//呼叫事件通知样例
string jsonBody = JsonConvert.SerializeObject(new Dictionary<string, object>(){
{"eventType", "callout"},
{"statusInfo", new Dictionary<string, object>(){
{"sessionId", "1201_612_4294967295_20190124030424@callenabler245.huaweicaas.com"},
{"timestamp", "2019-01-24 03:04:24"},
{"caller", "+86138*******2"},
{"called", "+86138*******1"},
}
}
});
Console.WriteLine("jsonBody:" + jsonBody);
OnCallEvent(jsonBody); //呼叫事件处理
}
/// <summary>
/// 呼叫事件通知,详细内容以接口文档为准
/// </summary>
/// <param name="jsonBody"></param>
static void OnCallEvent(string jsonBody)
{
JObject jsonObj = (JObject)JsonConvert.DeserializeObject(jsonBody); //将通知消息解析为jsonObj
string eventType = jsonObj["eventType"].ToString(); //通知事件类型
if ("fee".Equals(eventType))
{
Console.WriteLine("EventType error:" + eventType);
return;
}
if (!jsonObj.ContainsKey("statusInfo"))
{
Console.WriteLine("param error: no statusInfo.");
return;
}
JObject statusInfo = (JObject)jsonObj["statusInfo"]; //呼叫状态事件信息
Console.WriteLine("eventType:" + eventType); //打印通知事件类型
//callout:呼出事件
if ("callout".Equals(eventType))
{
/**
* Example: 此处以解析sessionId为例,请按需解析所需参数并自行实现相关处理
*
* 'timestamp': 该呼叫事件发生时语音通话平台的UNIX时间戳
* 'userData': 用户附属信息
* 'sessionId': 通话链路的标识ID
* 'caller': 主叫号码
* 'called': 被叫号码
*/
if (statusInfo.ContainsKey("sessionId"))
{
Console.WriteLine("sessionId:" + statusInfo["sessionId"]);
}
return;
}
//alerting:振铃事件
if ("alerting".Equals(eventType))
{
/**
* Example: 此处以解析sessionId为例,请按需解析所需参数并自行实现相关处理
*
* 'timestamp': 该呼叫事件发生时语音通话平台的UNIX时间戳
* 'userData': 用户附属信息
* 'sessionId': 通话链路的标识ID
* 'caller': 主叫号码
* 'called': 被叫号码
*/
if (statusInfo.ContainsKey("sessionId"))
{
Console.WriteLine("sessionId:" + statusInfo["sessionId"]);
}
return;
}
//answer:应答事件
if ("answer".Equals(eventType))
{
/**
* Example: 此处以解析sessionId为例,请按需解析所需参数并自行实现相关处理
*
* 'timestamp': 该呼叫事件发生时语音通话平台的UNIX时间戳
* 'userData': 用户附属信息
* 'sessionId': 通话链路的标识ID
* 'caller': 主叫号码
* 'called': 被叫号码
*/
if (statusInfo.ContainsKey("sessionId"))
{
Console.WriteLine("sessionId:" + statusInfo["sessionId"]);
}
return;
}
//collectInfo:放音收号结果事件,仅应用于语音通知场景
if ("collectInfo".Equals(eventType))
{
/**
* Example: 此处以解析digitInfo为例,请按需解析所需参数并自行实现相关处理
*
* 'timestamp': 该呼叫事件发生时语音通话平台的UNIX时间戳
* 'sessionId': 通话链路的标识ID
* 'digitInfo': 放音收号场景中,语音通话平台对开发者进行放音收号操作的结果描述
*/
if (statusInfo.ContainsKey("digitInfo"))
{
Console.WriteLine("digitInfo:" + statusInfo["digitInfo"]);
}
return;
}
//disconnect:挂机事件
if ("disconnect".Equals(eventType))
{
/**
* Example: 此处以解析sessionId为例,请按需解析所需参数并自行实现相关处理
*
* 'timestamp': 该呼叫事件发生时语音通话平台的UNIX时间戳
* 'userData': 用户附属信息
* 'sessionId': 通话链路的标识ID
* 'caller': 主叫号码
* 'called': 被叫号码
* 'partyType': 挂机的用户类型,仅在语音回呼场景携带
* 'stateCode': 通话挂机的原因值
* 'stateDesc': 通话挂机的原因值的描述
*/
if (statusInfo.ContainsKey("sessionId"))
{
Console.WriteLine("sessionId:" + statusInfo["sessionId"]);
}
return;
}
}
}
}
“话单通知API”代码样例
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
namespace voicecall_csharp_demo_x_aksk_
{
class FeeImpl
{
static void Main(string[] args)
{
//话单通知样例
string jsonBody = JsonConvert.SerializeObject(new Dictionary<string, object>(){
{"eventType", "fee"},
{"feeLst", new object[] {
new Dictionary<string, object>(){
{"direction", 0}, //通话的呼叫方向,以语音通话平台为基准
{"spId", "CaaS_Test_01"}, //客户的云服务账号
{"appKey", "ka4k*****Em2"}, //应用的app_key,购买服务时下发,请替换为实际值
{"icid", "CAE-20190124110424-12019775"}, //呼叫记录的唯一标识
{"bindNum", "+8675512****78"}, //发起此次呼叫的CallEnabler业务号码,即绑定号码
{"sessionId", "1201_612_4294967295_20190124030424@callenabler245.huaweicaas.com"}, //通话链路的唯一标识
{"callerNum", "+86138****0022"}, //主叫号码
{"calleeNum", "+86138****0021"}, //被叫号码
{"fwdDisplayNum", "+86138****0022"}, //转接呼叫时的显示号码(仅语音回呼场景携带)
{"fwdDstNum", "+86138****7021"}, //转接呼叫时的转接号码(仅语音回呼场景携带)
{"fwdStartTime", "2019-01-24 03:04:31"}, //转接呼叫操作的开始时间(仅语音回呼场景携带)
{"fwdAlertingTime", "2019-01-24 03:04:36"}, //转接呼叫操作后的振铃时间(仅语音回呼场景携带)
{"fwdAnswerTime", "2019-01-24 03:04:38"}, //转接呼叫操作后的应答时间(仅语音回呼场景携带)
{"callEndTime", "2019-01-24 03:04:49"}, //呼叫结束时间
{"fwdUnaswRsn", 0}, //转接呼叫操作失败的Q850原因值
{"failTime", ""}, //呼入,呼出的失败时间
{"ulFailReason", 0}, //通话失败的拆线点
{"sipStatusCode", 0}, //呼入,呼出的失败SIP状态码
{"callOutStartTime", "2019-01-24 03:04:24"}, //Initcall的呼出开始时间
{"callOutAlertingTime", "2019-01-24 03:04:27"}, //Initcall的呼出振铃时间
{"callOutAnswerTime", "2019-01-24 03:04:31"}, //Initcall的呼出应答时间
{"callOutUnaswRsn", 0}, //Initcall的呼出失败的Q850原因值
{"dynIVRStartTime", ""}, //自定义动态IVR开始时间(仅语音通知场景携带)
{"dynIVRPath", ""}, //自定义动态IVR按键路径(仅语音通知场景携带)
{"recordFlag", 0}, //录音标识
{"recordStartTime", ""}, //录音开始时间(仅语音回呼场景携带)
{"recordObjectName", ""}, //录音文件名(仅语音回呼场景携带)
{"recordBucketName", ""}, //录音文件所在的目录名(仅语音回呼场景携带)
{"recordDomain", ""}, //存放录音文件的域名(仅语音回呼场景携带)
{"recordFileDownloadUrl", ""}, //录音文件下载地址(仅语音回呼场景携带)
{"ttsPlayTimes", 0}, //应用TTS功能时,使用TTS的总次数
{"ttsTransDuration", 0}, //应用TTS功能时,TTS Server进行TTS转换的总时长(单位为秒)
{"serviceType", "002"}, //携带呼叫的业务类型信息
{"hostName", "callenabler245.huaweicaas.com"}, //话单生成的服务器设备对应的主机名
{"userData", "customerId123"} //用户附属信息
}
}
}
});
Console.WriteLine(jsonBody);
OnFeeEvent(jsonBody); //话单处理
}
/// <summary>
/// 话单通知,详细内容以接口文档为准
/// </summary>
/// <param name="jsonBody"></param>
static void OnFeeEvent(string jsonBody)
{
JObject jsonObj = (JObject)JsonConvert.DeserializeObject(jsonBody); //将通知消息解析为jsonObj
string eventType = jsonObj["eventType"].ToString(); //通知事件类型
if (!"fee".Equals(eventType))
{
Console.WriteLine("EventType error:" + eventType);
return;
}
if (!jsonObj.ContainsKey("feeLst"))
{
Console.WriteLine("param error: no feeLst.");
return;
}
JObject[] feeLst = jsonObj["feeLst"].ToObject<JObject[]>(); //呼叫话单事件信息
//Example: 此处以解析sessionId为例,请按需解析所需参数并自行实现相关处理
//短时间内有多个通话结束时语音通话平台会将话单合并推送,每条消息最多携带50个话单
if (feeLst.Length > 1)
{
foreach (JObject loop in feeLst)
{
if (loop.ContainsKey("sessionId"))
{
Console.WriteLine("sessionId:" + loop["sessionId"]);
}
}
}
else if (feeLst.Length == 1)
{
if (feeLst[0].ContainsKey("sessionId"))
{
Console.WriteLine("sessionId:" + feeLst[0]["sessionId"]);
}
}
else
{
Console.WriteLine("feeLst error: no element.");
}
}
}
}
父主题: 语音通知代码样例