更新时间: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."); } } } }
父主题: 语音通知代码样例