使用mod_curl实现FreeSWITCH与电商客服中心API鉴权集成,支持VIP客户动态路由
1. 业务场景与目标
电商客服中心在促销高峰期面临大量来电,需智能分配:VIP客户(如年消费>10万元)应优先接入专属销售坐席,普通客户接入常规客服。传统静态路由无法实时识别客户价值。目标:通过mod_curl调用CRM API,根据来电号码实时查询客户等级(VIP/普通),动态路由到不同坐席组(vip_sales/support),并播放个性化欢迎词,提升VIP客户满意度和销售转化。
2. 环境准备(uv + 依赖)
本任务类型为系统集成与配置。需安装FreeSWITCH(版本1.10+)并启用mod_curl模块,外部API服务使用Python Flask框架模拟。
- 安装FreeSWITCH:参考官方文档(如
apt-get install freeswitch)。 - 检查mod_curl:在FreeSWITCH控制台执行
load mod_curl,确认模块加载成功。 - 外部API环境:使用uv创建Python虚拟环境并安装依赖。
uv venv venv source venv/bin/activate uv add flask requests
3. 数据说明(真实数据口径或模拟数据生成逻辑)
模拟电商CRM数据:API根据来电号码查询客户等级。数据生成逻辑:来电号码以138开头模拟VIP客户(年消费>10万),返回{"customer_level": "VIP", "agent_group": "vip_sales", "greeting": "尊贵的VIP客户,为您转接专属顾问"};其他号码模拟普通客户,返回{"customer_level": "normal", "agent_group": "support", "greeting": "您好,客服代表为您服务"}。真实业务中,API应连接真实CRM数据库,查询客户消费记录。
4. 训练/实现步骤(完整代码)
步骤1:配置FreeSWITCH的mod_curl
编辑/etc/freeswitch/autoload_configs/curl.conf.xml,设置超时和重试参数。
<configuration name="curl.conf" description="cURL Configuration">
<settings>
<param name="enable" value="true"/>
<param name="timeout" value="3"/>
<param name="retries" value="2"/>
<param name="retry-delay" value="1000"/>
</settings>
</configuration>
步骤2:编写电商CRM API服务(Flask应用)
创建ecommerce_api.py,实现鉴权和客户等级查询。
from flask import Flask, request, jsonify
import time
import logging
app = Flask(__name__)
API_KEY = "ecommerce_secret_2024" # 实际应使用环境变量如os.getenv('API_KEY')
@app.route('/customer/route', methods=['POST'])
def route_call():
# 鉴权:检查API密钥
auth_key = request.headers.get('X-API-Key')
if auth_key != API_KEY:
app.logger.warning(f"Unauthorized access attempt with key: {auth_key}")
return jsonify({"error": "Unauthorized"}), 401
# 获取来电号码
data = request.json
caller_id = data.get('caller_id', '')
if not caller_id:
return jsonify({"error": "Missing caller_id"}), 400
# 模拟电商CRM查询:VIP客户识别
# 真实场景:此处应查询数据库,例如SELECT customer_level FROM customers WHERE phone=caller_id
if caller_id.startswith('138'):
# VIP客户,模拟查询耗时200ms
time.sleep(0.2)
response = {
"customer_level": "VIP",
"agent_group": "vip_sales",
"greeting": "尊贵的VIP客户,为您转接专属顾问"
}
else:
# 普通客户,模拟查询耗时100ms
time.sleep(0.1)
response = {
"customer_level": "normal",
"agent_group": "support",
"greeting": "您好,客服代表为您服务"
}
app.logger.info(f"Call from {caller_id} routed to {response['agent_group']}")
return jsonify(response), 200
if __name__ == '__main__':
logging.basicConfig(level=logging.INFO)
app.run(host='0.0.0.0', port=5000, debug=False)
步骤3:配置FreeSWITCH拨号计划
编辑/etc/freeswitch/dialplan/default.xml,添加动态路由逻辑,包含超时回退机制。
<extension name="ecommerce_dynamic_routing">
<condition field="destination_number" expression="^\d+$">
<!-- 调用CRM API,超时3秒,重试2次 -->
<action application="curl"
data="http://localhost:5000/customer/route post application/json {\"caller_id\": ${caller_id_number}} X-API-Key:ecommerce_secret_2024"/>
<action application="set"
data="api_response=${curl_response_data}"/>
<action application="log"
data="INFO Raw API Response: ${api_response}"/>
<!-- 解析API响应,如果失败则使用默认路由 -->
<action application="set"
data="agent_group=${regex(${api_response} |\"agent_group\":\"([^\"]+)\")}"/>
<action application="set"
data="greeting=${regex(${api_response} |\"greeting\":\"([^\"]+)\")}"/>
<!-- 检查解析结果,如果为空则使用默认值 -->
<action application="execute_extension"
data="check_api_result"/>
</condition>
</extension>
<extension name="check_api_result">
<condition field="${agent_group}" expression="^$">
<action application="log"
data="WARNING API call failed, using default routing"/>
<action application="set"
data="agent_group=support"/>
<action application="set"
data="greeting=您好,客服代表为您服务"/>
</condition>
<condition>
<action application="answer"/>
<action application="playback"
data="say:${greeting}"/>
<action application="bridge"
data="sofia/internal/1000@${agent_group}.example.com"/>
</condition>
</extension>
5. 调用方式
-
单条示例:在FreeSWITCH控制台执行命令测试VIP客户路由。
# 在FreeSWITCH CLI中执行,模拟VIP来电 originate sofia/gateway/your_gateway/13800138000 &bridge # 预期:调用API,路由到vip_sales坐席组,播放VIP欢迎词 -
离线批量:使用ESL脚本模拟100个来电号码,测试路由准确性和性能。创建
batch_test.py。import ESL import time import random
连接FreeSWITCH ESL
con = ESL.ESLconnection(“localhost”, “8021”, “ClueCon”) if not con.connected(): print(“Failed to connect to FreeSWITCH”) exit(1)
生成测试号码:50个VIP(138开头),50个普通
testnumbers = [f”138{random.randint(10000000, 99999999):08d}” for in range(50)] testnumbers += [f”139{random.randint(10000000, 99999999):08d}” for in range(50)]
print(f”Starting batch test for {len(test_numbers)} calls…”) success_count = 0 for i, number in enumerate(test_numbers, 1):
发起呼叫
cmd = f"originate sofia/gateway/test_gw/{number} &bridge"
result = con.api(cmd)
if "+OK" in result.getBody():
success_count += 1
print(f"Call {i}: {number} initiated successfully")
else:
print(f"Call {i}: {number} failed - {result.getBody()}")
# 间隔100ms避免过载
time.sleep(0.1)
print(f”Batch test completed. Success rate: {success_count}/{len(test_numbers)} ({success_count/len(test_numbers)*100:.1f}%)”) con.disconnect()
## 6. 指标说明
- **FreeSWITCH**:开源电话软交换平台,处理语音通话和路由,相当于电话系统的“大脑”。
- **mod_curl**:FreeSWITCH模块,允许通过HTTP调用外部API,类似浏览器访问网页但用于电话系统。
- **API鉴权**:验证请求是否合法,本项目中通过API密钥(X-API-Key)实现,防止未授权访问。
- **动态路由**:根据实时数据(如来电号码)决定通话去向,比如VIP客户转销售,普通客户转客服。
- **拨号计划**:FreeSWITCH中定义通话处理规则的配置文件,告诉系统如何响应来电。
- **CRM系统**:客户关系管理系统,存储客户信息如购买记录、等级,用于路由决策。
- **坐席组**:客服或销售团队的分组,如vip_sales组专门服务VIP客户。
- **API调用成功率**:FreeSWITCH成功调用API并获得有效响应的比例,例如100次调用中95次成功,成功率为95%。
- **平均响应时间**:从FreeSWITCH发送API请求到收到回复的平均耗时,影响通话延迟,目标小于500毫秒。
- **通话接通率**:成功接通的通话占总通话数的比例,反映系统整体稳定性,目标>98%。
- **ESL**:Event Socket Library,FreeSWITCH的事件接口,允许外部程序控制通话。
## 7. 上线后评估(运行指标,评估方法)
- **API调用成功率**:目标>99%。评估方法:监控FreeSWITCH日志,统计`curl`命令的成功与失败次数。实施步骤:部署日志收集脚本,解析日志中的`curl_response_data`字段,计算成功率。
- **平均响应时间**:目标<500ms。评估方法:测量API耗时,从FreeSWITCH日志提取时间戳。实施步骤:在拨号计划中添加`<action application="log" data="INFO API time: ${curl_response_time}"/>`,使用脚本计算平均值。
- **通话接通率**:目标>98%。评估方法:分析CDR(呼叫详细记录)文件。实施步骤:配置CDR存储,编写Python脚本解析CDR,统计状态为`ANSWERED`的比例。
- **监控仪表板配置**:使用Prometheus+Grafana实时监控。实施步骤:在API服务中添加/metrics端点暴露指标(如请求数、延迟),配置Prometheus抓取,Grafana展示仪表板。
## 8. 常见坑与排查
- **API响应超时导致通话失败**:现象:通话卡顿或直接挂断。排查:检查API服务器负载和网络延迟。实际操作:在`curl.conf.xml`中调整超时和重试参数,如设置`<param name="timeout" value="5"/>`和`<param name="retries" value="3"/>`;在拨号计划中添加超时回退逻辑(如本文步骤3的`check_api_result`扩展)。
- **鉴权逻辑漏洞引发安全风险**:现象:API返回401错误。排查:确认API密钥在FreeSWITCH配置中正确,且传输加密。实际操作:使用环境变量存储密钥,避免硬编码;在FreeSWITCH CLI测试:`curl http://localhost:5000/customer/route -H "X-API-Key:ecommerce_secret_2024"`验证连通性。
- **配置错误导致路由混乱**:现象:客户被错误路由(如VIP转到普通坐席)。排查:检查拨号计划中的正则表达式是否匹配JSON响应。实际操作:在拨号计划中添加详细日志输出`<action application="log" data="INFO Parsed agent_group: ${agent_group}"/>`,对比API原始响应。
- **外部系统故障影响通话**:现象:API服务宕机,所有通话失败。排查:监控API健康状态。实际操作:实现心跳检测,例如FreeSWITCH定时调用API健康检查端点;部署备用API服务器,在拨号计划中使用故障转移逻辑。