专线电话接入示例

说明

说明 专线电话服务可提供基于运营商网络的回拨电话和多人电话会议功能,支持国内手机号码和固定电话。

专线电话接口为标准的HTTP接口,以下示例包含了常见语言如何发起HTTP请求,帮助开发者更高效的接入专线电话接口。

注:最重要的四个参数,务必参考计算示例服务器API,否则会出现{"desc":"bad http header","code":414}

参数 参数说明
AppKey 开发者平台分配的appkey
Nonce 随机数(最大长度128个字符)
CurTime 当前UTC时间戳,从1970年1月1日0点0 分0 秒开始到现在的秒数(String)
CheckSum SHA1(AppSecret + Nonce + CurTime),三个参数拼接的字符串,进行SHA1哈希计算,转化成16进制字符(String,小写)

Appkey,Appsecret获取步骤:

  1. 成为云信开发者
  2. 登录云信管理后台
  3. 创建应用
  4. 打开App Key管理

Java-发起单人专线电话

package com.netease.code;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import com.netease.checksum.CheckSumBuilder;
/**
 * 发起单人专线电话
 * @author liuxuanlin
 *
 */
public class StartCall {
    //发送单人专线电话的请求路径URL
    private static final String
            SERVER_URL="https://api.netease.im/call/ecp/startcall.action";
    //网易云信分配的账号,请替换你在管理后台应用下申请的Appkey
    private static final String
            APP_KEY="fd460d34e786e7754e505bc4fab0f027";
    //网易云信分配的密钥,请替换你在管理后台应用下申请的appSecret
    private static final String APP_SECRET="xxxxxxxx";
    //随机数
    private static final String NONCE="123456";

    //发起本次请求的用户的accid(需在网易云信注册过的accid,用于鉴权请求)
    private static final String CALLERACC="liuxuanlin"; 

    //主叫方电话号码(不带+86这类国家码,下同)
    private static final String CALLER="13888888888";

    //被叫方电话号码
    private static final String CALLEE="13777777777";

    //本通电话最大可持续时长,单位秒,超过该时长时通话会自动切断。
    private static final String MAXDUR="100";

    public static void main(String[] args) throws Exception {

        DefaultHttpClient httpClient = new DefaultHttpClient();
        HttpPost httpPost = new HttpPost(SERVER_URL);
        String curTime = String.valueOf((new Date()).getTime() / 1000L);
        /*
         * 参考计算CheckSum的java代码,在上述文档的参数列表中,有CheckSum的计算文档示例
         */
        String checkSum = CheckSumBuilder.getCheckSum(APP_SECRET, NONCE, curTime);

        // 设置请求的header
        httpPost.addHeader("AppKey", APP_KEY);
        httpPost.addHeader("Nonce", NONCE);
        httpPost.addHeader("CurTime", curTime);
        httpPost.addHeader("CheckSum", checkSum);
        httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");

        // 设置请求的的参数,requestBody参数
        List<NameValuePair> nvps = new ArrayList<NameValuePair>();
        /*
         * callerAcc参数必须要在云信注册下的accid
         */
        nvps.add(new BasicNameValuePair("callerAcc", CALLERACC));
        nvps.add(new BasicNameValuePair("caller", CALLER));
        nvps.add(new BasicNameValuePair("callee", CALLEE));
        nvps.add(new BasicNameValuePair("maxDur", MAXDUR));

        httpPost.setEntity(new UrlEncodedFormEntity(nvps, "utf-8"));

        // 执行请求
        HttpResponse response = httpClient.execute(httpPost);
        /*
         * 1.打印执行结果,打印结果一般会200、403、414、500
         * 2.具体的code有问题的可以参考官网的Code状态表
         */
        System.out.println(EntityUtils.toString(response.getEntity(), "utf-8"));

    }
}

Java-发起专线会议

package com.netease.code;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import com.netease.checksum.CheckSumBuilder;
/**
 * 发起专线会议
 * @author liuxuanlin
 *
 */
public class StartCall {
    //发送专线会议的请求路径URL
    private static final String
            SERVER_URL="https://api.netease.im/call/ecp/startconf.action";
    //网易云信分配的账号,请替换你在管理后台应用下申请的Appkey
    private static final String
            APP_KEY="fd460d34e786e7754e505bc4fab0f027";
    //网易云信分配的密钥,请替换你在管理后台应用下申请的appSecret
    private static final String APP_SECRET="xxxxxxxx";
    //随机数
    private static final String NONCE="123456";
    //发起本次请求的用户的accid(需在网易云信注册过的accid,用于鉴权请求)
    private static final String CALLERACC="liuxuanlin"; 

    //主叫方电话号码(不带+86这类国家码,下同)
    private static final String CALLER="13888888888";

    //所有被叫方电话号码,必须是json格式的字符串,限制接口者号码个数最多为8个
    private static final String CALLEE="['13777777777','13666666666']";

    //本通电话最大可持续时长,单位秒,超过该时长时通话会自动切断,会议时长计算规则是所有单路时长之和
    private static final String MAXDUR="100";

    public static void main(String[] args) throws Exception {

        DefaultHttpClient httpClient = new DefaultHttpClient();
        HttpPost httpPost = new HttpPost(SERVER_URL);
        String curTime = String.valueOf((new Date()).getTime() / 1000L);
        /*
         * 参考计算CheckSum的java代码,在上述文档的参数列表中,有CheckSum的计算文档示例
         */
        String checkSum = CheckSumBuilder.getCheckSum(APP_SECRET, NONCE, curTime);

        // 设置请求的header
        httpPost.addHeader("AppKey", APP_KEY);
        httpPost.addHeader("Nonce", NONCE);
        httpPost.addHeader("CurTime", curTime);
        httpPost.addHeader("CheckSum", checkSum);
        httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");

         // 设置请求的的参数,requestBody参数
        List<NameValuePair> nvps = new ArrayList<NameValuePair>();
        /*
         * callerAcc参数必须要在云信注册下的accid
         */
        nvps.add(new BasicNameValuePair("callerAcc", CALLERACC));
        nvps.add(new BasicNameValuePair("caller", CALLER));
        nvps.add(new BasicNameValuePair("callee", CALLEE));
        nvps.add(new BasicNameValuePair("maxDur", MAXDUR));

        httpPost.setEntity(new UrlEncodedFormEntity(nvps, "utf-8"));

        // 执行请求
        HttpResponse response = httpClient.execute(httpPost);
        /*
         * 1.打印执行结果,打印结果一般会200、403、414、500
         * 2.具体的code有问题的可以参考官网的Code状态表
         */
        System.out.println(EntityUtils.toString(response.getEntity(), "utf-8"));

    }
}

Jar包下载 httpcore-4.4.3.jar

httpclient-4.5.1.jar

PHP-单人专线及专线会议

<?php
/**
 * 发起单人专线电话
 * @author  chensheng
***/

//使用示例
require('./ServerAPI.php');
//网易云信分配的账号,请替换你在管理后台应用下申请的Appkey
$AppKey = 'fd460d34e786e7754e505bc4fab0f027';
//网易云信分配的账号,请替换你在管理后台应用下申请的appSecret
$AppSecret = 'xxxxxxxx';
$p = new ServerAPI($AppKey,$AppSecret,'fsockopen');     //fsockopen伪造请求


//发起单人专线电话
print_r( $p->startcall('liuxuanlin','13095088501','18085997799',100) );

//发起专线会议电话
print_r( $p->startconf('liuxuanlin','13777777777',array('13888888888','13666666666'),100) );

?>
<?php

/**
 * 网易云信server API 简单实例
 * Class ServerAPI
 * @author  chensheng dengyuan
 *
 *
 ***/

class ServerAPI
{
    public $AppKey;                //开发者平台分配的AppKey
    public $AppSecret;             //开发者平台分配的AppSecret,可刷新
    public $Nonce;                    //随机数(最大长度128个字符)
    public $CurTime;                 //当前UTC时间戳,从1970年1月1日0点0 分0 秒开始到现在的秒数(String)
    public $CheckSum;                //SHA1(AppSecret + Nonce + CurTime),三个参数拼接的字符串,进行SHA1哈希计算,转化成16进制字符(String,小写)
    const HEX_DIGITS = "0123456789abcdef";

    /**
     * 参数初始化
     * @param $AppKey
     * @param $AppSecret
     * @param $RequestType [选择php请求方式,fsockopen或curl,若为curl方式,请检查php配置是否开启]
     */
    public function __construct($AppKey, $AppSecret, $RequestType = 'curl')
    {
        $this->AppKey = $AppKey;
        $this->AppSecret = $AppSecret;
        $this->RequestType = $RequestType;
    }

    /**
     * API checksum校验生成
     * @param  void
     * @return $CheckSum(对象私有属性)
     */
    public function checkSumBuilder()
    {
        //此部分生成随机字符串
        $hex_digits = self::HEX_DIGITS;
        $this->Nonce;
        for ($i = 0; $i < 128; $i++) {            //随机字符串最大128个字符,也可以小于该数
            $this->Nonce .= $hex_digits[rand(0, 15)];
        }
        $this->CurTime = (string)(time());    //当前时间戳,以秒为单位

        $join_string = $this->AppSecret . $this->Nonce . $this->CurTime;
        $this->CheckSum = sha1($join_string);
        //print_r($this->CheckSum);
    }

    /**
     * 将json字符串转化成php数组
     * @param  $json_str
     * @return $json_arr
     */
    public function json_to_array($json_str)
    {

        if (is_array($json_str) || is_object($json_str)) {
            $json_str = $json_str;
        } else if (is_null(json_decode($json_str))) {
            $json_str = $json_str;
        } else {
            $json_str = strval($json_str);
            $json_str = json_decode($json_str, true);
        }
        $json_arr = array();
        foreach ($json_str as $k => $w) {
            if (is_object($w)) {
                $json_arr[$k] = $this->json_to_array($w); //判断类型是不是object
            } else if (is_array($w)) {
                $json_arr[$k] = $this->json_to_array($w);
            } else {
                $json_arr[$k] = $w;
            }
        }
        return $json_arr;
    }

    /**
     * 使用CURL方式发送post请求
     * @param  $url     [请求地址]
     * @param  $data    [array格式数据]
     * @return $请求返回结果(array)
     */
    public function postDataCurl($url, $data)
    {
        $this->checkSumBuilder();       //发送请求前需先生成checkSum

        $timeout = 5000;
        $http_header = array(
            'AppKey:' . $this->AppKey,
            'Nonce:' . $this->Nonce,
            'CurTime:' . $this->CurTime,
            'CheckSum:' . $this->CheckSum,
            'Content-Type:application/x-www-form-urlencoded;charset=utf-8'
        );
        //print_r($http_header);

        // $postdata = '';
        $postdataArray = array();
        foreach ($data as $key => $value) {
            array_push($postdataArray, $key . '=' . urlencode($value));
        }
        $postdata = join('&', $postdataArray);

        // var_dump($postdata);

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata);
        curl_setopt($ch, CURLOPT_HEADER, false);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $http_header);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); //处理http证书问题
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

        $result = curl_exec($ch);
        if (false === $result) {
            $result = curl_errno($ch);
        }
        curl_close($ch);
        return $this->json_to_array($result);
    }


    /**
     * 使用FSOCKOPEN方式发送post请求
     * @param  $url     [请求地址]
     * @param  $data    [array格式数据]
     * @return $请求返回结果(array)
     */
    public function postDataFsockopen($url, $data)
    {
        $this->checkSumBuilder();//发送请求前需先生成checkSum

        $postdata = '';
        foreach ($data as $key => $value) {
            $postdata .= ($key . '=' . urlencode($value) . '&');
        }
        // building POST-request:
        $URL_Info = parse_url($url);
        if (!isset($URL_Info["port"])) {
            $URL_Info["port"] = 80;
        }
        $request = '';
        $request .= "POST " . $URL_Info["path"] . " HTTP/1.1\r\n";
        $request .= "Host:" . $URL_Info["host"] . "\r\n";
        $request .= "Content-type: application/x-www-form-urlencoded;charset=utf-8\r\n";
        $request .= "Content-length: " . strlen($postdata) . "\r\n";
        $request .= "Connection: close\r\n";
        $request .= "AppKey: " . $this->AppKey . "\r\n";
        $request .= "Nonce: " . $this->Nonce . "\r\n";
        $request .= "CurTime: " . $this->CurTime . "\r\n";
        $request .= "CheckSum: " . $this->CheckSum . "\r\n";
        $request .= "\r\n";
        $request .= $postdata . "\r\n";

        print_r($request);
        $fp = fsockopen($URL_Info["host"], $URL_Info["port"]);
        fputs($fp, $request);
        $result = '';
        while (!feof($fp)) {
            $result .= fgets($fp, 128);
        }
        fclose($fp);

        $str_s = strpos($result, '{');
        $str_e = strrpos($result, '}');
        $str = substr($result, $str_s, $str_e - $str_s + 1);
        print_r($result);
        return $this->json_to_array($str);
    }

    /**
     * 发起单人专线电话
     * @param  $callerAcc       [发起本次请求的用户的accid]
     * @param  $caller          [主叫方电话号码(不带+86这类国家码,下同)]
     * @param  $callee          [被叫方电话号码]
     * @param  $maxDur          [本通电话最大可持续时长,单位秒,超过该时长时通话会自动切断]
     * @return $result          [返回array数组对象]
     */
    public function startcall($callerAcc,$caller,$callee,$maxDur){
        $url = 'https://api.netease.im/call/ecp/startcall.action';
        $data= array(
            'callerAcc' => $callerAcc,
            'caller' => $caller,
            'callee' => $callee,
            'maxDur' => $maxDur
        );
        if($this->RequestType=='curl'){
            $result = $this->postDataCurl($url,$data);
        }else{
            $result = $this->postDataFsockopen($url,$data);
        }
        return $result;
    }

    /**
     * 发起专线会议电话
     * @param  $callerAcc       [发起本次请求的用户的accid]
     * @param  $caller          [主叫方电话号码(不带+86这类国家码,下同)]
     * @param  $callee          [所有被叫方电话号码,必须是json格式的字符串,如["13588888888","13699999999"]]
     * @param  $maxDur          [本通电话最大可持续时长,单位秒,超过该时长时通话会自动切断]
     * @return $result          [返回array数组对象]
     */
    public function startconf($callerAcc,$caller,$callee,$maxDur){
        $url = 'https://api.netease.im/call/ecp/startconf.action';
        $data= array(
            'callerAcc' => $callerAcc,
            'caller' => $caller,
            'callee' => json_encode($callee),
            'maxDur' => $maxDur
        );
        if($this->RequestType=='curl'){
            $result = $this->postDataCurl($url,$data);
        }else{
            $result = $this->postDataFsockopen($url,$data);
        }
        return $result;
    }


}

?>

C#-单人专线电话

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.Net;
using System.IO;

namespace server_http_api
{
    class CheckSumBuilder
    {
        // 计算并获取CheckSum
        public static String getCheckSum(String appSecret, String nonce, String curTime)
        {
            byte[] data = Encoding.Default.GetBytes(appSecret + nonce + curTime);
            byte[] result;

            SHA1 sha = new SHA1CryptoServiceProvider();
            // This is one implementation of the abstract class SHA1.
            result = sha.ComputeHash(data);

            return getFormattedText(result);
        }

        // 计算并获取md5值
        public static String getMD5(String requestBody)
        {
            if (requestBody == null)
                return null;

            // Create a new instance of the MD5CryptoServiceProvider object.
            MD5 md5Hasher = MD5.Create();

            // Convert the input string to a byte array and compute the hash.
            byte[] data = md5Hasher.ComputeHash(Encoding.Default.GetBytes(requestBody));

            // Create a new Stringbuilder to collect the bytes
            // and create a string.
            StringBuilder sBuilder = new StringBuilder();

            // Loop through each byte of the hashed data
            // and format each one as a hexadecimal string.
            for (int i = 0; i < data.Length; i++)
            {
                sBuilder.Append(data[i].ToString("x2"));
            }

            // Return the hexadecimal string.
            return getFormattedText(Encoding.Default.GetBytes(sBuilder.ToString()));
        }

        private static String getFormattedText(byte[] bytes)
        {
            char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5',
            '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
            int len = bytes.Length;
            StringBuilder buf = new StringBuilder(len * 2);
            for (int j = 0; j < len; j++) {
                buf.Append(HEX_DIGITS[(bytes[j] >> 4) & 0x0f]);
                buf.Append(HEX_DIGITS[bytes[j] & 0x0f]);
            }
            return buf.ToString();
        }
    }

    class HttpClient
    {
        //发起Http请求
        public static void HttpPost(string url, Stream data, IDictionary<object, string> headers = null)
        {
            System.Net.WebRequest request = HttpWebRequest.Create(url);
            request.Method = "POST";
            if (data != null)
            request.ContentLength = data.Length;
            //request.ContentType = "application/x-www-form-urlencoded;charset=utf-8";

            if (headers != null)
            {
                foreach (var v in headers)
                {
                    if (v.Key is HttpRequestHeader)
                        request.Headers[(HttpRequestHeader)v.Key] = v.Value;
                    else
                        request.Headers[v.Key.ToString()] = v.Value;
                }
            }
            HttpWebResponse response = null;
            try
            {
                // Get the response.
                response = (HttpWebResponse)request.GetResponse();
                // Display the status.
                Console.WriteLine(response.StatusDescription);
                // Get the stream containing content returned by the server.
                Stream dataStream = response.GetResponseStream();
                // Open the stream using a StreamReader for easy access.
                StreamReader reader = new StreamReader(dataStream);
                // Read the content.
                string responseFromServer = reader.ReadToEnd();
                // Display the content.
                Console.WriteLine(responseFromServer);
                // Cleanup the streams and the response.
                reader.Close();
                dataStream.Close();
                response.Close();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                Console.WriteLine(response.StatusDescription);
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            String url = "https://api.netease.im/call/ecp/startcall.action";
            url += "?callerAcc=liuxuanlin&caller=13888888888&callee=13666666666&maxDur=100";//请输入正确的手机号

            //网易云信分配的账号,请替换你在管理后台应用下申请的Appkey
            String appKey = "fd460d34e786e7754e505bc4fab0f027";
            //网易云信分配的密钥,请替换你在管理后台应用下申请的appSecret
            String appSecret = "xxxxxxxx";
            //随机数(最大长度128个字符)
            String nonce = "12345";

            TimeSpan ts = DateTime.Now.ToUniversalTime() - new DateTime(1970, 1, 1);
            Int32 ticks = System.Convert.ToInt32(ts.TotalSeconds);
            //当前UTC时间戳,从1970年1月1日0点0 分0 秒开始到现在的秒数(String)
            String curTime = ticks.ToString();
            //SHA1(AppSecret + Nonce + CurTime),三个参数拼接的字符串,进行SHA1哈希计算,转化成16进制字符(String,小写)
            String checkSum = CheckSumBuilder.getCheckSum(appSecret, nonce, curTime);

            IDictionary<object, String> headers = new Dictionary<object, String>();
            headers["AppKey"] = appKey;
            headers["Nonce"] = nonce;
            headers["CurTime"] = curTime;
            headers["CheckSum"] = checkSum;
            headers["ContentType"] = "application/x-www-form-urlencoded;charset=utf-8";
            //执行Http请求
            HttpClient.HttpPost(url, null, headers);
        }
    }
}

C#-发起专线会议

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.Net;
using System.IO;

namespace server_http_api
{
    class CheckSumBuilder
    {
        // 计算并获取CheckSum
        public static String getCheckSum(String appSecret, String nonce, String curTime)
        {
            byte[] data = Encoding.Default.GetBytes(appSecret + nonce + curTime);
            byte[] result;

            SHA1 sha = new SHA1CryptoServiceProvider();
            // This is one implementation of the abstract class SHA1.
            result = sha.ComputeHash(data);

            return getFormattedText(result);
        }

        // 计算并获取md5值
        public static String getMD5(String requestBody)
        {
            if (requestBody == null)
                return null;

            // Create a new instance of the MD5CryptoServiceProvider object.
            MD5 md5Hasher = MD5.Create();

            // Convert the input string to a byte array and compute the hash.
            byte[] data = md5Hasher.ComputeHash(Encoding.Default.GetBytes(requestBody));

            // Create a new Stringbuilder to collect the bytes
            // and create a string.
            StringBuilder sBuilder = new StringBuilder();

            // Loop through each byte of the hashed data
            // and format each one as a hexadecimal string.
            for (int i = 0; i < data.Length; i++)
            {
                sBuilder.Append(data[i].ToString("x2"));
            }

            // Return the hexadecimal string.
            return getFormattedText(Encoding.Default.GetBytes(sBuilder.ToString()));
        }

        private static String getFormattedText(byte[] bytes)
        {
            char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5',
            '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
            int len = bytes.Length;
            StringBuilder buf = new StringBuilder(len * 2);
            for (int j = 0; j < len; j++) {
                buf.Append(HEX_DIGITS[(bytes[j] >> 4) & 0x0f]);
                buf.Append(HEX_DIGITS[bytes[j] & 0x0f]);
            }
            return buf.ToString();
        }
    }

    class HttpClient
    {
        //发起Http请求
        public static void HttpPost(string url, Stream data, IDictionary<object, string> headers = null)
        {
            System.Net.WebRequest request = HttpWebRequest.Create(url);
            request.Method = "POST";
            if (data != null)
            request.ContentLength = data.Length;
            //request.ContentType = "application/x-www-form-urlencoded;charset=utf-8";

            if (headers != null)
            {
                foreach (var v in headers)
                {
                    if (v.Key is HttpRequestHeader)
                        request.Headers[(HttpRequestHeader)v.Key] = v.Value;
                    else
                        request.Headers[v.Key.ToString()] = v.Value;
                }
            }
            HttpWebResponse response = null;
            try
            {
                // Get the response.
                response = (HttpWebResponse)request.GetResponse();
                // Display the status.
                Console.WriteLine(response.StatusDescription);
                // Get the stream containing content returned by the server.
                Stream dataStream = response.GetResponseStream();
                // Open the stream using a StreamReader for easy access.
                StreamReader reader = new StreamReader(dataStream);
                // Read the content.
                string responseFromServer = reader.ReadToEnd();
                // Display the content.
                Console.WriteLine(responseFromServer);
                // Cleanup the streams and the response.
                reader.Close();
                dataStream.Close();
                response.Close();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                Console.WriteLine(response.StatusDescription);
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            String url = "https://api.netease.im/call/ecp/startconf.action";
            url += "?callerAcc=liuxuanlin&caller=13777777777&callee=['13888888888','13666666666']&maxDur=100";//请输入正确的手机号

            //网易云信分配的账号,请替换你在管理后台应用下申请的Appkey
            String appKey = "fd460d34e786e7754e505bc4fab0f027";
            //网易云信分配的密钥,请替换你在管理后台应用下申请的appSecret
            String appSecret = "xxxxxxxx";
            //随机数(最大长度128个字符)
            String nonce = "12345";

            TimeSpan ts = DateTime.Now.ToUniversalTime() - new DateTime(1970, 1, 1);
            Int32 ticks = System.Convert.ToInt32(ts.TotalSeconds);
            //当前UTC时间戳,从1970年1月1日0点0 分0 秒开始到现在的秒数(String)
            String curTime = ticks.ToString();
            //SHA1(AppSecret + Nonce + CurTime),三个参数拼接的字符串,进行SHA1哈希计算,转化成16进制字符(String,小写)
            String checkSum = CheckSumBuilder.getCheckSum(appSecret, nonce, curTime);

            IDictionary<object, String> headers = new Dictionary<object, String>();
            headers["AppKey"] = appKey;
            headers["Nonce"] = nonce;
            headers["CurTime"] = curTime;
            headers["CheckSum"] = checkSum;
            headers["ContentType"] = "application/x-www-form-urlencoded;charset=utf-8";
            //执行Http请求
            HttpClient.HttpPost(url, null, headers);
        }
    }
}

常见错误码

所有的专线电话HTTP请求均有response,response有两部分组成,

  1. 第一部分是code,代表code具体的内容,成功还是失败
  2. 第二部分是desc或者msg,代表错误原因描述(非code=200的情况,才会有desc)

414参数错误

1. checksum

{"desc":"checksum","code":414}

典型的checksum计算错误,需要自行核对计算checksum的参数算法,前提是保证这个appSecret是属于您在管理后台的应用下的。

2. bad http header

{"desc":"bad http header","code":414}

典型的请求http header计算错误,需要自行核对请求header中的4个参数,分别为Appkey,Nonce,Curtime,CheckSum。(上述文档可以查询这4个参数)

3. bad param 'callerAcc'

{"msg":"bad param 'callerAcc'","code":414}

callerAcc参数是发起本次请求的用户accid,该accid是网易云信用于专线电话的鉴权,accid的获取方式如下: 测试应用:登录云信管理后台 -> 打开左边栏应用 -> 当前开通专线电话功能的应用 -> 账号管理 -> 新建账号 正式应用:通过服务器API创建云信id

4. bad param 'callee'

{"code":414,"msg":"bad param 'callee'"}

在发起专线会议时,callee参数是jsonArray的格式,需要提供正确的参数格式,云信才会通过校验,正确callee的格式可在上述代码示例中进行参考

403没有权限

1. no authorization

{"code":403,"msg":"no authorization"}

403就是由于相应专线电话的权限没有开通,需联系相应商务开通,或咨询官网电话:4009-000-123

400 HTTP错误

1. HTTP Status 400 这个错误是HTTP常见错误, 400 请求出错 由于语法格式有误,服务器无法理解此请求,一般出现的情况,都是短信请求的参数body与短信请求的URL不匹配导致的,只要参考检查上述文档中的URL,以及文档中的body参数即可。

专线电话结束回调抄送

专线电话通话结束回调是指在双人通话或会议通话最后一个人退出通话过程之后,由网易云通信服务端主动向应用提供的接口中POST该通会话的详情,抄送回调地址需要联系相应的商务配置,或拨打官网电话:4009-000-123 通话结束回调参数格式,可参考通话结束回调参数 对应回调抄送详情示例,可参考专线电话通话结束回调抄送