一.阿里云和华为云的区别大致说下:
1.阿里云AXB中的X是从阿里云控制到中的号码池中选出来的(X号码在号码池中买)阿里的X 大致绑定200对,华为的可以绑定1000对
2.一般这个功能就是在App中虚拟通话,无论阿里还是华为这个功能是收费的,所以要监控客户的打电话时间。如果通话时间超过了缴费所对应的时间 需要平台挂断 。
3.上边提到这个平台挂断阿里的产品是没有这个功能,华为中有一个接口来终止通话axbStopCall
二.号码隐私流程
// 第一步: 号码绑定,即调用AXB模式绑定接口
axb.axbBindNumber("+8617010000001", "+8618612345678", "+8618612345679");
// 当用户发起通话时,隐私保护通话平台会将呼叫事件推送到商户应用
// 当用户使用短信功能,隐私保护通话平台将短信事件推送到商户应用
// 第二步: 用户通过隐私号码发起呼叫后,商户可随时终止一路呼叫,即调用终止呼叫接口
// axb.axbStopCall("1200_366_0_20161228102743@callenabler.home1.com");
// 第三步: 用户通话结束,若设置录音,则商户可以获取录音文件下载地址,即调用获取录音文件下载地址接口
// axb.axbGetRecordDownloadLink("ostor.huawei.com", "1200_366_0_20161228102743.wav");
// 第四步: 根据业务需求,可更改绑定关系,即调用AXB模式绑定信息修改接口
// axb.axbModifyNumber("efw89efwf7fea324252", "+8618612345679", null);
// 第五步: 隐私号码循环使用,商户可将绑定关系解绑,即调用AXB模式解绑接口
// axb.axbUnbindNumber(null, "+8617010000001");
// 第六步: 商户可查询已订购的隐私号码的绑定信息,即调用AXB模式绑定信息查询接口
三. 说说其中的坑
1.首先用这个华为云的AXB 功能需要公司申请认证,然后拿到 appkey ,appsecret,ompDomainName (这个是app的接入地址,这个作用是拼接各个接口的)
2.我最主要的用的功能就是这个终止呼叫接口,axbStopCall接口 这个接口的参数是sessionId ,但是你绑定AXB的时候华为没有给你返,那这个sessionId 怎么拿呢。你需要出一个接口 来接受消息回执(这个是阿里中的说法,华为叫话单通知接口,名字比较拗口,就暂用消息回执)。这个消息回执中需要接受华为传给你的参数 关于这个电话的详细参数,这里面有sessionId,你存到数据库中怎么来取呢 根据绑定Id subscriptionId 这个字段来取 接下来就很简单了
3.接下来附上我的service 各个接口的代码
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.shanmi.api.user.service.AXBService;
import com.shanmi.api.user.utils.HttpUtil;
import com.shanmi.api.user.vo.AxbRequestVO;
import com.shanmi.plf.core.common.validator.Assert;
import com.shanmi.user.biz.UserAxbBiz;
import com.shanmi.user.entity.UserAxb;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author zhangshoubo
* @Date 2020/07/23
*/
@Service
@Slf4j
public class AXBServiceImpl implements AXBService {
@Autowired
private UserAxbBiz userAxbBiz;
@Value("${huaweiyun.axb.appKey}")
private String appKey;
@Value("${huaweiyun.axb.appSecret}")
private String appSecret;
@Value("${huaweiyun.axb.ompDomainName}") // APP接入地址
private String ompDomainName;
@Value("${huaweiyun.axb.relationNum}") x号码
private String relationNum;
private String buildOmpUrl(String path) {
return ompDomainName + path;
}
@Override
public String axbBindNumber(AxbRequestVO axbRequestVO) {
if (StringUtils.isBlank(relationNum) || StringUtils.isBlank(axbRequestVO.getCallerNum()) || StringUtils.isBlank(axbRequestVO.getCalleeNum())) {
//log.info("axbBindNumber set params error");
Assert.isNull(axbRequestVO,"axb绑定参数异常");
}
// 必填,AXB模式绑定接口访问URI
String url = "/rest/caas/relationnumber/partners/v1.0";
String realUrl = buildOmpUrl(url);
// 封装JOSN请求
JSONObject json = new JSONObject();
json.put("relationNum", relationNum); // X号码(关系号码)
json.put("callerNum", axbRequestVO.getCallerNum()); // A方真实号码(手机或固话)
json.put("calleeNum", axbRequestVO.getCalleeNum()); // B方真实号码(手机或固话)
json.put("recordFlag", false); //是否通话录音
json.put("callDirection", 0); //允许呼叫的方向
json.put("duration", 600); //绑定关系保持时间 10分钟
json.put("maxDuration", 10); //单次通话最长时间
json.put("lastMinVoice", "lastMinVoice.wav"); //通话最后一分钟提示音
/**
* 选填,各参数要求请参考"AXB模式绑定接口"
*/
// json.put("areaCode", "0755"); //城市码
// json.put("areaMatchMode", "1"); //号码筛选方式
// json.put("callDirection", 0); //允许呼叫的方向
// json.put("duration", 86400); //绑定关系保持时间
// json.put("recordFlag", false); //是否通话录音
// json.put("recordHintTone", "recordHintTone.wav"); //录音提示音
// json.put("maxDuration", 60); //单次通话最长时间
// json.put("lastMinVoice", "lastMinVoice.wav"); //通话最后一分钟提示音
// json.put("privateSms", true); //是否支持短信功能
// JSONObject preVoice = new JSONObject();
// preVoice.put("callerHintTone", "callerHintTone.wav"); //设置A拨打X号码时的通话前等待音
// preVoice.put("calleeHintTone", "calleeHintTone.wav"); //设置B拨打X号码时的通话前等待音
// json.put("preVoice", preVoice); //个性化通话前等待音
String result = HttpUtil.sendPost(appKey, appSecret, realUrl, json.toString());
log.info("AXB绑定接口 Response is :" + result);
return result;
}
@Override
public String axbUnbindNumber(AxbRequestVO axbRequestVO) {
if (StringUtils.isBlank(axbRequestVO.getSubscriptionId()) || StringUtils.isBlank(relationNum)) {
Assert.isNull(axbRequestVO,"axb解绑参数异常");
}
// 必填,AXB模式解绑接口访问URI
String url = "/rest/caas/relationnumber/partners/v1.0";
String realUrl = buildOmpUrl(url);
// 申明对象
Map<String, Object> map = new HashMap<String, Object>();
if (StringUtils.isNotBlank(axbRequestVO.getSubscriptionId())) {
map.put("subscriptionId", axbRequestVO.getSubscriptionId()); // 绑定关系ID
} else {
map.put("relationNum", relationNum); // X号码(关系号码)
}
String result = HttpUtil.sendDelete(appKey, appSecret, realUrl, HttpUtil.map2UrlEncodeString(map));
log.info("AXB解绑接口 Response is :" + result);
return result;
}
@Override
public String axbStopCall(AxbRequestVO axbRequestVO) {
if (StringUtils.isBlank(axbRequestVO.getSubscriptionId())) {
Assert.isNull(axbRequestVO,"axb解绑参数异常");
}
/**
* 根据subscriptionId 去库中查询 sessionId
* 在根据sessionId 来中断通话
*/
UserAxb userAxb = userAxbBiz.selectSessionIdBySubscriptionId(axbRequestVO.getSubscriptionId());
if (userAxb == null){
Assert.isNull(userAxb,"获取sessionId参数异常");
}
String sessionid = userAxb.getSessionid();
if (StringUtils.isBlank(sessionid)) {
Assert.isBlank(sessionid,"axb终止呼叫参数异常");
log.info("axbStopCall set params error");
}
// 必填,AXB模式终止呼叫接口访问URI
String url = "/rest/httpsessions/callStop/v2.0";
String realUrl = buildOmpUrl(url);
// 封装JOSN请求
JSONObject json = new JSONObject();
json.put("sessionid", sessionid); // 呼叫会话ID
json.put("signal", "call_stop"); // 取值固定为"call_stop"
String result = HttpUtil.sendPost(appKey, appSecret, realUrl, json.toString());
log.info("终止呼叫 Response is :" + result);
return result;
}
@Override
public String axbQueryBindRelation(AxbRequestVO axbRequestVO) {
if (StringUtils.isBlank(axbRequestVO.getSubscriptionId()) || StringUtils.isBlank(relationNum)) {
Assert.isBlank(axbRequestVO.getSubscriptionId(),"axb查詢接口参数异常");
}
// 必填,AXB模式绑定信息查询接口访问URI
String url = "/rest/caas/relationnumber/partners/v1.0";
String realUrl = buildOmpUrl(url);
// 申明对象
Map<String, Object> map = new HashMap<String, Object>();
if (StringUtils.isNotBlank(axbRequestVO.getSubscriptionId())) {
map.put("subscriptionId", axbRequestVO.getSubscriptionId()); // 绑定关系ID
} else {
map.put("relationNum", relationNum); // X号码(关系号码)
/**
* 选填,各参数要求请参考"AXB模式绑定信息查询接口"
*/
// map.put("pageIndex", 1); //查询的分页索引,从1开始编号
// map.put("pageSize", 20); //查询的分页大小,即每次查询返回多少条数据
}
String result = HttpUtil.sendGet(appKey, appSecret, realUrl, HttpUtil.map2UrlEncodeString(map));
log.info("查询AXB绑定信息 Response is :" + result);
return result;
}
@Override
public String onFeeEvent(JSONObject jsonBody) {
JSONObject jsonObject = new JSONObject();
// 封装JSON请求
JSONObject json = jsonObject.parseObject(jsonBody.toJSONString());
String eventType = json.getString("eventType"); // 通知事件类型
if (!("fee".equalsIgnoreCase(eventType))) {
log.info("EventType error: " + eventType);
}
JSONArray feeLst = json.getJSONArray("feeLst"); // 呼叫话单事件信息
List<UserAxb> list = new ArrayList<>();
Map<String,Object> map = new HashMap<>();
if (feeLst.size() > 0) {
for (Object userAxb : feeLst) {
UserAxb user = new UserAxb();
user.setSessionid(((JSONObject) userAxb).getString("sessionId").toString());
user.setSubscriptionid(((JSONObject) userAxb).getString("subscriptionId").toString());
user.setSpid(((JSONObject) userAxb).getString("spId").toString());
user.setAppkey(((JSONObject) userAxb).getString("appKey").toString());
user.setIcid(((JSONObject) userAxb).getString("icid").toString());
user.setBindnum(((JSONObject) userAxb).getString("bindNum").toString());
user.setCallernum(((JSONObject) userAxb).getString("callerNum").toString());
user.setCalleenum(((JSONObject) userAxb).getString("calleeNum").toString());
user.setFwddisplaynum(((JSONObject) userAxb).getString("fwdDisplayNum").toString());
user.setFwddstnum(((JSONObject) userAxb).getString("fwdDstNum").toString());
user.setCallintime(((JSONObject) userAxb).getDate("callInTime"));
user.setFwdstarttime(((JSONObject) userAxb).getDate("fwdStartTime"));
user.setFwdalertingtime(((JSONObject) userAxb).getDate("fwdAlertingTime"));
user.setFwdanswertime(((JSONObject) userAxb).getDate("fwdAnswerTime"));
user.setCallendtime(((JSONObject) userAxb).getDate("callEndTime"));
user.setFailtime(((JSONObject) userAxb).getDate("failTime"));
user.setFwdunaswrsn(((JSONObject) userAxb).getInteger("fwdUnaswRsn"));
user.setUlfailreason(((JSONObject) userAxb).getInteger("ulFailReason"));
user.setSipstatuscode(((JSONObject) userAxb).getInteger("sipStatusCode"));
user.setDirection(((JSONObject) userAxb).getLong("direction"));
list.add(user);
}
userAxbBiz.insertList(list);
}
return "ok";
}
}
import lombok.Data;
/**
* @author zhangshoubo
* @Date 2020/07/18$
*/
@Data
public class AxbRequestVO {
private String callerNum; //主叫A
private String calleeNum;// 被叫B
private String subscriptionId;// 通话唯一Id
}
希望大神指出我的问题 阿里的AXB我也写了代码 想要的评论