顶顶通呼叫中心中间件(mod_cti基于FreeSWITCH)-电话机器人话术引擎说明

电话机器人话术引擎说明

介绍

介绍请看这个页面 http://www.ddrj.com/smartivr/robot.html
和smartivr接口的区别,smartivr接口只实现了把ASR识别结果提交给http接口进行处理,根据http接口返回的动作执行放音等操作。
新一代电话机器人接口实现了话术解析引擎,可以不依赖外部接口直接完成整个机器人对话过程。

开始执行流程

<action application="cti_robot" data="flowname"/>
<action application="set" data="park_timeout=3600000"/>
<action application="park"/>
  • flowname 流程名字,不需要.josn后缀

流程执行步骤记录

CREATE TABLE `conversation` (
`createtime` DATETIME NULL DEFAULT NULL COMMENT '记录生成事件',
`callid` VARCHAR(50) NULL DEFAULT NULL COMMENT '通话ID' COLLATE 'utf8_unicode_ci',
`current_appid` VARCHAR(50) NULL DEFAULT NULL COMMENT '当前执行APPID' COLLATE 'utf8_unicode_ci',
`sequence` INT(11) NULL DEFAULT NULL COMMENT '序列号',
`current_flowid` VARCHAR(50) NULL DEFAULT NULL COMMENT '当前流程ID' COLLATE 'utf8_unicode_ci',
`input_type` INT(11) NULL DEFAULT NULL COMMENT '输入类型0:TEXT 1:DTMF 2:COMPLETE 10:CREATE 11:DESTORY',
`input_args` VARCHAR(1024) NULL DEFAULT NULL COMMENT '输入参数' COLLATE 'utf8_unicode_ci',
`input_nlp_args` VARCHAR(50) NULL DEFAULT NULL COMMENT 'nlp处理后的参数' COLLATE 'utf8_unicode_ci',
`input_start_time` DATETIME NULL DEFAULT NULL COMMENT '输入开始时间',
`input_duration` INT(11) NULL DEFAULT NULL COMMENT '输入持续时间',
`input_play_time` INT(11) NULL DEFAULT NULL COMMENT '放音时间',
`matching_method` INT(11) NULL DEFAULT NULL COMMENT '匹配方法0:mismatch 1:boot 2:regex 3:full 4:any',
`matching_condition` VARCHAR(256) NULL DEFAULT NULL COMMENT '匹配表达式' COLLATE 'utf8_unicode_ci',
`condition_id` VARCHAR(50) NULL DEFAULT NULL COMMENT '匹配条件ID' COLLATE 'utf8_unicode_ci',
`condition_weight` INT(11) NULL DEFAULT NULL,
`matching_keyword` VARCHAR(50) NULL DEFAULT NULL COMMENT '匹配关键词' COLLATE 'utf8_unicode_ci',
`response_type` INT(11) NULL DEFAULT NULL COMMENT '响应类型 1:flow 2:kb 3:mismatch',
`response_description` VARCHAR(50) NULL DEFAULT NULL COMMENT '响应描述' COLLATE 'utf8_unicode_ci',
`response_id` VARCHAR(50) NULL DEFAULT NULL COMMENT '响应的FlowID,或者PromptID' COLLATE 'utf8_unicode_ci',
`response_action` VARCHAR(50) NULL DEFAULT NULL COMMENT '响应动作' COLLATE 'utf8_unicode_ci',
`response_args` VARCHAR(2048) NULL DEFAULT NULL COMMENT '响应参数' COLLATE 'utf8_unicode_ci',
`response_text` VARCHAR(8192) NULL DEFAULT NULL COMMENT '响应文本' COLLATE 'utf8_unicode_ci,
`repetition` INT(11) NULL DEFAULT NULL COMMENT 'kb:rompt重复播放次数 ,mismatch:连续未匹配次数 flow:已经执行次数',
`potential` VARCHAR(50) NULL DEFAULT NULL COMMENT '意向ID' COLLATE 'utf8_unicode_ci',
`record` VARCHAR(260) NULL DEFAULT NULL COMMENT '录音' COLLATE 'utf8_unicode_ci'
)
COLLATE='utf8_unicode_ci'
ENGINE=InnoDB
;
  • createtime 记录生成事件

  • callid 通话ID

  • current_appid 当前执行APPID

  • sequence 序列号,当前执行动作的次数

  • current_flowid 当前流程ID

  • input_type 输入类型0:TEXT 1:DTMF 2:COMPLETE 10:CREATE 11:DESTORY 20:FLOWID 30:ERROR 40:NOTIFY

    • TEXT asr转换后的文字
    • DTMF 按键
    • COMPLETE 动作执行完成
    • CREATE 进入流程创建上下文(input_args是话术名字:version[话术文件.json可以设置一个version字段设置话术版本])
    • DESTORY 离开流程销毁上下文
    • FLOWID 流程ID,比如通过知识库或者return动作切换流程(input_args:如果空就是返回父流程,否则就是流程ID)
    • ERROR 错误信息,比如切断流程失败(input_args:发生错误的流程ID,matching_condition:错误的流程ID,response_description:错误信息)
    • NOTIFY 触发通知
  • input_args 输入参数,input_type TEXT时asr识别结果,DTMF时按键内容,COMPLETE是完成输入参数,DESTORY是结束原因,FLOWID是切换流程参数,NOTIFY是通知参数

    • asr识别结果前缀说明

      • 前缀F:一句话识别完成
      • 前缀E:ASR错误
      • 前缀S:用户还在说话,实时识别中。
      • 前缀P:放音时的识别结果(打断模式128和256时放音时候说话才触发)
    • dtmf按键内容

      • d:未匹配到终止符
      • D:已经匹配到终止符
    • 完成输入参数

      • DONE() 输入完成,DONE(F:识别内容1F:识别内容2)

      • TIMEOUT() 输入超时了,TIMEOUT(F:放音时候的识别内容S:超过最大说话时间了)。如果没检测到声音就是TIMEOUT()。TIMEOUT(S:识别内容)这样的也代表一次ASR调用,也要对ASR进行计费。

      • ERROR() 遇到错误
      • BREAK() 外部程序执行了uuid_break
      • HANGUP() 挂机了,如果用户说完就挂机了,识别结果会HANGUP(F说话内容)推送。
    • 结束原因

      • send_bye 系统挂机
      • recv_bye 对方挂机
      • hangup 未知方挂机
      • transfer 转接
      • limit 授权限制
      • manual() 转人工
    • 切换流程

      • 空或者return 切换到上一个流程
      • top 切换到主流程
      • 切换到指定返回流程ID
    • 通知参数

      • {
        "trigger_type": "calculate",
        "trigger_time":10,
        "url":""
        "linegroup": "121",
        "stop_robot": false,
        "beep_time": 0,
        "rest_time": 0
        }
- trigger_type 触发通知类型

    - calculate 根据意向配置计算触发
    - kb 知识库配置触发
    - flow 节点配置触发

- trigger_time 机器人对话多久后触发

- url 通知到URL时是http地址

- linegroup 通知到坐席组时是坐席组名

- stop_robot   true对话模式,false监听模式

- beep_time 坐席beep时间

- rest_time  坐席话后休息时间
  • input_nlp_args nlp 接口返回的数据

  • input_start_time 输入开始时间,比如说话开始时的时间

  • input_duration 输入持续时间 ,比如说话的持续时间

  • input_play_time 输入时的放音时间,

    正数 说明抢话了,input_play_time -input_duration 就是放音多少秒的时候用户开始说话的。

    负数 就是放音完成之后多少秒,用户才开始说法的。

  • matching_method 匹配方法0:mismatch 1:boot 2:regex 3:full 4:any 5:flowid

    • mismatch 未匹配到条件
    • boot 创建流程时从start进入第一个引导结点(开场白)
    • regex 正则表达式匹配
    • full 完整的关键词匹配
    • any 任意匹配(就是关键词设置为any)
    • flowid 匹配到流程ID
  • matching_condition 匹配表达式 ,就是被匹配成功的关键词,或者正则表达式

  • condition_id 匹配条件ID ,话术版本2加入

  • condition_weight 匹配条件权重,话术版本3加入

  • matching_keyword 匹配关键词,就是text中被匹配中的部分

  • response_type 响应类型 0:none 1:flow 2:kb 3:mismatch 4:switchflow 5:timeout 6:globalflow 7:brotherflow 8:noiserule 9:disablebreak

    • none 没反应动作
    • flow 匹配到子流程
    • kb 匹配到知识库
    • mismatch 执行未匹配放音
    • switchflow 切换流程节点
    • timeout 执行无输入放音
    • globalflow 匹配到全局流程
    • brotherflow 匹配到源流程的子流程
    • noiserule 匹配到噪音规则
    • disablebreak 匹配到禁止打断。
  • response_id 响应的FlowID,或者PromptID

  • response_action 响应动作,执行那个FS的APP

  • response_args 响应参数,APP的参数

  • response_text 响应文本,话术中添加一个 playbacks_text:[“放音描述”],重复放音replaybacks_text:[“重复放音内容”]其他类似,就可以记录到每次放音的文本内容。

  • repetition kb:prompt重复播放次数 ,timeout和mismatch:连续未匹配次数 flow:已经执行次数

  • potential 意向信息

  • record 当前输入的录音文件,text输入的时候才有,一个动作(一次放音)的多次说话会记录到一个录音文件。

例子

执行流程

{
"createtime": "2024-10-17 16:39:48",
"callid": "dfd3585d-1209-4c69-bb5f-777a48a66321",
"current_appid": "",
"sequence": 0,
"current_flowid": "Start",
"input_type": 10,
"input_args": "debug/905ee60c2703a80d318ed17b7eeee75d",
"input_nlp_args": "",
"input_start_time": "2024-10-17 16:39:48",
"input_duration": 0,
"matching_method": 1,
"matching_condition": "",
"condition_id": "",
"condition_weight": 0,
"matching_keyword": "",
"response_type": 1, //1表示执行流程
"response_description": "是否有贷款意向", //流程名称
"response_id": "F1",
"response_action": "cti_play_and_detect_speech", //放音
"response_text": "你好,这里是信贷中心,请问你最近是否有资金上的需求?", //放音内容
"repetition": 0,
"potential": "", //流程意向 1:有意向 -1:无意向 A-F:意向标签
"record": "",
}

用户回答

{
"createtime": "2024-10-17 16:44:49",
"callid": "65b53f05-a2c8-4fb4-a141-a7eccdad516e",
"current_appid": "28515905-47c1-41d7-a7bc-1aa8395694fc",
"sequence": 2,
"current_flowid": "F1",
"input_type": 0, //0表示本次为ASR识别结果通知
"input_args": "F有的。", //ASR识别结果内容,前缀F表示一句话, 显示的时候去除前缀,去除的方法去除第一个字符,如果第一个字符是P,则去前2个字符。
"input_nlp_args": "",
"input_start_time": "2024-10-17 16:44:48", //说话开始时间
"input_duration": 1439, //说话持续多少毫秒
"matching_method": 3, //匹配方法 2:正则 3:字符串匹配 4:兜底
"matching_condition": "",
"condition_id": "test1",
"condition_weight": 1, //匹配到的关键词的权重 1:积极回答 -1:消极回答 0:中性
"matching_keyword": "有", //匹配到的关键词
"response_type": 1, //1 表示匹配到了子流程
"response_description": "需要多少资金",
"response_id": "F4",
"response_action": "cti_play_and_detect_speech",
"response_text": "请问你需要多少资金呢?",
"repetition": 1,
"potential": "1",
}

触发知识库

{
"createtime": "2024-10-17 17:03:15",
"callid": "acb3fb63-66e7-4e1f-8c9d-89ebfa33d710",
"current_appid": "7c2cbf39-15ad-45aa-9c8f-90ad43fcee8a",
"sequence": 1,
"current_flowid": "F1",
"input_type": 0,
"input_args": "F公司。",
"input_nlp_args": "",
"input_start_time": "2024-10-17 17:03:13",
"input_duration": 1581,
"matching_method": 3,
"matching_condition": "",
"condition_id": "",
"condition_weight": 0,
"matching_keyword": "公司",
"response_type": 2, //2 表示 匹配到了知识库
"response_description": "公司介绍", //知识库节点名字
"response_id": "P1",
"response_action": "cti_play_and_detect_speech",
"response_text": "我们是正规贷款公司,专业提供金融服务的。", //知识库放音内容
"repetition": 1,
"potential": "7", //知识库意向 1:有意向 -1:无意向 A-F:意向标签
}

切换流程

{
"createtime": "2024-10-17 17:08:14",
"callid": "116ac20b-f3af-485a-bf95-8b3dd01f944a",
"current_appid": "957c5e70-0153-4e1d-9eae-4ae808bcd016",
"sequence": 1,
"current_flowid": "F1",
"input_type": 0,
"input_args": "F听不清。",
"input_nlp_args": "",
"input_start_time": "2024-10-17 17:08:12",
"input_duration": 2220,
"matching_method": 3,
"matching_condition": "",
"condition_id": "",
"condition_weight": 0,
"matching_keyword": "听不清",
"response_type": 6, //6表示匹配到了全局流程
"response_description": "返回流程重复执行",
"response_id": "F33",
"response_action": "return", //表示执行返回动作
"response_args": "", //返回到哪里 top 主流程 空或者return 上一个流程 其他值指定流程
"response_text": "好的,我重新说一下了。",
"repetition": 1,
"potential": "",
}
{
"createtime": "2024-10-17 17:47:07",
"callid": "767cbfdf-48d8-4544-a05b-b67e7980a0d7",
"current_appid": "4aad1709-641d-4b5c-a746-c4c8eadb2686",
"sequence": 2,
"current_flowid": "F33",
"input_type": 20,
"input_args": "",
"input_nlp_args": "",
"input_start_time": "2024-10-17 17:47:07",
"input_duration": 0,
"matching_method": 5,
"matching_condition": "",
"condition_id": "",
"condition_weight": 0,
"matching_keyword": "",
"response_type": 4,
"response_description": "是否有贷款意向",
"response_id": "F1",
"response_action": "cti_play_and_detect_speech",
"response_text": "好的,我重新说一下了。 请问你最近是否有资金上的需求吗?",
"repetition": 2,
"potential": "",
}

挂机

{
"createtime": "2024-10-17 17:14:48",
"callid": "3b5d2384-aa4b-4165-a8e6-b36626f5090c",
"current_appid": "1b805dbd-44ae-4e5e-9ad8-677d98df67c7",
"sequence": 2,
"current_flowid": "F2",
"input_type": 2, //
"input_args": "DONE()", //动作执行完成
"input_nlp_args": "",
"input_start_time": "2024-10-17 17:14:48",
"input_duration": 0,
"matching_method": 4,
"matching_condition": "",
"condition_id": "",
"condition_weight": 0,
"matching_keyword": "",
"response_type": 1,
"response_description": "",
"response_id": "F3",
"response_action": "hangup", // 执行挂机
"response_args": "",
"response_text": "",
"repetition": 1,
"potential": "",
"record": "",
}

对话结束

{
"createtime": "2024-10-17 17:14:48",
"callid": "3b5d2384-aa4b-4165-a8e6-b36626f5090c",
"current_appid": "d5f16661-fca7-4e3a-baf8-30dacd2eca60",
"sequence": 3,
"current_flowid": "F3",
"input_type": 11, //11表示 对话结束
"input_args": "send_bye", //表示挂机方 前缀send 系统挂机,前缀recv,手机挂机
"input_nlp_args": "",
"input_start_time": "2024-10-17 17:14:48",
"input_duration": 0,
"matching_method": 0,
"matching_condition": "",
"condition_id": "",
"condition_weight": 0,
"matching_keyword": "",
"response_type": 0,
"response_description": "",
"response_id": "",
"response_action": "",
"response_args": "",
"response_text": "",
"repetition": 0,
"potential": "b",
"record": "",
}
  • input_args 结束原因
    • send_bye 系统挂机
    • recv_bye 对方挂机
    • hangup 未知方挂机
    • transfer 转接
    • limit 授权限制
    • manual 转人工

根据CDR配置,流程执行步骤可以记录到数据库或者redis

如果配置为记录到数据库,input_type 等于DESTORY是 即流程执行结束,可以通知到http接口或者redis的list或者channel。

{
"robot": {
/*机器人对话的执行流程记录*/
"record": {
通知包含的通道变量
"notify_fields": [ "caller_id_name", "destination_number", "call_source", "source_name", "cti_dial_number" ],
/*机器人交换记录是否推送到redis的channel和list*/
"redis": {
"channel": "",
"list": "",
},
"database": {
/*机器人的交换记录插入数据库的那个表*/
"table": "conversation",
},
"log": false //是否输出到redis的JSON和输出SQL。
},
/*机器人对话交互的统计数据*/
"statistic":
{
/*是否推送到redis的channel和list*/
"redis": {
"channel": "",
"list": ""
},
"database": {
/*插入数据库的那个表*/
"table":"classify"
},
"log": false //是否输出到redis的JSON和SQL到日志。
},
"nlp": {
"debug": false //是否输出机器人引擎调试日志,比如要输出正则表达式匹配过程,可以设置为true
},
"httpflow": {
"usecurl": false, //默认使用顶顶通实现的http库,修改成true,使用curl库执行http请求
"retries": 2, //http请求失败时重试次数
"connecttimeout": 3000, //连接超时
"responsetimeout": 10000 //等待响应超时
},
"event_after_hangup":true // 挂断之后是否继续处理事件,如果不开启 用户说话之后没等ASR识别完成就挂机,会丢失识别结果,开启后会有complete事件参数HANGUP(F说话内容)。
}
}

机器人对话交互的统计数据

用于意向分析和比如客户分类

CREATE TABLE `classify` (
`callid` VARCHAR(50) NOT NULL,
`talk_time` INT(11) NULL DEFAULT NULL,
`respond_count` INT(11) NULL DEFAULT NULL,
`positive_respond_count` INT(11) NULL DEFAULT NULL,
`passive_respond_count` INT(11) NULL DEFAULT NULL,
`intentional_count` INT(11) NULL DEFAULT NULL,
`unintentional_count` INT(11) NULL DEFAULT NULL,
`trigger_kb` INT(11) NULL DEFAULT NULL,
`trigger_global_flow` INT(11) NULL DEFAULT NULL,
`proactively_hangup` INT(11) NULL DEFAULT NULL,
`label_result` VARCHAR(50) NULL DEFAULT NULL,
`label_hit_id` VARCHAR(50) NULL DEFAULT NULL,
`label_hit_type` INT(11) NULL DEFAULT NULL,
PRIMARY KEY (`callid`)
)
  • talk_time 通话时长
  • respond_count 回答次数
  • positive_respond_count 积极回答(对所以命中关键词权重大于0的进行求和)。举例:比如肯定关键词权重都设置1,那么积极回答的值就是肯定回答了多少次。
  • passive_respond_count 消极回答(对所有命中关键词权重小于0的进行求和然后取绝对值)。举例:比如否定关键词权重都设置-1,那么消极回答的值就是否定回答了多少次。
  • intentional_count 有意向节点(对所有执行节点意向大于0的进行求和)。举例:比如有意向的节点意向都设置1,那么这个值就是执行了多少个有意向的节点。
  • unintentional_count 无意向节点(对所有执行节点意向小于0的进行求和然后取绝对值)。举例:比如无意向的节点意向都设置-1,那么这个值就是执行了多少个无意向的节点。
  • trigger_kb 触发知识库次数
  • trigger_global_flow 触发全局流程次数
  • proactively_hangup 机器人主动挂断设置为1,否则设置为0
  • label_result 分类结果
  • label_hit_type 分类结果的类型
    1. 流程直接设置的分类(label_hit_id为设置分类的的流程ID)
    2. 知识库直接设置的分类(label_hit_id为设置分类的知识库ID)
    3. 根据配置规则分类(label_hit_id为命中的分配配置规则ID)

NLP接口

全局配置设置了NLP接口地址,并且节点配置了FLOWID,那么会调用NLP接口进行处理。

NLP接口原理,话术引擎把输入的数据和需要匹配的关键词发送给NLP接口,由NLP接口返回匹配命中的关键词。

请求参数

{
"flowid": "F1",
"nlpid": "1",
"callid": "58b0733b-8a80-4fdc-860b-ad7e5bb85fbe",
"flowkeywords": "o%7Chello%7Cok%7Cyes%7Cno%7Cwo%7Cxuhuaiyi",
"kbkeywords": "lixi%7Cgongs%7Cnali%7Chello%7Cok%7Cyes%7Cno",
"input": "text",
"text": "SHello%20hello"
}
  • flowkeywords 所有子流程的所有关键词

  • kbkeywords 关联知识库的所有关键词

  • input 输入类型

  • text 输入参数

NLP接口返回数据

{
"keyword":"输入结果匹配到的关键词",
"description":“描述”
}

话术编辑

请看这个页面 http://www.ddrj.com/smartivr/robot.html ,用户可以设计自己的话术编辑界面,只需要按照话术脚本格式生成JSON文件就可以。

2个不同的匹配条件进入同一个流程的实现方法

可以在流程名字名字前面加上冒号区分不同条件进入同一个流程。注意:需要json添加一个version:2。

{
"version":2,
"flow": {
"F1": {
"action":"cti_play_and_detect_speech",
"subflow": {
"肯定:F3": {
"id":"匹配条件ID",
"condition": {
"text": [
"是"
],
}
},
"默认:F3": {
"id":"匹配条件ID",
"condition": {
"complete": [
"any"
],
}
}
}
}
}

话术脚本

{
"flow": {
/*节点ID*/
"F1": {
/*节点执行的动作*/
"action": "cti_play_and_detect_speech",
/*动作参数*/
"argument": "'1' '' '' '0' '' '' '' '' '' '' ''",
/*节点位置信息*/
"position": {
"x": 2499,
"y": 156
},
/*nlp ID*/
"nlpid": "",
/*节点描述*/
"description": "描述",
/*节点放音文件列表*/
"playbacks": [
"测试声音"
],
/*子节点信息*/
"subflow": {
/*子节点ID*/
"F3": {
/*进入字节点的条件*/
"condition": {
"matching_id":"匹配条件ID",
/*ASR识别到关键词*/
"text": [
"any"
],
/*动作执行完成*/
"complete": [
"any"
],
/*DTMF输入按键*/
"dtmf": [
"any"
]
}
}
},
/*节点重复执行是放音,用来替换playbacks配置*/
"replaybacks": [],
"filter": {
"text": "S",
"dtmf": "none"
},
/*知识库返回时放音*/
"kbplaybacks": [
"测试声音"
],
/*未匹配到关键词时放音*/
"mismatchplaybacks": [
"不好意思,我没听清!"
],
/*未匹配到关键词放音次数*/
"mismatchrepetition": "2",
/*关联的知识库ID*/
"kb": "C1",
/*节点最大重复进入次数*/
"repetition": "",
/*节点的意向信息*/
"potential": ""
}
}
}

知识库

{
"kb": {
/*分类ID*/
"C1": {
/*分类名字*/
"name": "常见问题回答",
/*分类下面的条目*/
"prompts": [
"P1"
],
"description": ""
}
},
"prompt": {
/*条目ID*/
"P1": {
/*条目名字*/
"name": "公司介绍",
"ref": 2,
/*最大重复执行次数*/
"repetition": "2",
/*进入知识库的关键词*/
"keyworks": [
"谁",
"哪里",
"公司"
],
/*进入后的放音文件*/
"playbacks": [
"放音测试"
],
/*意向等级*/
"potential": "7",
/*切换到流程 可以配置流程ID,或者当前流程的匹配关键词,"text:"前缀匹配子流程的文本输入,"DTMF:"前缀匹配子流程的DTMF输入,"complete:"前缀匹配子流程的完成输入*/
"switchflow":"",
"description": ""
}
}
}

同义词

{
"synonym": {
/*分类*/
"肯定词": [/*同义词列表*/
"是",
"好",
"要",
"没错",
"有",
"对"
],
"否定词": [
"不",
"没"
]
}
}

全局配置

/*配置tts和asr默认配置*/
"global": {
"voicelist": [],
"defaultvoice": "",
"voicedir": "",
"ttsurl": "http:\/\/180.76.224.191:9989\/tts",
"ttsengine": "",
"ttsconfig": "",
"ttsvolume": 0,
"ttsspeechrate": 0,
"ttspitchrate": 0,
"interrupt": "2",
"asrproxy_addr": "180.76.224.191:9988",
"vad_min_active_time_ms": "150",
"vad_max_end_silence_time_ms": "800",
"wait_speech_timeout_ms": "5000",
"max_speech_time_ms": "20000",
"hot_word": "",
"asr_params": "{\"group\":\"default\"}",
"nlpurl": "",
"vad": "0",
"vad_mode": "0",
"vad_filter": "0.3"
},

tts接口

等待完成

话术流程存入redis

fs启动的时候会自动同步cti_robot_flow和cti_robot_flow@domain 2个哈希表里的话术流程,到fs话术目录,然后自动加载。

cti_robot_flow和cti_robot_flow@domain的区别,cti_robot_flow@domain指定的domain的fs才加载,cti_robot_flow连接这个redis的所有fs都会加载,用于群集模式。

  • key 流程名称
  • value 流程的json内容

cti_robot_flow改变通知

cti_robot_flow改变PUBLISH 通知到config@all [通道] ,cti_robot_flow@domain改变PUBLISH 通知到config@domain[通道],先修改hash表内容,然后推送通知,fs收到通知会自动同步话术脚本到本地,然后加载。

{
"type":"config_change",
"table":"cti_robot_flow",
"key":"t1"
}