Search...
Menu

IVR Inbound

You can confirm whether to enable this feature based on your business needs. Using  IVR can help improve the service capacity for incoming calls, such as:

  1. Work time control: You can use the IVR navigation to control the distribution of calls to agents during work hours, and guide calls outside of work hours to voicemail or play a voice prompt before disconnecting.
  2. Business navigation configuration: You can use the IVR navigation to guide users to make selections based on their different business requests, and then transfer them to the appropriate agent or agent group for handling.

 1. Create IVR

IVR(Interactive Voice Response) allows users to select the service they need by pressing a button when calling into our system。We can provide different services through the user's choice:like:

  • transfer the call to the Specified Agent;
  • transfer the call to the Specified Agent Group;
  • Go to the message box;
  • Based on local time, determine whether to transfer to an agent.
  • Hang up

Menu:Management- Self Service -Voice Flow

Steps:

  1. Click the "Add" or "New" button
  2. In the pop-up dialog, enter the name for the IVR
  3. Click the "Confirm" or "OK" button

2. Edit IVR

Steps:

  1. Select the IVR that needs to be edited, and click "Edit".

  2. Set the IVR navigation region/language (the system will automatically select the corresponding TTS capability) and time zone (time-based decisions will be made based on the respective time zone).

  3. Click "+" to add a new IVR node. The available node types include:

    • Playback
    • Key Press
    • Time-jundgment
    • Transfer to Agent Group
    • Transfer to Agent
    • Transfer to Voicemail
  4. Click the "Save" button to temporarily save the IVR flow, and then click "Publish" to officially publish the IVR flow

3. Use IVR

Menu: Management - Voice - My Numbers

Steps:

  1. Select the DID (Direct Inward Dialing) number that you want to configure the IVR for, and click "Settings".

  2. Select "Route to: IVR" as the call handling option.

  3. In the IVR flow dropdown, select the IVR that has already been published.

  4. Click the "Confirm" button to complete the configuration.

  5. When users call this number, they will be routed directly into the configured IVR flow.

4. Examples of common IVR progress

Handle incoming calls based on business hours

Functionality:

  • During normal business hours from 8am to 8pm on weekdays, calls will be routed to the agent group.

  • Outside of normal business hours, callers will be guided to leave a voicemail message.

Assign agents based on the services required by the user

Functionality:

  • If the customer presses 1, they will be played a prompt saying the return service is not supported currently, and then redirected back to the IVR menu.
  • If the customer presses 2, they will be transferred to the A agent group for package tracking inquiries.
  • If the customer presses 3, they will be transferred to a agent group.
  • If the customer makes an invalid key press, they will hear a prompt asking them to try again with the correct key.
  • If the customer makes 3 invalid key presses, they will hear a message saying there were too many invalid entries, and the call will be disconnected.

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&timestamp=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&timestamp=1743413535&body={"name":"牛小信","id":10001}
                }else{
                    raw.append(bodyStr); // {"name":"牛小信","id":10001}
                }
                log.info("step2: {}", raw); // action=test&secretKey=77ed1dda&timestamp=1743413535&body={"name":"牛小信","id":10001}
            }

            // step3: 拼接accessSecret
            raw.append("&accessSecret=").append(accessSecret);
            log.info("step3: {}", raw); // test&secretKey=77ed1dda&timestamp=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;
    }
}

Previous
AI Outbound
Next
Report
Last modified: 2025-06-10