点击回拨电话呼叫项目案例研发指南

1、为什么使用点击拨号电话,在哪些场景使用?

  • 很久以前由于互联网监控还没完善,有歪念的不法分子为了掩盖自己的身份(电话号码),从而在某些运营商或者其他渠道进行合作,然后通过这种渠道虚拟电话号码拨打或者发短信进行欺骗些没有意识的良民的老百姓财产

  • 网络监控工作逐步完善之后,国家为了保护老百姓的人身财产权益,然后慢慢会改善了,然而会慢慢减少短信的欺骗,只要是经过范围内控制,天涯海角都能通过大数据进行 分析找到痕迹

  • 经过以上两点进行阐述,大概有点明白了吧?回归正传, 点击点击电话回拨场景一般用在是软件开发里面呢?俺就讲述一个亲身经历参与的开发项目案例上面吧。曾经参与一个关于律师的互联网的产品研发,然后这个产品最终的宗旨为人民解忧,通过线上律师进行来,解答,咨询,律师函定制,合同服务等(记住律师回答您的问题不是免费,老铁们要收费的呢,人家的知识点可贵了?而且别人说不定接一单可以三年不干活的呢)制定来为线上用户在生活中有法律纠纷的疑难疑点,比如:房产纠纷,财产纠纷,离婚纠纷,个人利益,劳动合同纠纷等操作问题,然而项目分用户端律师端,还有一个后台管理后台(管理用户或律师)端的发布信息进行开发。

  • 刚刚提到律师不会很清闲帮你解答的呢?一个为解决线上用户有法律法规纠纷,二来为了吸引律师来注册到平台里面处理问题,故我们就想办法帮律师创收这方面进行考虑,然后开发了一个呼叫电话功能模块.这里就涉及律师的隐私问题(手机号码或者微信),故就用上了点击拨号电话呼叫API,从而在律师身上抽点水。

2、点击回拨有哪些提供商选择呢?

  • 虽然很多国内或国外很企业做这样的中间商,个人建议推荐华为和阿里云毕竟大公司靠谱,选择国外的不好监控,而且API国外点也调用也慢
    而且华为在通信知名度就不多说了,阿里没用过故不做过多的阐述,相信也做得杠杠的。

华为点击回拨API
阿里云点击回拨API

  • 文章这里以华为为例进行展开,详解API请看在线文档

https://support.huaweicloud.com/api-VoiceCall/rtc_05_0002.html

3 准备工作

  • 公司要运营商(华为或阿里)公司进行签到合约,找到他们平台负责人进行获取
  • 注意: 老证书AK,录音的时候会用到,在双方签合同的时候必须强调进行签约,否则不签约第二次审批走流程就时间长了

1.所有使用的号码均需要使用+86开头
2.ContentType均为application/json;charset=UTF-8
3.使用https请求
4.正常分配的平台号码均为028的四川地区固话,如需显示特殊号码,请联系移动申请
5.语音通知业务因管控要求,只能使用固定语音文件+TTS形式或纯固定语音文件方式,如有疑问请向合作经理咨询
6.测试账号只分配2个端口,即支持一路通话并发,如需更多端口用于调测,请向移动申请
7.使用的固定放音文件为.wav,CCITT A-Law 8.00 kHz,8位单声道
8.1010001(检查参数是否没使用双引号包裹,检查参数类型是否设置错误Integer直接填数字,不需要引号包裹)
9.1010002(检查参数是否缺失,检查号码是否都使用+86开头)

参数 参数说明
主机Ip 华为分配的Ip
APP_KEY 申请应用标识,在应用创建时由能力开放管理平台分配
APP_SECRET 应用密钥,创建应用时CaaS平台分配给APP_KEY的密钥
USER_NAME 用户名称
PASS_WORD 明文密码, SP在CaaS平台上注册时设置的密码或会议业务码/个人号码的密码
PLATFORM_NUMBER 平台号码
TYPE 账号类型: 1-用户号码 2-SP账号
REFRESH_TOKEN 授权类型
AK 老证书AK,录音的时候会用到,在双方签合同的时候必须强调进行签约,否则不签约第二次审批走流程就时间长了

4、大客户SP简单认证API

  • 大客户SP简单认证API是提供给合作伙伴的一种简单的认证接口,仅允许批发模式的应用调用。


    大客户SP简单认证API

大客户SP简单认证流程说明:
1、第三方应用接收到用户的登录请求,首先检测平台是否具有合法的用户授权,如果没有得到用户的授权,则要求用户进行认证;
2、第三方应用要求用户输入账号、口令;
3、用户输入认证信息,并且提交;
4、第三方应用携带用户的账号、口令向CaaS平台发起授权请求(授权接口采用HTTPS
通讯,保证帐号口令的安全传输);
5、CaaS平台生成访问Token并返回给第三方应用,第三方应用使用该Token向CaaS平台
发送业务请求。

  • 代码实现 ,HttpClient通信工具
  • 请参考我之前写的kotlin与java的HttpClient封装http通信工具类文章
/**
     * @Description 大客户 SP 简单认证 API,详细请参考华为提供的【点击呼叫API接口文档.pdf】文档指引
     * @Author      liangjilong  
     * @Date        2017年6月6日 下午1:42:41  
     * @return 参数  
     * @return SimpleVerifyVo 返回类型   
     * @throws
     */
    public static SimpleVerifyVo verifyFastLogin(){
        try {
            String reqUrl = ClickCallConfigUtil.HOST_URL+"rest/fastlogin/v1.0";
            //======请求参数================
            Map reqMap = new HashMap();
            reqMap.put("app_key", ClickCallConfigUtil.APPKEY);
            reqMap.put("username", ClickCallConfigUtil.USERNAME);
            reqMap.put("type", ClickCallConfigUtil.TYPE);
            String reqParams = HttpClientUtil.getConcatParams(reqMap);
            
            String newReqUrl= reqUrl+"?"+reqParams;//请求链接
            
            Map headerMap  = new HashMap();
            headerMap.put("Authorization", ClickCallConfigUtil.PASSWORD);//设置密码授权头header属性文件
            headerMap.put("Content-Type", GlobalConstants.CONTENT_TYPE);//设置密码授权头header属性文件
            //方式请求方法一:
            //String retMsg = HttpClientUtil.createHttps(newReqUrl,"POST",headerMap,true,GlobalConstants.SSL_VERSION,null);
            //方式请求方法二:
            String retMsg = HttpClientUtil.createHttpsPost(newReqUrl, null, GlobalConstants.CONTENT_TYPE, GlobalConstants.UTF8, headerMap);
            if(ObjectUtil.isNotEmpty(retMsg) && !"FAIL".equals(retMsg)){
                JSONObject jsonObject = JSONObject.fromObject(retMsg);
                if(!ObjectUtil.isEmpty(jsonObject)){
                    return (SimpleVerifyVo)JSONObject.toBean(jsonObject, SimpleVerifyVo.class);
                }else{
                    return null;
                }
            }else{
                return null;
            }
        } catch (UnsupportedEncodingException e) {
            logger.error("@see "+getCurrentClassName()+"#verifyFastLogin,出现异常,异常信息为:"+e.getMessage());
            e.printStackTrace();
        }
        return null;
    }

5、 刷新授权API

  • Access token的有效期不是无限的。当用户授权给第三方应用使用的Access token超过了其生命周期时,可以通过刷新机制来获取新的Access Token。刷新授权API用于根据授权时返回的refresh_token参数获取新的Access Token。

  • 代码实现

/**
     * @Description 刷新授权API  
     * @Author      liangjilong  
     * @Date        2017年6月6日 下午1:46:42   参数  
     * @return void 返回类型   
     * @throws
     */
    public static SimpleVerifyVo refreshOAuth(){
        try {
            SimpleVerifyVo simpleVerifyVo = verifyFastLogin();
            String reqUrl = ClickCallConfigUtil.HOST_URL+"omp/oauth/refresh";
            Map reqMap = new HashMap();
            reqMap.put("app_key", ClickCallConfigUtil.APPKEY);
            reqMap.put("grant_type", ClickCallConfigUtil.REFRESH_TOKEN);
            reqMap.put("app_secret", ClickCallConfigUtil.APP_SECRET);
            if(simpleVerifyVo!=null){
                //刷新令牌。授权时CaaS平台返回的refresh_token字段的值
                String refresh_token = simpleVerifyVo.getRefresh_token();
                reqMap.put("refresh_token", refresh_token);
            }
            String reqParams = HttpClientUtil.getConcatParams(reqMap);
            
            Map headerMap  = new HashMap();
            headerMap.put("Content-Type", GlobalConstants.CONTENT_TYPE);//设置密码授权头header属性文件
            
            String newReqUrl= reqUrl+"?"+reqParams;//请求链接
            String retMsg = HttpClientUtil.createHttps(newReqUrl,"POST",headerMap,true,GlobalConstants.SSL_VERSION,null);
            if(ObjectUtil.isNotEmpty(retMsg) && !"FAIL".equals(retMsg)){
                JSONObject jsonObject = JSONObject.fromObject(retMsg);
                if(!ObjectUtil.isEmpty(jsonObject)){
                    return (SimpleVerifyVo)JSONObject.toBean(jsonObject, SimpleVerifyVo.class);
                }
                return null;
            }else{
                return null;
            }
            
        } catch (UnsupportedEncodingException e) {
            logger.error("@see "+getCurrentClassName()+"#refreshOAuth,出现异常,异常信息为:"+e.getMessage());
            e.printStackTrace();
        }
        return null;
    }

6、取消授权 API

  • 开发者调用取消授权API,CaaS平台将回收应用使用者对应用的授权。取消授权后如需再次访问API资源,第三方APP需要重新获得应用使用者的授权。
  • 代码实现
/**
     * @Description 取消授权 API,返回true表示取消成功,true表示取消失败
     * 
     * @Author      liangjilong  
     * @Date        2017年6月6日 下午1:46:42   参数  
     * @return void 返回类型   
     * @throws
     */
    public static boolean cancelOAuth(){
        try {
            SimpleVerifyVo simpleVerifyVo = verifyFastLogin();
            String reqUrl = ClickCallConfigUtil.HOST_URL+"rest/logout/v1.0";
            Map reqMap = new HashMap();
            reqMap.put("app_key", ClickCallConfigUtil.APPKEY);
            if(simpleVerifyVo!=null){
                //刷新令牌。授权时CaaS平台返回的access_token字段的值
                String access_token = simpleVerifyVo.getAccess_token();
                reqMap.put("access_token", access_token);
            }
            String reqParams = HttpClientUtil.getConcatParams(reqMap);
             
            Map headerMap  = new HashMap();
            headerMap.put("Content-Type", GlobalConstants.CONTENT_TYPE);//设置密码授权头header属性文件
            String newReqUrl= reqUrl+"?"+reqParams;//请求链接
            String retMsg = HttpClientUtil.createHttps(newReqUrl,"POST",headerMap,true,GlobalConstants.SSL_VERSION,null);
            
            if(ObjectUtil.isNotEmpty(retMsg) && !"FAIL".equals(retMsg)){
                JSONObject jsonObject = JSONObject.fromObject(retMsg);
                
                if(jsonObject!=null){
                    boolean hasResultcode = jsonObject.has("resultcode");
                    if(hasResultcode){
                        String resultcode = jsonObject.getString("resultcode");
                        if(ObjectUtil.isNotEmpty(resultcode) && "0".equals(resultcode)){
                            return true; //取消成功
                        }
                    }else{
                        return false;//取消失败
                    }
                }
            }else{
                return false; //这里表示不成功,因为华为那边只能一分钟请求一次获取授权登录
            }
        } catch (UnsupportedEncodingException e) {
            logger.error("@see "+getCurrentClassName()+"#cancelOAuth,出现异常,异常信息为:"+e.getMessage());
            e.printStackTrace();
        }
        return false;
    }

7、刷新访问 OceanStor

  • 本API用于SP向系统请求重新生成录音文件的下载证书。
    刷新后,旧证书3天(OMU上配置)后失效。旧证书没有失效,再次刷新,返回刷新频繁错误码。
  • 代码实现
/**   
     * @Description  刷新访问 OceanStor 的证书  ,此接口语音会用到的Key
     * @Author      liangjilong  
     * @Date        2017年6月6日 下午1:46:42   参数  
     * @return void 返回类型   
     * @throws
     */
    public static void refreshKey(String access_token){

        try {
            
            String reqUrl = ClickCallConfigUtil.HOST_URL+"rest/refreshkey/v2.0";
            Map reqMap = new HashMap();
            reqMap.put("app_key", ClickCallConfigUtil.APPKEY);
            if(access_token!=null){
                //刷新令牌。授权时CaaS平台返回的access_token字段的值
                reqMap.put("access_token", access_token);
            }else{
                SimpleVerifyVo simpleVerifyVo = verifyFastLogin();
                if(ObjectUtil.isNotEmpty(simpleVerifyVo)){
                    access_token = simpleVerifyVo.getAccess_token();
                    reqMap.put("access_token", access_token);
                }
            }
            
            reqMap.put("AK", ClickCallConfigUtil.AK);
            
            String reqParams = HttpClientUtil.getConcatParams(reqMap);
             
            Map headerMap  = new HashMap();
            headerMap.put("Content-Type", GlobalConstants.CONTENT_TYPE);//设置密码授权头header属性文件
            String newReqUrl= reqUrl+"?"+reqParams;//请求链接
            String retMsg = HttpClientUtil.createHttps(newReqUrl,"POST",headerMap,true,GlobalConstants.SSL_VERSION,null);
            
            if(ObjectUtil.isNotEmpty(retMsg) && !"FAIL".equals(retMsg)){
                
            }else{
            }
        } catch (UnsupportedEncodingException e) {
            logger.error("@see "+getCurrentClassName()+"#refreshKey,出现异常,异常信息为:"+e.getMessage());
            e.printStackTrace();
        }

    }

8、点击呼叫场景 API

  • 点击呼叫是同时将主叫号码和被叫号码通过IP网络发送给服务器,由服务器呼叫主叫和被叫,使主叫和被叫能够互相通话。


    点击呼叫场景 API
  • 点击呼叫业务体验描述:
    用户A想要让用户B和用户C通话。一般情况下,用户A会是用户B和用户C的某一个人。
  1. 用户A向CaaS平台发送点击拨号业务请求。
  2. CaaS平台呼叫用户B的号码。
  3. 用户B接听,并听到提示音。
  4. CaaS平台呼叫用户C的号码。
  5. 用户C接听。
  6. 用户B和用户C通话。
  • 应用场景,电话咨询

某用户在浏览某培训机构的网页或APP,对培训内容很感兴趣。此用户则在此网页或APP输入自己的电话号码,点联系客服。培训机构的系统就会调用CaaS平台的点击拨号接口,CaaS平台先呼叫某客服,接通后再呼叫此用户,就此用户和客服建立了通话。
场景价值
1、双方均作为被叫,可为其省去电话费用,费用由企业支付。
2、可使用企业号码作为主显号码,屏蔽双方个人的真实号码,保护个人号码不泄露。
3、企业认为重要的电话,可在接口中指示对通话进行录音,作为业务存档资料

  • 代码实现
/**
     * @Description 点击呼叫场景API    
     * @Author      liangjilong  
     * @Date        2017年6月7日 上午10:16:52  
     * @param reqBodyMap 请求body参数
     * @return 参数  
     * @return ClickCall 返回类型   
     * @throws
     */
    public synchronized static ClickCallVo clickCall(Map reqBodyMap,String access_token){

        try {
            //商用环境
            String reqUrl = ClickCallConfigUtil.HOST_URL+"rest/httpsessions/click2Call/v2.0";
            //测试环境
            //String reqUrl = ClickCallConfigUtil.HOST_URL+"sandbox/rest/httpsessions/click2Call/v2.0";
            
            Map reqMap = new HashMap();
            reqMap.put("app_key", ClickCallConfigUtil.APPKEY);
            reqMap.put("access_token", access_token);
            
            String reqParams = HttpClientUtil.getConcatParams(reqMap);
            
            Map headerMap = setJsonContentType();
            
            String bodyParam = JSONUtil.mapToJson(reqBodyMap);//请求body参数
            
            String newReqUrl= java.net.URLDecoder.decode(reqUrl+"?"+reqParams,"utf-8");  ;//请求链接
            
            String retMsg = HttpClientUtil.createHttps(newReqUrl,"POST",headerMap,true,GlobalConstants.SSL_VERSION,bodyParam);
            
            if(ObjectUtil.isNotEmpty(retMsg) && !"FAIL".equals(retMsg)){ 
                JSONObject jsonObject = JSONObject.fromObject(retMsg);
                ClickCallVo clickCall  = null ;
                if(!ObjectUtil.isEmpty(jsonObject)){
                     clickCall = (ClickCallVo)JSONObject.toBean(jsonObject, ClickCallVo.class);
                }
                return clickCall;
            }else{
                 return null;
            }
        } catch (Exception e) {
            logger.error("@see "+getCurrentClassName()+"#clickCall,出现异常,异常信息为:"+e.getMessage());
            e.printStackTrace();
        }
        return null;
    }

9、 呼叫终止场景 API

  • 呼叫终止API就是在点击类业务执行的过程中终止业务。比如终止正在进行的点击拨号。如果业务已经执行完毕,呼叫终止API会返回失败。
呼叫终止场景 API
  • 呼叫终止体验描述:
    用户A想要终止正在进行的点击拨号业务。
    1、用户A向Caas平台发送终止呼叫请求;
    2、Caas平台会分别将B、C用户都挂机。
    应用场景
    终止整个会话呼叫,可以和点击呼叫和语音验证码联合使用
  • 代码实现
/**
     * @Description 呼叫终止场景API,此接口必须是要已经在线才可以停止
     * @Author      liangjilong  
     * @Date        2017年6月7日 上午10:21:10  
     * @param reqBodyMap 请求body参数  
     * @return void 返回类型   
     * @throws
     */
    public static boolean callStop(String sessionId,String access_token){
        try {
            String reqUrl = ClickCallConfigUtil.HOST_URL+"rest/httpsessions/callStop/v2.0";//商用环境
            Map reqMap = new HashMap();
            reqMap.put("app_key", ClickCallConfigUtil.APPKEY);
            reqMap.put("access_token", access_token);
            Map callStopReqBodyMap = new HashMap();
            callStopReqBodyMap.put("sessionid", sessionId);//使用点击呼叫场景API或语音验 证码场景API时返回的sessionid值。
            callStopReqBodyMap.put("signal", "call_stop");//signal的值固定为"call_stop", 表示主被叫都拆线
            
            Map headerMap = setJsonContentType();
            String reqParams = HttpClientUtil.getConcatParams(reqMap);

            String newReqUrl= java.net.URLDecoder.decode(reqUrl+"?"+reqParams,"utf-8");  ;//请求链接
            
            //请求body参数
            String bodyParam = JSONUtil.mapToJson(callStopReqBodyMap);
            
            String retMsg = HttpClientUtil.createHttps(newReqUrl,"POST",headerMap,true,GlobalConstants.SSL_VERSION,bodyParam);
            if(ObjectUtil.isNotEmpty(retMsg) && !"FAIL".equals(retMsg)){ 
                JSONObject jsonObject =JSONObject.fromObject(retMsg);
                if(jsonObject!=null){
                    boolean hasReturnCode = jsonObject.has("returnCode");
                    if(hasReturnCode){
                        String returnCode = jsonObject.getString("returnCode");
                        if(ObjectUtil.isNotEmpty(returnCode) && "0".equals(returnCode)){
                            return true;
                        }
                    }
                }else{
                    return false;
                }
            }else{
                return false;
            }
        } catch (UnsupportedEncodingException e) {
            logger.error("@see "+getCurrentClassName()+"#callStop,出现异常,异常信息为:"+e.getMessage());
            e.printStackTrace();
        }
        return false;
        
    }

10、查询呼叫端口使用情况

  • 用于查询APPKEY对应的呼叫最大端口数和空闲端口数
  • 代码实现
/**
     * @TODO 华为接口返回 Inner error
     * @Description 查询呼叫端口使用情况  
     * @Author      liangjilong  
     * @Date        2017年6月6日 下午1:55:39   参数  
     * @return void 返回类型   
     * @throws
     */
    public static void queryCallUseVoicePort(String access_token){
        try {
            String reqUrl = ClickCallConfigUtil.HOST_URL+"rest/provision/call/voice/port/v1.0";//商用环境
            Map reqMap = new HashMap();
            reqMap.put("app_key", ClickCallConfigUtil.APPKEY);
            //刷新令牌。授权时CaaS平台返回的access_token字段的值
            reqMap.put("access_token", access_token);
            Map headerMap = setJsonContentType();
            String reqParams = HttpClientUtil.getConcatParams(reqMap);
            String newReqUrl= java.net.URLDecoder.decode(reqUrl+"?"+reqParams,"utf-8");  ;//请求链接
            
            String retMsg = HttpClientUtil.createHttps(newReqUrl,"POST",headerMap,true,GlobalConstants.SSL_VERSION,null);
            if(ObjectUtil.isNotEmpty(retMsg) && !"FAIL".equals(retMsg)){ 
                JSONObject jsonObject =JSONObject.fromObject(retMsg);
            }else{
            }
        } catch (UnsupportedEncodingException e) {
            logger.error("queryCallUseVoicePort");
            e.printStackTrace();
        }
    }

11、点击回拨的录入下载

  • 在某种场景下,录音是非常重要的一个文件,比如:律师与用户的对话,当用户在交流过程中,用户听不太清楚律师的通话的时候,语音就显得尤其为重要,这时,用户就可以在软件App里面在线反复听音频。
  • 代码实现
/**
     * 
     * @Description 华为点击回拨的录入下载是调用amazon(亚马逊)https://aws.amazon.com/releasenotes/4473256057156237  
     * 下载sdk请参考官方文档,地址为:Download the latest AWS SDK for Java
     * 
     * @Author      liangjilong  
     * @Email       [email protected] 
     * @Date        2017年8月1日 上午11:00:47  
     * @param fileName  录音文件名(S3存储对象)
     * @param buckName  录音文件名所在的目录名(S3存储桶名)
     * @return 参数  
     * @return String 返回类型
     */
    public static String []  downRecordFile(String fileName,String buckName ){
        
        try {
            String filePath = PropertiesLoader.getProperty("HuaWei.recordPath");
            //不存在就创建目录.
            IoUtils.createDirectory(filePath);
            
            String appKey = PropertiesLoader.getProperty("HuaWei.AK");//获取AppKey
            String appSecret = PropertiesLoader.getProperty("HuaWei.SK");//获取AppSecret
            String urlPort = PropertiesLoader.getProperty("HuaWei.RecordUrl");//获取录入URl
            //String buckName = PropertiesLoader.getProperty("HuaWei.buckName");//存储空间名称
            //创建亚马逊AWSCredentials对象
            AWSCredentials credentials = new BasicAWSCredentials(appKey, appSecret);
            //创建亚马逊AmazonS3对象
            AmazonS3 amazonS3 = new AmazonS3Client(credentials);
            amazonS3.setEndpoint(urlPort);//调用录入接口地址
            //建立亚马孙http请求
            GeneratePresignedUrlRequest httpRequest = new GeneratePresignedUrlRequest(buckName, fileName);

            String tmpUrl = amazonS3.generatePresignedUrl(httpRequest).toString();
            
            CloseableHttpClient client = HttpClientUtil.createHttpClient();
            HttpGet httpget = new HttpGet(tmpUrl);
            CloseableHttpResponse resp = client.execute(httpget);

            int status = resp.getStatusLine().getStatusCode();
            if (status==200) {
               HttpEntity entity = resp.getEntity();
               if(ObjectUtil.isNotEmpty(entity)){
                   IoUtils.writer(entity.getContent(), filePath+"/"+fileName);
                   logger.info("下载录入文件成功,下载文件为:"+fileName);
               }
               return new String []{tmpUrl,"true"};
               //return true;
           } else {
               HttpEntity entity = resp.getEntity();
               if(ObjectUtil.isNotEmpty(entity)){
                   String retMsg = IoUtils.readerByIs(entity.getContent());
                   logger.error("下载录入文件失败,返回信息为:"+retMsg);
               }
               return new String []{tmpUrl,"false"};
             }
        } catch (Exception e) {
            logger.error("下载录入文件失败,返回信息为:"+e.getMessage());
            e.printStackTrace();
        }
        return null;
    }

12、呼叫状态和话单通知

  • 开发方提供接口连接接收第三方API的入参数Body
  • 第三方SP如果需要获取呼叫状态信息和话单记录,可根据如下两种情况进行操作:l 若第三方SP使用的开放功能为点击呼叫、语音验证码、语音通知时,可在申请APP时指定statusUrl和feeUrl,或在发起请求时填写statusUrl和feeUrl即可。l 若第三方SP使用的开放功能为其他功能,需要在申请APP时指定statusUrl和feeUrl。CaaS平台就会把此次呼叫对应的呼叫状态和话单推送给第三方服务器的URL。statusUrl和feeUrl只支持POST方法。注:若CaaS平台推送话单给SP失败,会重传话单,直至SP接收成功。最多重传6次,每次时间间隔1小时
  • 应用场景
    SP实时获取每个呼叫的状态
    SP实时获取每个呼叫的话单
statusUrl和feeUrl
feeUrl
  • SP用于接收状态上报的URL;点 击类业务触发过程中通话的状态,信息CaaS平台会推送至此服务器地址(支持域名和IP);此字段要求进行BASE64编码。最大128字节
statusUrl
第三方API的入参数Body

关键源代码和文档下载

你可能感兴趣的:(点击回拨电话呼叫项目案例研发指南)