
# 回调接口说明
AICC支持对第三方系统给定的URL进行回调，将当前通话事件推送给第三方系统。
由于系统不断演变，语音通知的回调URL有两种配置方式：
- 通过界面配置：租户管理员选择"配置中心 \> 扩展与集成 \> 语音通知"，进入"语音通知回调配置"设置"挂机回调url"。
- 通过创建语音通知接口传入：调用创建通知接口时传入请求参数callBackUrl。
![](https://support.huaweicloud.com/api-ccfs-cec/public_sys-resources/note_3.0-zh-cn.png)
- 通过界面配置回调URL的方式，URL鉴权方式为不鉴权，不鉴权可能有安全风险，请谨慎使用。
- 如果两种方式都配置了回调URL，优先选择接口传入的URL。推荐接口传入callBackUrl，并配置共享密匙。
- HTTPS采用TLS1.2及以上版本，确保web应用的敏感数据在传输过程中不被非法截获
 
#### 语音通知回调接口签名算法说明
- **签名算法（鉴权）使** **用前** **提** **条件**
  当通过创建语音通知接口传入URL，并在"回调url配置"界面中"请输入共享密钥"配置了共享密钥。请参考本节进行签名验证。
  

- **鉴权过程**
  1. 释放事件回调接口请求入参会增加以下字段： timestamp：当前时间戳
     nonce：随机字符串
     signature：鉴权签名
     
  
  2. 客户侧收到回调后，需要根据签名算法生成鉴权签名，并与入参的signature进行校验，若一致表示验证通过。
   

- **签名（signature）字符串生成方式** ：
  1. 根据参数名称对所有的请求参数（除这三个参数外：timestamp、nonce、signature）进行字典排序，然后用英文逗号拼接成字符串。例如将{"b":"2", "a":1}排序拼接为"a=1,b=2"。
  
  2. 生成timestamp时间戳及nonce随机字符串，并和appSecret（界面配置的共享密钥）及[1]生成的字符串通过 _ 拼接在一起。格式为 appSecret_timestamp_nonce_[1]生成的字符串。
  
  3. 通过SHA256算法加密成byte数组，然后将该数组Base64编码。
   

- **参考代码**
  ```
  import javax.crypto.Mac;
  import javax.crypto.spec.SecretKeySpec;
  private String generateSinature(TreeMap<String, Object> callbackParametters, String nonce, long timestamp, String appSecret) {
      // appSecret_timestamp_nonce_参数
      // {"b":"2", "a":1}排序拼接后的字符串是："a=1,b=2"
      String paramStr = callbackParametters.toString().replace(" ", "");
      String toSignString = appSecret + "_" + timestamp + "_" + nonce + "_" + 
             paramStr.substring(1, paramStr.length() - 1);
      return Base64.encodeBase64String(tokenByHmacSha256(toSignString.getBytes(StandardCharsets.UTF_8), appSecret));
  }
  public static byte[] tokenByHmacSha256(byte[] dataBytes, String appSecret) {
      try {
          Mac mac = Mac.getInstance("HmacSHA256");
          byte[] key = appSecret.getBytes(StandardCharsets.UTF_8);
          SecretKeySpec secretKey = new SecretKeySpec(key, "HmacSHA256");
          mac.init(secretKey);return mac.doFinal(dataBytes);
      } catch (Exception e) {
          LOGGER.error("tokenByHmacSha256 failed: ", e);throw new RuntimeException("HmacSha256 run failed.");
      }
  }
  ```
  
 
