API invocation within IVR
New Authentication Method
Operation path: Management-third-party docking-API overview and settings-new
Select the corresponding signature algorithm and fill in the SecretValue, which will be used as the key to sign the actual http request;
IVR configuration call API node
Operation path: Management-IVR management-add (edit)-add node "call API"
Select the configured authentication method and fill in the corresponding API Request information; (remember to fill in the appropriate maximum Request timeout period)
Divert to different logic based on response data
Transfer to the agent group: Remember to add the tester account to the agent group first (Operation path: Management- People - Voice Agent Group)
Line routing Association IVR process
Operation Path: Management-Call Center Settings-Routing Management-(Existing Routing) Edit
Incoming call trigger process
An incoming call from outside to a bound number on the line
Server-side signature verification tool
package com.nx.callcenter.service.utils;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson2.JSONObject;
import com.nx.callcenter.enums.TenantApiAuthEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
/**
* @author huangqueqi
*/
@Slf4j
public class ApiAuthSignUtils {
/**
* 生成接口参数签名demo
*/
public static void main(String[] args) {
// header参数
Map<String, String> headers = new HashMap<>(8);
headers.put("secretKey", "77ed1dda");
headers.put("action", "test");
headers.put("timestamp", System.currentTimeMillis()/1000 + "");
// accessKey对应的密码
String accessSecret = "00163e067561";
// 业务参数
Map<String, Object> body = new HashMap<>();
body.put("id", 10001);
body.put("name", "牛小信");
System.out.println(calcSign(headers, body, accessSecret,"HMAC-MD5"));
// System.out.println(calcSign(headers, body, accessSecret,"HMAC-SHA256"));
// System.out.println(calcSign(headers, body, accessSecret,"HMAC-SHA512"));
// log.info("sign: {}", sign); // sign: 87c3560d3331ae23f1021e2025722354
}
/**
* 计算sign签名
*
* @param headers 请求头中的公共参数
* @param body body中的json字符串
* @param accessSecret 秘钥
* @param algorithmType 加密方式
* @return
*/
public static String calcSign(Map<String, String> headers, Map<String, Object> body,
String accessSecret, String algorithmType) {
try{
StringBuilder raw = new StringBuilder();
// step1: 拼接header参数
if(CollUtil.isNotEmpty(headers)) {
// 使用TreeMap自动按ASCII码升序排序
Map<String, String> sortedHeaders = new TreeMap<>(headers);
for (Map.Entry<String, String> entry : sortedHeaders.entrySet()) {
raw.append(entry.getKey())
.append("=")
.append(entry.getValue())
.append("&");
}
if (raw.length() > 0) {
raw.deleteCharAt(raw.length() - 1); // 删除末尾多余的&
}
log.info("step1: {}", raw); // step1: action=test&secretKey=77ed1dda×tamp=1743413535
}
// step2: 拼接body参数
if(CollUtil.isNotEmpty(body)) {
String bodyStr = JSONObject.toJSONString(body);
if (raw.length() > 0) {
raw.append("&body=").append(bodyStr); // action=test&secretKey=77ed1dda×tamp=1743413535&body={"name":"牛小信","id":10001}
}else{
raw.append(bodyStr); // {"name":"牛小信","id":10001}
}
log.info("step2: {}", raw); // action=test&secretKey=77ed1dda×tamp=1743413535&body={"name":"牛小信","id":10001}
}
// step3: 拼接accessSecret
raw.append("&accessSecret=").append(accessSecret);
log.info("step3: {}", raw); // test&secretKey=77ed1dda×tamp=1743413535&body={"name":"牛小信","id":10001}&accessSecret=00163e067561
// step4: MD5算法加密,结果转换成十六进制小写
String sign = null;
if(algorithmType.equals(TenantApiAuthEnum.ALGORITHM_MD5.getName())) {
sign = DigestUtils.md5Hex(raw.toString());
}else if(algorithmType.equals(TenantApiAuthEnum.ALGORITHM_SHA256.getName())) {
sign = DigestUtils.sha256Hex(raw.toString());
}else if(algorithmType.equals(TenantApiAuthEnum.ALGORITHM_SHA512.getName())) {
sign = DigestUtils.sha512Hex(raw.toString());
}
log.info("step4: algorithmType={}, sign={}", algorithmType, sign); // step4: sign=fe78d3b72cef9247e7e14add91019397
return sign;
}catch (Exception e){
log.error("ApiAuthSignUtils.calcSign error",e);
}
return null;
}
}