1
0
mirror of https://github.com/chatopera/cosin.git synced 2025-08-01 16:38:02 +08:00

Revert "2020年10月14日"

This reverts commit 3d7b2f8f6e65fa1ce6a4012df06ba63cc4e15284.
This commit is contained in:
苗圃 2020-10-14 17:13:22 +08:00
parent 3d7b2f8f6e
commit 9dcab79ec5
143 changed files with 114 additions and 5048 deletions

View File

@ -1,165 +0,0 @@
# RASA中文聊天机器人项目
---
**RASA 开发中文指南系列博文:**
- [Rasa中文聊天机器人开发指南(1):入门篇](https://jiangdg.blog.csdn.net/article/details/104328946)
- [Rasa中文聊天机器人开发指南(2)NLU篇](https://jiangdg.blog.csdn.net/article/details/104530994)
- [Rasa中文聊天机器人开发指南(3)Core篇](https://jiangdg.blog.csdn.net/article/details/105434136)
- Rasa中文聊天机器人开发指南(4)RasaX篇
- Rasa中文聊天机器人开发指南(5)Action篇
**注:本系列博客翻译自[Rasa官方文档](https://rasa.com/docs/rasa/)并融合了自己的理解和项目实战同时对文档中涉及到的技术点进行了一定程度的扩展目的是为了更好的理解Rasa工作机制。与本系列博文配套的项目GitHub地址[ChitChatAssistant](https://github.com/jiangdongguo/ChitChatAssistant),欢迎`star``issues`,我们共同讨论、学习!**
---
# 1. 安装rasa
## 1.1 环境要求
- python 3.6 +
- mitie
- jieba
## 1.2 安装步骤
**1. 安装rasa**
```shell
# 当前版本为1.9.5
# 该命令运行时间较长,会安装完所有的依赖
pip --default-timeout=500 install -U rasa
```
**2. 安装mitie**
```shell
# 在线安装Mitie
pip install git+https://github.com/mit-nlp/MITIE.git
pip install rasa[mitie] # 注:由于第一步始终没成功过,没尝试过这个命令的意义
```
 由于自己在线安装尝试了很多次都拉不下来,因此只能走离线安装的方式,有三个步骤:
- 首先,下载[MITIE源码](https://github.com/mit-nlp/MITIE)和中文词向量模型[total_word_feature_extractor_zh.dat(密码p4vx)](https://pan.baidu.com/s/1kNENvlHLYWZIddmtWJ7Pdg)这里需要将该模型拷贝到创建的python项目data目录下(可任意位置)后面训练NLU模型时用到
- 其次,安装[Visual Studio 2017](https://blog.csdn.net/qq_42276781/article/details/88594870) ,需要勾选“`用于 CMake 的 Visual C++ 工具`因为编译MITIE源码需要Cmake和Visual C++环境。安装完毕后,将`C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin`添加到环境变量中,再重启电脑使之生效;
- 从Pycharm的命令终端进行Mitie源码根目录执行下面的命令
> python setup.py build
> python setup.py install
**3. 安装jieba**
```shell
# 安装Jieba中文分词
pip install jieba
```
# 2. 训练模型
 当所有样本和配置文件准备好后接下来就是训练模型了打开命令终端执行下面的命令该命令会同时训练NLU和Core模型。
- 使用MITIE
```shell
python -m rasa train --config configs/config.yml --domain configs/domain.yml --data data/
```
- 使用Supervised_Embedding
```bash
python -m rasa train --config configs/zh_jieba_supervised_embeddings_config.yml --domain configs/domain.yml --data data/
```
- 使用MITIE+Supervised_Embedding
```bash
python -m rasa train --config configs/zh_jieba_mitie_embeddings_config.yml --domain configs/domain.yml --data data/
```
# 3. 运行服务
**1启动Rasa服务**
 在命令终端,输入下面命令:
```shell
# 启动rasa服务
# 该服务实现自然语言理解(NLU)和对话管理(Core)功能
# 注:该服务的--port默认为5005如果使用默认则可以省略
python -m rasa run --port 5005 --endpoints configs/endpoints.yml --credentials configs/credentials.yml --debug
```
**2启动Action服务**
在命令终端,输入下面命令:
```shell
# 启动action服务
# 注:该服务的--port默认为5055如果使用默认则可以省略
Python -m rasa run actions --port 5055 --actions actions --debug
```
**3启动server.py服务**
```shell
python server.py
```
当**Rasa Server**、**Action Server**和**Server.py**运行后,在浏览器输入测试:
` http://127.0.0.1:8088/ai?content=查询广州明天的天气`
终端调用效果为:
![](https://img-blog.csdnimg.cn/20200227153932228.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0FuZHJFeHBlcnQ=,size_16,color_FFFFFF,t_70)
# 4. 更新日志
**1V1.0.2020.02.15**
- 创建项目,模型训练成功;
- 前端访问Rasa服务器正常响应
- 对接图灵闲聊机器人、心知天气API便于测试
**2V1.1.2020.02.27**
- 优化NLU样本尝试使用同义词、正则、查找表
- 改进supervised_embeddings实体提取和意图识别明显提高训练速度加快很多
- 完成`Rasa中文聊天机器人开发指南(2)NLU篇`文章撰写;
**3V1.2.2020.04.10**
- 使用Interactive Learning构建样本
- 新增MITIE+supervised_embeddings管道并训练相应的模型
- 新增身份查询案例;
- 将Rasa版本升级到1.9.5解决win10使用tensorflow出现的异常(详见`入门篇`)
- 完成`Rasa中文聊天机器人开发指南(3)Core篇`文章撰写;
# 5. License
> ```
> Copyright 2020 Jiangdongguo
>
> Licensed under the Apache License, Version 2.0 (the "License");
> you may not use this file except in compliance with the License.
> You may obtain a copy of the License at
>
> http://www.apache.org/licenses/LICENSE-2.0
>
> Unless required by applicable law or agreed to in writing, software
> distributed under the License is distributed on an "AS IS" BASIS,
> WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> See the License for the specific language governing permissions and
> limitations under the License.
> ```

View File

@ -1,59 +0,0 @@
# 访问图灵机器人openapi
# -*- coding: utf-8 -*-
"""
ChatApis.py
~~~~~~~~~
图灵机器人(公司)闲聊系统API对接
免费版只限每天调用100次需联外网
:date: 2020-02-10 15:56:00
:author: by jiangdg
"""
import requests
import json
def get_response(msg):
"""
访问图灵机器人openApi
:param msg 用户输入的文本消息
:return string or None
"""
apiurl = "http://openapi.tuling123.com/openapi/api/v2"
# 构造请求参数实体
params = {"reqType": 0,
"perception": {
"inputText": {
"text": msg
}
},
"userInfo": {
"apiKey": "ca7bf19ac0e644c38cfbe9d6fdc08de1",
"userId": "439608"
}}
# 将表单转换为json格式
content = json.dumps(params)
# 发起post请求
r = requests.post(url=apiurl, data=content, verify=False).json()
print("r = " + str(r))
# 解析json响应结果
# {'emotion':{
# 'robotEmotion': {'a': 0, 'd': 0, 'emotionId': 0, 'p': 0},
# 'userEmotion': {'a': 0, 'd': 0, 'emotionId': 10300, 'p': 0}
# },
# 'intent': {
# 'actionName': '',
# 'code': 10004,
# 'intentName': ''
# },
# 'results': [{'groupType': 1, 'resultType': 'text', 'values': {'text': '欢迎来到本机器人的地盘。'}}]}
code = r['intent']['code']
if code == 10004 or code == 10008:
message = r['results'][0]['values']['text']
return message
return None

View File

@ -1,54 +0,0 @@
# 访问openapi
# -*- coding: utf-8 -*-
"""
WeatherApis.py
~~~~~~~~~
使用心知天气数据查询天气
:date: 2020-02-10 15:56:00
:author: by jiangdg
"""
import requests
import json
KEY = 'rmhrne8hal69uwyv' # API key(私钥)
UID = "" # 用户ID, TODO: 当前并没有使用这个值,签名验证方式将使用到这个值
LOCATION = 'beijing' # 所查询的位置可以使用城市拼音、v3 ID、经纬度等
API = 'https://api.seniverse.com/v3/weather/daily.json' # API URL可替换为其他 URL
UNIT = 'c' # 单位
LANGUAGE = 'zh-Hans' # 查询结果的返回语言
def fetch_weather(location, start=0, days=15):
result = requests.get(API, params={
'key': KEY,
'location': location,
'language': LANGUAGE,
'unit': UNIT,
'start': start,
'days': days
}, timeout=2)
return result.json()
def get_weather_by_day(location, day=1):
result = fetch_weather(location)
normal_result = {
"location": result["results"][0]["location"],
"result": result["results"][0]["daily"][day]
}
return normal_result
if __name__ == '__main__':
default_location = "合肥"
result = fetch_weather(default_location)
print(json.dumps(result, ensure_ascii=False))
default_location = "合肥"
result = get_weather_by_day(default_location)
print(json.dumps(result, ensure_ascii=False))

View File

@ -1,171 +0,0 @@
from typing import Dict, Text, Any, List, Union
from rasa_sdk import Tracker, Action
from rasa_sdk.events import UserUtteranceReverted, Restarted, SlotSet
from rasa_sdk.executor import CollectingDispatcher
from rasa_sdk.forms import FormAction
import re
from actions import ChatApis
from actions.WeatherApis import get_weather_by_day
from requests import (
ConnectionError,
HTTPError,
TooManyRedirects,
Timeout
)
class NumberForm(FormAction):
"""Example of a custom form action"""
def name(self) -> Text:
"""Unique identifier of the form"""
return "number_form"
@staticmethod
def required_slots(tracker: Tracker) -> List[Text]:
"""A list of required slots that the form has to fill"""
return ["type", "number", "business"]
def slot_mappings(self) -> Dict[Text, Union[Dict, List[Dict]]]:
"""A dictionary to map required slots to
- an extracted entity
- intent: value pairs
- a whole message
or a list of them, where a first match will be picked"""
return {
"type": self.from_entity(entity="type", not_intent="chitchat"),
"number": self.from_entity(entity="number", not_intent="chitchat"),
"business": [
self.from_entity(
entity="business", intent=["inform", "request_number"]
),
self.from_entity(entity="business"),
],
}
def submit(
self,
dispatcher: CollectingDispatcher,
tracker: Tracker,
domain: Dict[Text, Any],
) -> List[Dict]:
"""Define what the form has to do
after all required slots are filled"""
number_type = tracker.get_slot('type')
number = tracker.get_slot('number')
business = tracker.get_slot('business')
if not business:
dispatcher.utter_message(text="您要查询的{}{}所属人为张三,湖南长沙人,现在就职于地球村物业管理有限公司。".format(number_type, number))
return []
dispatcher.utter_message(text="你要查询{}{}{}balabalabalabalabala。".format(number_type, number, business))
return [SlotSet("business", None)]
class WeatherForm(FormAction):
def name(self) -> Text:
"""Unique identifier of the form"""
return "weather_form"
@staticmethod
def required_slots(tracker: Tracker) -> List[Text]:
"""A list of required slots that the form has to fill"""
return ["date_time", "address"]
def submit(
self,
dispatcher: CollectingDispatcher,
tracker: Tracker,
domain: Dict[Text, Any],
) -> List[Dict]:
"""Define what the form has to do
after all required slots are filled"""
address = tracker.get_slot('address')
date_time = tracker.get_slot('date_time')
date_time_number = text_date_to_number_date(date_time)
if isinstance(date_time_number, str): # parse date_time failed
dispatcher.utter_message("暂不支持查询 {} 的天气".format([address, date_time_number]))
else:
weather_data = get_text_weather_date(address, date_time, date_time_number)
dispatcher.utter_message(weather_data)
return []
def get_text_weather_date(address, date_time, date_time_number):
try:
result = get_weather_by_day(address, date_time_number)
except (ConnectionError, HTTPError, TooManyRedirects, Timeout) as e:
text_message = "{}".format(e)
else:
text_message_tpl = """
{} {} ({}) 的天气情况为白天{}夜晚{}气温{}-{} °C
"""
text_message = text_message_tpl.format(
result['location']['name'],
date_time,
result['result']['date'],
result['result']['text_day'],
result['result']['text_night'],
result['result']["high"],
result['result']["low"],
)
return text_message
def text_date_to_number_date(text_date):
if text_date == "今天":
return 0
if text_date == "明天":
return 1
if text_date == "后天":
return 2
# Not supported by weather API provider freely
if text_date == "大后天":
# return 3
return text_date
if text_date.startswith("星期"):
# TODO: using calender to compute relative date
return text_date
if text_date.startswith("下星期"):
# TODO: using calender to compute relative date
return text_date
# follow APIs are not supported by weather API provider freely
if text_date == "昨天":
return text_date
if text_date == "前天":
return text_date
if text_date == "大前天":
return text_date
class ActionDefaultFallback(Action):
"""Executes the fallback action and goes back to the previous state
of the dialogue"""
def name(self):
return 'action_default_fallback'
def run(self, dispatcher, tracker, domain):
# 访问图灵机器人API(闲聊)
text = tracker.latest_message.get('text')
message = ChatApis.get_response(text)
if message is not None:
dispatcher.utter_message(message)
else:
dispatcher.utter_template('utter_default', tracker, silent_fail=True)
return [UserUtteranceReverted()]

View File

@ -1,22 +0,0 @@
language: "zh"
pipeline:
- name: "MitieNLP"
model: "data/total_word_feature_extractor_zh.dat"
- name: "JiebaTokenizer"
dictionary_path: "data/dict"
- name: "MitieEntityExtractor"
- name: "EntitySynonymMapper"
- name: "RegexFeaturizer"
- name: "MitieFeaturizer"
- name: "SklearnIntentClassifier"
policies:
- name: KerasPolicy
epochs: 500
max_history: 5
- name: FallbackPolicy
fallback_action_name: 'action_default_fallback'
- name: MemoizationPolicy
max_history: 5
- name: FormPolicy

View File

@ -1,29 +0,0 @@
# This file contains the credentials for the voice & chat platforms
# which your bot is using.
# https://rasa.com/docs/rasa/user-guide/messaging-and-voice-channels/
rest:
# # you don't need to provide anything here - this channel doesn't
# # require any credentials
#facebook:
# verify: "<verify>"
# secret: "<your secret>"
# page-access-token: "<your page access token>"
#slack:
# slack_token: "<your slack token>"
# slack_channel: "<the slack channel>"
#socketio:
# user_message_evt: <event name for user message>
# bot_message_evt: <event name for but messages>
# session_persistence: <true/false>
#mattermost:
# url: "https://<mattermost instance>/api/v4"
# team: "<mattermost team>"
# user: "<bot username>"
# pw: "<bot token>"
# webhook_url: "<callback URL>"

View File

@ -1,130 +0,0 @@
intents:
- affirm
- deny
- greet
- goodbye
- thanks
- whoareyou
- whattodo
- request_weather
- request_number
- inform
- inform_business
- stop
- chitchat
session_config:
carry_over_slots_to_new_session: true
session_expiration_time: 60
slots:
date_time:
type: unfeaturized
auto_fill: false
address:
type: unfeaturized
auto_fill: false
type:
type: unfeaturized
auto_fill: false
number:
type: unfeaturized
auto_fill: false
business:
type: unfeaturized
auto_fill: false
entities:
- date_time
- address
- type
- number
- business
actions:
- utter_answer_affirm
- utter_answer_deny
- utter_answer_greet
- utter_answer_goodbye
- utter_answer_thanks
- utter_answer_whoareyou
- utter_answer_whattodo
- utter_ask_date_time
- utter_ask_address
- utter_ask_number
- utter_ask_business
- utter_ask_type
- action_default_fallback
forms:
- weather_form
- number_form
responses:
utter_answer_affirm:
- text: "嗯嗯,好的!"
- text: "嗯嗯,很开心能够帮您解决问题~"
- text: "嗯嗯,还需要什么我能够帮助您的呢?"
utter_answer_greet:
- text: "您好!请问我可以帮到您吗?"
- text: "您好!很高兴为您服务。请说出您要查询的功能?"
utter_answer_goodbye:
- text: "再见"
- text: "拜拜"
- text: "虽然我有万般舍不得,但是天下没有不散的宴席~祝您安好!"
- text: "期待下次再见!"
- text: "嗯嗯,下次需要时随时记得我哟~"
- text: "see you!"
utter_answer_deny:
- text: "主人,您不开心吗?不要离开我哦"
- text: "怎么了,主人?"
utter_answer_thanks:
- text: "嗯呢。不用客气~"
- text: "这是我应该做的,主人~"
- text: "嗯嗯,合作愉快!"
utter_answer_whoareyou:
- text: "您好我是小蒋呀您的AI智能助理"
utter_answer_whattodo:
- text: "您好!很高兴为您服务,我目前只支持查询天气哦。"
utter_ask_date_time:
- text: "请问您要查询哪一天的天气?"
utter_ask_address:
- text: "请问您要查下哪里的天气?"
utter_ask_number:
- text: "请问您要查的{type}号码是多少?"
utter_ask_business:
- text: "请问您要查询什么业务呢?"
utter_default:
- text: "没听懂,请换种说法吧~"
utter_ask_continue:
- text: "请问您还要继续吗?"
utter_noworries:
- text: "不用客气 :)"
- text: "没事啦"
- text: "不客气哈,都是老朋友了 :)"
utter_wrong_business:
- text: "当前还不支持{business}业务,请重新输入。"
utter_wrong_type:
- text: "当前还不支持查询{type}。"
utter_wrong_number:
- text: "您输入的{number}有误,请重新输入。"
utter_chitchat:
- text: "呃呃呃呃呃"
- text: "您这是在尬聊吗?"

View File

@ -1,42 +0,0 @@
# This file contains the different endpoints your bot can use.
# Server where the models are pulled from.
# https://rasa.com/docs/rasa/user-guide/running-the-server/#fetching-models-from-a-server/
#models:
# url: http://my-server.com/models/default_core@latest
# wait_time_between_pulls: 10 # [optional](default: 100)
# Server which runs your custom actions.
# https://rasa.com/docs/rasa/core/actions/#custom-actions/
action_endpoint:
url: "http://localhost:5055/webhook"
# Tracker store which is used to store the conversations.
# By default the conversations are stored in memory.
# https://rasa.com/docs/rasa/api/tracker-stores/
#tracker_store:
# type: redis
# url: <host of the redis instance, e.g. localhost>
# port: <port of your redis instance, usually 6379>
# db: <number of your database within redis, e.g. 0>
# password: <password used for authentication>
# use_ssl: <whether or not the communication is encrypted, default false>
#tracker_store:
# type: mongod
# url: <url to your mongo instance, e.g. mongodb://localhost:27017>
# db: <name of the db within your mongo instance, e.g. rasa>
# username: <username used for authentication>
# password: <password used for authentication>
# Event broker which all conversation events should be streamed to.
# https://rasa.com/docs/rasa/api/event-brokers/
#event_broker:
# url: localhost
# username: username
# password: password
# queue: queue

View File

@ -1,25 +0,0 @@
language: "zh"
pipeline:
- name: "MitieNLP"
model: "data/total_word_feature_extractor_zh.dat"
- name: "JiebaTokenizer"
dictionary_path: "data/dict"
- name: "MitieEntityExtractor"
- name: "EntitySynonymMapper"
- name: "RegexFeaturizer"
- name: "MitieFeaturizer"
- name: "EmbeddingIntentClassifier"
policies:
- name: FallbackPolicy
nlu_threshold: 0.5
ambiguity_threshold: 0.1
core_threshold: 0.5
fallback_action_name: 'action_default_fallback'
- name: MemoizationPolicy
max_history: 5
- name: FormPolicy
- name: MappingPolicy
- name: EmbeddingPolicy
epochs: 500

View File

@ -1,24 +0,0 @@
language: "zh"
pipeline:
- name: "JiebaTokenizer"
dictionary_path: "data/dict"
- name: "RegexFeaturizer"
- name: "CRFEntityExtractor"
- name: "EntitySynonymMapper"
- name: "CountVectorsFeaturizer"
- name: "CountVectorsFeaturizer"
analyzer: "char_wb"
min_ngram: 1
max_ngram: 4
- name: "EmbeddingIntentClassifier"
policies:
- name: EmbeddingPolicy
epochs: 100
max_history: 5
- name: FallbackPolicy
fallback_action_name: 'action_default_fallback'
- name: MemoizationPolicy
max_history: 5
- name: FormPolicy

View File

@ -1,3 +0,0 @@
电话号码 5 n
手机号 5 n
电话号 5 n

View File

@ -1,164 +0,0 @@
## intent:greet
- 你好
- 你好啊
- 早上好
- 晚上好
- hello
- hi
- 嗨
- 嗨喽
- 见到你很高兴
- 嘿
- 早
- 上午好
- hello哈喽
- 哈喽哈喽
- hello hello
- 喂喂
## intent:goodbye
- goodbye
- bye
- bye bye
- 88
- 886
- 再见
- 拜
- 拜拜
- 拜拜,下次再聊
- 下次见
- 回头见
- 下次再见
- 下次再聊
- 有空再聊
- 先这样吧
- 好了,就说这么多了
- 好了,先这样
- 没事
## intent:whoareyou
- 你是谁
- 我知道你吗
- 谁
- 我认识你吗
- 这是谁啊
- 是谁
- 请问你是谁
- 请问我认识你吗
- 你是哪位
- 你是?
- 是谁?
- 可以告诉我你的名字吗
- 你叫什么名字
## intent:whattodo
- 你支持什么功能
- 你有什么功能
- 你能干什么
- 你能做什么
## intent:thanks
- 谢谢
- thanks
- thank you
- 真的太感谢你了,帮了我大忙
- 谢谢你帮了我大忙
- 你帮了我大忙,谢谢你小智
- 非常感谢
- 谢了
## intent:deny
- 不了
- 算了
- 不用了
- 不需要
- 就这样吧
- 不
- no
- 不可以
- 不是的
- 不认同
- 否定
- 不是这样子的
- 我不同意你的观点
- 不同意
- 不好
- 你长得很美,就不要想得太美。
- 拒绝
- 不行
## intent:affirm
- 知道了
- 是的
- 当然
- 好的
- ok
- 嗯
- 可以
- 你可以这么做
- 你做得可以啊
- 同意
- 听起来不错
- 是这样的
- 的确是这样子的
- 我同意你的观点
- 对的
- 好滴
- 行
- 还行
- 当然可以
## intent:chitchat
- 你是不是傻
- 你喜欢靓仔靓女吗
- 能跟我说说你的男朋友吗
- 嘿,朋友,你好啊?
- 你是堆的
- 你今天过得开心吗
- 你没事吧
- 今天感觉怎么样
- 广州今天下雨了
- 我能够知道谁邀请你吗
- 请告诉我谁创造了你
- 你的老板是谁
- 我想知道谁发明了你
- 你是哪家公司的
- 你是谁发明的
- 你是什么
- 你还好吗
- 你现在在干什么
- 最近怎么样
- 你最近过得怎么样
- 谁是林俊杰
- 卢十瓦是不是疯了
- 你这个早上干什么了
- 外面真安静
- 现在的生活变得越来越好了
- 是不是下雨了
- 今天的天气很好,不是吗
- 外面好冷啊
- 你认识张天爱吗
- 现在的世界真乱,你说是不是
- 你今天看不起不错哟
- 你觉得华为手机怎么样
- 你知不知道新型冠形病毒
- 你现在在干什么
## intent:stop
- 你是不是傻
- 你就像个傻逼一样
- 真差劲,什么都不懂
- 真蠢
- 什么都查不到
- 你什么都不会
- 感觉你什么都不知道
- 你太蠢了
- 我不查了,太傻了
- 就这样吧
- 感觉你什么都不会
- 没有了
- 什么都没查到
- 我猜你是不是坏了

View File

@ -1,164 +0,0 @@
## intent:request_number
- 帮我查一个[电话号码](type)
- 帮我查询[手机号](type)
- 查询[手机号码](type)
- 查询[电话号码](type)
- [手机号](type)
- [电话号](type)
- 查一个[手机](type)
- [13548501905](number)
- 号码是[19820618425](number)
- 查一下[19862618425](number)
- 查下[19862618425](number)
- 我要查的是[19860612425](number)
- 查询的号码是[11160222425](number)
- 我想查的号码是[12260222425](number)
- 帮我查询[电话号码](type),号码是[19820618425](number)
- 帮我查一个号码[19862618425](number)
- [12260222425](number)这[手机号](type)
- 查询[电话](type)[19862618425](number)
- 查询[电话号码](type)[19860612425](number)
- [电话号码](type)为[19860218425](number)
- [电话号](type)为[12860618425](number)
- 查[电话](type)[19820618425](number)
- 我想知道[电话号码](type)为[19860612425](number)
- 我想查[电话号码](type)[19860618422](number)
- 我要查下[电话号](type)[19822618425](number)
- 你好!请帮我查询一下[电话](type)[12260618425](number)
- 查一下[手机号码](type)[19862228425](number)
- 帮我查个[电话](type)[19860612222](number)
- 请告诉我[电话号码](type)为[19860222425](number)
- 查[电话](type)[11160222425](number)
- 查[电话号码](type)[19800222425](number)
- 查[手机号码](type)[12260222425](number)
- 查询[手机](type)[12260222425](number)
- [手机号](type)[12260222425](number)
- [12260222425](number)这[手机号](type)
- 我想查[身份证](type)
- 我要查下[身份证](type)
- 你好!请帮我查询一下[身份证](type)
- 帮我查一个[身份证号码](type)
- 帮我查询[身份证](type)
- 查询[身份证](type)
- 查询[身份证号码](type)
- [身份证](type)
- [身份证号码](type)
- [查身份证](type)
- 我想查[身份证](type)
- 我要查下[身份证](type)
- 你好!请帮我查询一下[身份证](type)
- [330781198509071514](number)
- [44010319790115345X](number)
- 请告诉我[33078119850907853X](number)这个号码是谁的
- [110101199909073876](number)谁的号码
- 查下[320102198708085599](number)
- 查[433335196712305681](number)
- 号码[430102199711012075](number)
- 帮我查下[110101199909073876](number)
- [110101199909073876](number)的个人信息
- [433335196712305681](number)是谁
- 身份证[433335196712305681](number)
- 查下号码[433335196712305681](number)
- 帮我查询身份证[441235196712305622](number)
- 查询身份证[441235192212305681](number)
- 我想查身份证[441222296712305681](number)
- 身份证号码为[441235196712302222](number)
- 查个身份证,号码是[33078119850907853X](number)
## intent:inform_business
- [开房信息](business)
- [开房](business)
- [住宿信息](business)
- [住宿记录](business)
- 查一查[开房记录](business)
- 查[开房信息](business)
- [住宿信息](business)怎么样
- 查下[住宿信息](business)
- 我想了解[开房记录](business)
- [违章记录](business)
- [违章](business)
- [违章信息](business)
- 查下[违章记录](business)
- 我想知道这个号码的[违章信息](business)
- 能告诉我他的[违章记录](business)吗
- 最近的[违章记录](business)
- [犯罪记录](business)
- [犯罪信息](business)
- [违法记录](business)
- [犯罪](business)
- [违法](business)
- 我要查询这个人的[犯罪记录](business)
- 帮我查[犯罪记录](business)
- 查查[犯罪信息](business)
- 这个人有没有[违法](business)
- 告诉我[犯罪记录](business)
- 查[违法信息](business)
- 我要知道这个人是否有[违法犯罪](business)
- [教育经历](business)
- [教育情况](business)
- [教育](business)
- [教育信息](business)
- 查一查[教育经历](business)
- 这个人的[教育经历](business)
- 看下[教育情况](business)
- 查下[教育信息](business)
- 帮我查一查[教育径路](business)
- [出行轨迹](business)
- [出行信息](business)
- [出行路线](business)
- [出行](business)
- 查下[出行轨迹](business)
- 我想知道这个人的[出行信息](business)
## synonym:身份证号码
- 身份证
- 身份证号码
## synonym:电话号码
- 电话
- 电话号
- 电话号码
- 手机
- 手机号
- 手机号码
## synonym:违章记录
- 违章
- 违章信息
- 违章记录
- 违章处罚
- 违章情况
## synonym:教育经历
- 教育
- 教育经历
- 教育信息
- 教育情况
## synonym:出行轨迹
- 出行
- 出行路线
- 出行信息
- 出行轨迹
- 出行记录
## synonym:开房信息
- 开房记录
- 开房
- 住宿记录
- 住宿信息
- 开房信息
- ## synonym:犯罪记录
- 犯罪
- 犯罪信息
- 犯罪记录
- 违法记录
- 违法
- 违法犯罪
## regex:phone_number
- ((\d{3,4}-)?\d{7,8})|(((\+86)|(86))?(1)\d{10})
## regex:number
- ([1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx])|([1-9]\d{5}\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{2}[0-9Xx])

View File

@ -1,65 +0,0 @@
## intent:request_weather
- 查天气
- 帮我查下天气
- 告诉我天气怎么样
- 查下天气
- 我要查天气
- 天气怎么样
- 看下天气
- 天气如何
- 天气
- 查询天气
- 帮我查天气信息
- 我想知道[明天](date_time)的天气
- [星期一](date_time)的天气
- [今天](date_time)的天气怎么样
- 帮我查下[后天](date_time)的天气
- 查下[广州](address)的天气怎么样
- [长沙](address)的天气
- [深圳](address)[明天](date_time)的天气
- 查下[今天](date_time)[上海](address)的天气
- 帮我查查[佛山](address)这[周六](date_time)的天气
- 我想知道[上海](address)[明天](date_time)的天气
- [上海](address)[明天](date_time)的天气
- [广州](address)[今天](date_time)的天气
- [永州](address)[后天](date_time)的天气
- 你能告诉我[后天](date_time)[广州](address)的天气吗?
- [明天](date_time)在[北京](address)
- 请问[北京](address)[今天](date_time)的天气如何?
- [后天](date_time)我会在[南京](address),请问哪里的天气如何?
- [明天](date_time)我要回[乌鲁木齐](address)了,那里的天气怎么样?
- [今天](date_time)的天气有点冷,不知道[哈尔滨](address)是不是一样冷?
- 小智,帮我查下[明天](date_time)[广州](address)的天气
- 查询[长沙](address)[后天](date_time)的天气
- [今天](date_time)[重庆](address)的天气怎么样?
- [深圳](address)昨天下冰雹了,[明天](date_time)还会下吗?
## intent:inform
- 告诉我在[广州](address)的怎么样
- [武汉](address)
- 在[北京](address)的呢?
- 我想知道[杭州](address)的天气
- 我现在在[上海](address)
- [佛山](address)的吧
- 我要查询[乌鲁木齐](address)的天气
- 查询[深圳](address)的天气
- [常德](address)的天气怎么样?
- 请告诉我[武汉](address)的天气
- 还在[宁波](address)
- [永州](address)的
- 我现在在[广州](address)
- [上海](address)的天气
- [今天](date_time)的
- [明天](date_time)的天气
- [后天](date_time)的天气
- 我想知道[明天](date_time)的天气
- [明天](date_time)
- [后天](date_time)
- [今天](date_time)
- 告诉我[明天](date_time)的天气
- [明天](date_time)的怎么样
- 查询[后天](date_time)的天气
- 查下[明天](date_time)的
- [后天](date_time)的吧
- 帮我查下[今天](date_time)的
- 不知道[今天](date_time)的怎么样

View File

@ -1,67 +0,0 @@
## greet
* greet
- utter_answer_greet
## say affirm with greet
* greet
- utter_answer_greet
* affirm
- utter_answer_affirm
## say affirm
* affirm
- utter_answer_affirm
## say no with greet
* greet
- utter_answer_greet
* deny
- utter_answer_deny
## say no
* deny
- utter_answer_deny
## say goodbye
* goodbye
- utter_answer_goodbye
## thanks with greet
* greet
- utter_answer_greet
* thanks
- utter_answer_thanks
## thanks
* thanks
- utter_answer_thanks
## who are you with greet
* greet
- utter_answer_greet
* whoareyou
- utter_answer_whoareyou
## who are you
* whoareyou
- utter_answer_whoareyou
## who are you with greet
* greet
- utter_answer_greet
* whoareyou
- utter_answer_whoareyou
## what to do
* whattodo
- utter_answer_whattodo
## what to do with greet
* greet
- utter_answer_greet
* whattodo
- utter_answer_whattodo

View File

@ -1,351 +0,0 @@
## interactive_story_1
## happy path
* greet
- utter_answer_greet
* request_number
- number_form
- form{"name": "number_form"}
- form{"name": null}
* thanks
- utter_noworries
## interactive_story_2
## happy path
* greet
- utter_answer_greet
* request_number
- number_form
- form{"name": "number_form"}
- slot{"requested_slot": "business"}
* form: inform{"business": "开房记录"}
- slot{"business": "开房记录"}
- form: restaurant_form
- slot{"business": "开房记录"}
* thanks
- utter_noworries
## interactive_story_3
# happy pathitem+number+business+business+business
* request_number{"type": "身份证号码"}
- number_form
- form{"name": "number_form"}
- slot{"type": "身份证号码"}
- slot{"requested_slot": "number"}
* form: request_number{"number": "431124199720139720"}
- form: number_form
- slot{"number": "431124199720139720"}
- slot{"type": "身份证号码"}
- form{"name": null}
- slot{"requested_slot": null}
* inform_business{"business": "违章记录"}
- number_form
- form{"name": "number_form"}
- slot{"type": "身份证号码"}
- slot{"number": "431124199720139720"}
- slot{"business": "违章记录"}
- slot{"business": null}
- form{"name": null}
- slot{"requested_slot": null}
* inform_business{"business": "开房信息"}
- number_form
- form{"name": "number_form"}
- slot{"type": "身份证号码"}
- slot{"number": "431124199720139720"}
- slot{"business": "开房信息"}
- slot{"business": null}
- form{"name": null}
- slot{"requested_slot": null}
* inform_business{"business": "出行轨迹"}
- number_form
- form{"name": "number_form"}
- slot{"type": "身份证号码"}
- slot{"number": "431124199720139720"}
- slot{"business": "出行轨迹"}
- slot{"business": null}
- form{"name": null}
- slot{"requested_slot": null}
* affirm
- utter_answer_affirm
## interactive_story_4
# happy pathnumber+business+business+business
* request_number{"number": "18902346721"}
- number_form
- form{"name": "number_form"}
- slot{"number": "18902346721"}
- slot{"type": "电话号码"}
- form{"name": null}
- slot{"requested_slot": null}
* inform_business{"business": "违章记录"}
- number_form
- form{"name": "number_form"}
- slot{"type": "电话号码"}
- slot{"number": "18902346721"}
- slot{"business": "违章记录"}
- slot{"business": null}
- form{"name": null}
- slot{"requested_slot": null}
* inform_business{"business": "犯罪记录"}
- number_form
- form{"name": "number_form"}
- slot{"type": "电话号码"}
- slot{"number": "18902346721"}
- slot{"business": "犯罪记录"}
- slot{"business": null}
- form{"name": null}
- slot{"requested_slot": null}
* inform_business{"business": "开房信息"}
- number_form
- form{"name": "number_form"}
- slot{"type": "电话号码"}
- slot{"number": "18902346721"}
- slot{"business": "开房信息"}
- slot{"business": null}
- form{"name": null}
- slot{"requested_slot": null}
* affirm
- utter_answer_affirm
## interactive_story_5
# unhappychit+answer
* greet
- utter_answer_greet
* request_number{"type": "身份证号码"}
- number_form
- form{"name": "number_form"}
- slot{"type": "身份证号码"}
- slot{"number": null}
- slot{"business": null}
- slot{"requested_slot": "number"}
* chitchat{"date_time": "今天"}
- utter_chitchat
- number_form
- slot{"requested_slot": "number"}
* form: request_number{"number": "440123199087233467"}
- form: number_form
- slot{"number": "440123199087233467"}
- slot{"type": "身份证号码"}
- form{"name": null}
- slot{"requested_slot": null}
* thanks
- utter_noworries
## interactive_story_6
# very unhappychit + chit + answer
* greet
- utter_answer_greet
* request_number{"type": "电话号码"}
- number_form
- form{"name": "number_form"}
- slot{"type": "电话号码"}
- slot{"number": null}
- slot{"business": null}
- slot{"requested_slot": "number"}
* chitchat
- utter_chitchat
- number_form
- slot{"requested_slot": "number"}
* chitchat
- utter_chitchat
- number_form
- slot{"requested_slot": "number"}
* form: request_number{"number": "18902346721"}
- form: number_form
- slot{"number": "18902346721"}
- slot{"type": "电话号码"}
- form{"name": null}
- slot{"requested_slot": null}
* thanks
- utter_noworries
## interactive_story_7
# very very unhappychitchat+chitchat+chitchat+answer
* greet
- utter_answer_greet
* request_number{"type": "电话号码"}
- number_form
- form{"name": "number_form"}
- slot{"type": "电话号码"}
- slot{"number": null}
- slot{"business": null}
- slot{"requested_slot": "number"}
* chitchat
- utter_chitchat
- number_form
- slot{"requested_slot": "number"}
* chitchat
- utter_chitchat
- number_form
- slot{"requested_slot": "number"}
* chitchat
- utter_chitchat
- number_form
- slot{"requested_slot": "number"}
* form: request_number{"number": "18902346721"}
- form: number_form
- slot{"number": "18902346721"}
- slot{"type": "电话号码"}
- form{"name": null}
- slot{"requested_slot": null}
* thanks
- utter_noworries
## interactive_story_8
## unhappy pathstop and really stop path
* greet
- utter_answer_greet
* request_number{"type": "身份证号码"}
- number_form
- form{"name": "number_form"}
- slot{"type": "身份证号码"}
- slot{"number": null}
- slot{"business": null}
- slot{"requested_slot": "number"}
* stop
- utter_ask_continue
* deny
- action_deactivate_form
- form{"name": null}
- slot{"requested_slot": null}
* thanks
- utter_noworries
## interactive_story_9
## unhappy pathstop but continue path
* greet
- utter_answer_greet
* request_number{"type": "电话号码"}
- number_form
- form{"name": "number_form"}
- slot{"type": "电话号码"}
- slot{"number": null}
- slot{"business": null}
- slot{"requested_slot": "number"}
* stop
- utter_ask_continue
* affirm
- number_form
- slot{"requested_slot": "number"}
* form: request_number{"number": "18902346721"}
- form: number_form
- slot{"number": "18902346721"}
- slot{"type": "电话号码"}
- form{"name": null}
- slot{"requested_slot": null}
* thanks
- utter_noworries
## interactive_story_10
# unhappy pathchitchat stop but continue path
* greet
- utter_answer_greet
* request_number{"type": "身份证号码"}
- number_form
- form{"name": "number_form"}
- slot{"type": "身份证号码"}
- slot{"number": null}
- slot{"business": null}
- slot{"requested_slot": "number"}
* chitchat
- utter_chitchat
- number_form
- slot{"requested_slot": "number"}
* stop
- utter_ask_continue
* affirm
- number_form
- slot{"requested_slot": "number"}
* form: request_number{"number": "440123199087233467"}
- form: number_form
- slot{"number": "440123199087233467"}
- slot{"type": "身份证号码"}
- form{"name": null}
- slot{"requested_slot": null}
* thanks
- utter_noworries
## interactive_story_11
## unhappy path: stop but continue and chitchat path
* greet
- utter_answer_greet
* request_number{"type": "电话号码"}
- number_form
- form{"name": "number_form"}
- slot{"type": "电话号码"}
- slot{"number": null}
- slot{"business": null}
- slot{"requested_slot": "number"}
* stop
- utter_ask_continue
* affirm
- number_form
- slot{"requested_slot": "number"}
* chitchat
- utter_chitchat
- number_form
- slot{"requested_slot": "number"}
* form: request_number{"number": "18902346721"}
- form: number_form
- slot{"number": "18902346721"}
- slot{"type": "电话号码"}
- form{"name": null}
- slot{"requested_slot": null}
* thanks
- utter_noworries
## interactive_story_12
## unhappy path: chitchat stop but continue and chitchat path
* greet
- utter_answer_greet
* request_number
- number_form
- form{"name": "number_form"}
- slot{"type": "电话号码"}
- slot{"number": null}
- slot{"business": null}
- slot{"requested_slot": "number"}
* chitchat
- utter_chitchat
- number_form
- slot{"requested_slot": "number"}
* stop
- utter_ask_continue
* affirm
- number_form
- slot{"requested_slot": "number"}
* chitchat
- utter_chitchat
- number_form
- slot{"requested_slot": "number"}
* form: request_number{"number": "18902346721"}
- form: number_form
- slot{"number": "18902346721"}
- slot{"type": "电话号码"}
- form{"name": null}
- slot{"requested_slot": null}
* thanks
- utter_noworries
## interactive_story_13
## unhappy path: chitchat, stop and really stop path
* greet
- utter_answer_greet
* request_number
- number_form
- form{"name": "number_form"}
- slot{"type": "电话号码"}
- slot{"number": null}
- slot{"business": null}
- slot{"requested_slot": "number"}
* chitchat
- utter_chitchat
- number_form
- slot{"requested_slot": "number"}
* stop
- utter_ask_continue
* deny
- action_deactivate_form
- form{"name": null}
- slot{"requested_slot": null}
* thanks
- utter_noworries

View File

@ -1,420 +0,0 @@
## happy path
* request_weather
- weather_form
- form{"name": "weather_form"}
- form{"name": null}
## happy path
* greet
- utter_answer_greet
* request_weather
- weather_form
- form{"name": "weather_form"}
- form{"name": null}
* thanks
- utter_noworries
## unhappy path
* greet
- utter_answer_greet
* request_weather
- weather_form
- form{"name": "weather_form"}
* chitchat
- utter_chitchat
- weather_form
- form{"name": null}
* thanks
- utter_noworries
## very unhappy path
* greet
- utter_answer_greet
* request_weather
- weather_form
- form{"name": "weather_form"}
* chitchat
- utter_chitchat
- weather_form
* chitchat
- utter_chitchat
- weather_form
* chitchat
- utter_chitchat
- weather_form
- form{"name": null}
* thanks
- utter_noworries
## stop but continue path
* greet
- utter_answer_greet
* request_weather
- weather_form
- form{"name": "weather_form"}
* stop
- utter_ask_continue
* affirm
- weather_form
- form{"name": null}
* thanks
- utter_noworries
## stop and really stop path
* greet
- utter_answer_greet
* request_weather
- weather_form
- form{"name": "weather_form"}
* stop
- utter_ask_continue
* deny
- action_deactivate_form
- form{"name": null}
## chitchat stop but continue path
* request_weather
- weather_form
- form{"name": "weather_form"}
* chitchat
- utter_chitchat
- weather_form
* stop
- utter_ask_continue
* affirm
- weather_form
- form{"name": null}
* thanks
- utter_noworries
## stop but continue and chitchat path
* greet
- utter_answer_greet
* request_weather
- weather_form
- form{"name": "weather_form"}
* stop
- utter_ask_continue
* affirm
- weather_form
* chitchat
- utter_chitchat
- weather_form
- form{"name": null}
* thanks
- utter_noworries
## chitchat stop but continue and chitchat path
* greet
- utter_answer_greet
* request_weather
- weather_form
- form{"name": "weather_form"}
* chitchat
- utter_chitchat
- weather_form
* stop
- utter_ask_continue
* affirm
- weather_form
* chitchat
- utter_chitchat
- weather_form
- form{"name": null}
* thanks
- utter_noworries
## chitchat, stop and really stop path
* greet
- utter_answer_greet
* request_weather
- weather_form
- form{"name": "weather_form"}
* chitchat
- utter_chitchat
- weather_form
* stop
- utter_ask_continue
* deny
- action_deactivate_form
- form{"name": null}
## interactive_story_1
## 天气 + 时间 + 地点 + 地点
* request_weather
- weather_form
- form{"name": "weather_form"}
- slot{"requested_slot": "date_time"}
* form: inform{"date_time": "明天"}
- form: weather_form
- slot{"date_time": "明天"}
- slot{"requested_slot": "address"}
* form: inform{"address": "广州"}
- form: weather_form
- slot{"address": "广州"}
- form{"name": null}
- slot{"requested_slot": null}
* inform{"date_time": "后天"} OR request_weather{"date_time": "后天"}
- weather_form
- form{"name": "weather_form"}
- slot{"date_time": "明天"}
- slot{"address": "广州"}
- slot{"date_time": "后天"}
- form{"name": null}
- slot{"requested_slot": null}
* thanks
- utter_answer_thanks
## interactive_story_1
## 天气 + 时间 + 地点 + 时间
* request_weather
- weather_form
- form{"name": "weather_form"}
- slot{"requested_slot": "date_time"}
* form: inform{"date_time": "明天"}
- form: weather_form
- slot{"date_time": "明天"}
- slot{"requested_slot": "address"}
* form: inform{"address": "广州"}
- form: weather_form
- slot{"address": "广州"}
- form{"name": null}
- slot{"requested_slot": null}
* inform{"address": "上海"} OR request_weather{"address": "深圳"}
- weather_form
- form{"name": "weather_form"}
- slot{"date_time": "明天"}
- slot{"address": "广州"}
- slot{"address": "上海"}
- form{"name": null}
- slot{"requested_slot": null}
* affirm
- utter_answer_affirm
## interactive_story_2
## 天气/时间/地点 + 地点
* request_weather{"date_time": "明天", "address": "上海"}
- weather_form
- form{"name": "weather_form"}
- slot{"date_time": "明天"}
- slot{"address": "上海"}
- form{"name": null}
- slot{"requested_slot": null}
* inform{"address": "广州"} OR request_weather{"address": "广州"}
- weather_form
- form{"name": "weather_form"}
- slot{"date_time": "明天"}
- slot{"address": "上海"}
- slot{"address": "广州"}
- form{"name": null}
- slot{"requested_slot": null}
* thanks
- utter_answer_thanks
## interactive_story_3
## 天气/时间/地点 + 时间
* request_weather{"address": "深圳", "date_time": "后天"}
- weather_form
- form{"name": "weather_form"}
- slot{"date_time": "后天"}
- slot{"address": "深圳"}
- form{"name": null}
- slot{"requested_slot": null}
* inform{"date_time": "大后天"} OR request_weather{"date_time": "大后天"}
- weather_form
- form{"name": "weather_form"}
- slot{"date_time": "后天"}
- slot{"address": "深圳"}
- slot{"date_time": "大后天"}
- form{"name": null}
- slot{"requested_slot": null}
* thanks
- utter_answer_thanks
## interactive_story_2
## 天气/时间/地点 + 地点 + 时间
* request_weather{"date_time": "明天", "address": "上海"}
- weather_form
- form{"name": "weather_form"}
- slot{"date_time": "明天"}
- slot{"address": "上海"}
- form{"name": null}
- slot{"requested_slot": null}
* inform{"address": "北京"} OR request_weather{"address": "北京"}
- weather_form
- form{"name": "weather_form"}
- slot{"date_time": "明天"}
- slot{"address": "上海"}
- slot{"address": "北京"}
- form{"name": null}
- slot{"requested_slot": null}
* inform{"date_time": "后天"} OR request_weather{"date_time": "后天"}
- weather_form
- form{"name": "weather_form"}
- slot{"date_time": "明天"}
- slot{"address": "北京"}
- slot{"date_time": "后天"}
- form{"name": null}
- slot{"requested_slot": null}
* affirm
- utter_answer_affirm
## interactive_story_3
## 天气/时间/地点 + 地点 + 地点
* request_weather{"date_time": "后天", "address": "北京"}
- weather_form
- form{"name": "weather_form"}
- slot{"date_time": "后天"}
- slot{"address": "北京"}
- form{"name": null}
- slot{"requested_slot": null}
* inform{"address": "深圳"} OR request_weather{"address": "深圳"}
- weather_form
- form{"name": "weather_form"}
- slot{"date_time": "后天"}
- slot{"address": "北京"}
- slot{"address": "深圳"}
- form{"name": null}
- slot{"requested_slot": null}
* inform{"address": "南京"} OR request_weather{"address": "南京"}
- weather_form
- form{"name": "weather_form"}
- slot{"date_time": "后天"}
- slot{"address": "深圳"}
- slot{"address": "南京"}
- form{"name": null}
- slot{"requested_slot": null}
* thanks
- utter_answer_thanks
## interactive_story_4
## 天气/时间/地点 + 时间 + 地点
* request_weather{"date_time": "明天", "address": "长沙"}
- weather_form
- form{"name": "weather_form"}
- slot{"date_time": "明天"}
- slot{"address": "长沙"}
- form{"name": null}
- slot{"requested_slot": null}
* inform{"date_time": "后天"} OR request_weather{"date_time": "后天"}
- weather_form
- form{"name": "weather_form"}
- slot{"date_time": "明天"}
- slot{"address": "长沙"}
- slot{"date_time": "后天"}
- form{"name": null}
- slot{"requested_slot": null}
* inform{"date_time": "大后天"} OR request_weather{"date_time": "大后天"}
- weather_form
- form{"name": "weather_form"}
- slot{"date_time": "后天"}
- slot{"address": "长沙"}
- slot{"date_time": "大后天"}
- form{"name": null}
- slot{"requested_slot": null}
* affirm
- utter_answer_affirm
## interactive_story_5
## 天气/时间/地点 + 时间 + 时间
* request_weather{"date_time": "后天", "address": "深圳"}
- weather_form
- form{"name": "weather_form"}
- slot{"date_time": "后天"}
- slot{"address": "深圳"}
- form{"name": null}
- slot{"requested_slot": null}
* inform{"date_time": "明天"} OR request_weather{"date_time": "明天"}
- weather_form
- form{"name": "weather_form"}
- slot{"date_time": "后天"}
- slot{"address": "深圳"}
- slot{"date_time": "明天"}
- form{"name": null}
- slot{"requested_slot": null}
* inform{"address": "广州"} OR request_weather{"address": "广州"}
- weather_form
- form{"name": "weather_form"}
- slot{"date_time": "明天"}
- slot{"address": "深圳"}
- slot{"address": "广州"}
- form{"name": null}
- slot{"requested_slot": null}
* thanks
- utter_answer_thanks
## interactive_story_4
## 天气/时间 + 地点 + 时间
* request_weather{"date_time": "明天"}
- weather_form
- form{"name": "weather_form"}
- slot{"date_time": "明天"}
- slot{"requested_slot": "address"}
* form: inform{"address": "广州"}
- form: weather_form
- slot{"address": "广州"}
- form{"name": null}
- slot{"requested_slot": null}
* inform{"date_time": "后天"} OR request_weather{"date_time": "后天"}
- weather_form
- form{"name": "weather_form"}
- slot{"date_time": "明天"}
- slot{"address": "广州"}
- slot{"date_time": "后天"}
- form{"name": null}
- slot{"requested_slot": null}
* thanks
- utter_answer_thanks
## interactive_story_5
## 天气/地点 + 时间 + 时间
* request_weather{"address": "广州"}
- weather_form
- form{"name": "weather_form"}
- slot{"address": "广州"}
- slot{"requested_slot": "date_time"}
* form: inform{"date_time": "后天"}
- form: weather_form
- slot{"date_time": "后天"}
- form{"name": null}
- slot{"requested_slot": null}
* inform{"date_time": "明天"} OR request_weather{"date_time": "明天"}
- weather_form
- form{"name": "weather_form"}
- slot{"date_time": "后天"}
- slot{"address": "广州"}
- slot{"date_time": "明天"}
- form{"name": null}
- slot{"requested_slot": null}
* thanks
- utter_answer_thanks
## interactive_story_1
## 天气/时间/地点 + chit + chit(restart)+询问天气
* request_weather{"date_time": "今天", "address": "广州"}
- weather_form
- form{"name": "weather_form"}
- slot{"date_time": "今天"}
- slot{"address": "广州"}
- form{"name": null}
- slot{"requested_slot": null}
* chitchat
- utter_chitchat
* chitchat
- utter_chitchat
- action_restart
* request_weather
- weather_form
- form{"name": "weather_form"}
- slot{"requested_slot": "date_time"}
* form: inform{"date_time": "今天"}
- form: weather_form
- slot{"date_time": "今天"}
- slot{"requested_slot": "address"}
* form: inform{"address": "广州"}
- form: weather_form
- slot{"address": "广州"}
- form{"name": null}
- slot{"requested_slot": null}
* thanks
- utter_answer_thanks

View File

@ -1,148 +0,0 @@
absl-py==0.9.0
aiofiles==0.4.0
aiohttp==3.6.2
APScheduler==3.6.3
astor==0.8.1
async-generator==1.10
async-timeout==3.0.1
attrs==19.3.0
bleach==1.5.0
boto3==1.12.36
botocore==1.15.36
cachetools==4.0.0
certifi==2019.11.28
cffi==1.14.0
chardet==3.0.4
Click==7.0
cloudpickle==1.2.2
colorama==0.4.3
colorclass==2.2.0
coloredlogs==10.0
colorhash==1.0.2
contextvars==2.4
cryptography==2.9
cycler==0.10.0
decorator==4.4.2
dnspython==1.16.0
docopt==0.6.2
docutils==0.15.2
enum34==1.1.10
fbmessenger==6.0.0
Flask==1.1.2
future==0.18.2
gast==0.2.2
gevent==1.4.0
google-auth==1.13.1
google-auth-oauthlib==0.4.1
google-pasta==0.2.0
greenlet==0.4.15
grpcio==1.28.1
h11==0.8.1
h2==3.2.0
h5py==2.10.0
hpack==3.0.0
hstspreload==2020.3.31
html5lib==0.9999999
httplib2==0.17.1
httptools==0.1.1
httpx==0.9.3
humanfriendly==8.1
hyperframe==5.2.0
idna==2.8
idna-ssl==1.1.0
immutables==0.11
importlib-metadata==1.6.0
itsdangerous==1.1.0
jieba==0.42.1
Jinja2==2.11.1
jmespath==0.9.4
joblib==0.14.1
jsonpickle==1.3
jsonschema==3.2.0
kafka-python==1.4.7
Keras-Applications==1.0.8
Keras-Preprocessing==1.1.0
kiwisolver==1.1.0
Markdown==3.2.1
MarkupSafe==1.1.1
matplotlib==3.1.3
mattermostwrapper==2.1
mitie==0.7.0
multidict==4.7.5
networkx==2.4
numpy==1.18.2
oauth2client==4.1.3
oauthlib==3.1.0
opt-einsum==3.2.0
packaging==19.0
pika==1.1.0
prompt-toolkit==2.0.10
protobuf==3.11.3
psycopg2-binary==2.8.4
pyasn1==0.4.8
pyasn1-modules==0.2.8
pycparser==2.19
pydot==1.4.1
PyJWT==1.7.1
pykwalify==1.7.0
pymongo==3.8.0
pyparsing==2.4.6
pyreadline==2.1
pyrsistent==0.16.0
PySocks==1.7.1
python-crfsuite==0.9.6
python-dateutil==2.8.1
python-engineio==3.11.2
python-socketio==4.4.0
python-telegram-bot==11.1.0
pytz==2019.3
PyYAML==5.3.1
questionary==1.5.1
rasa==1.9.5
rasa-sdk==1.9.0
redis==3.4.1
requests==2.23.0
requests-oauthlib==1.3.0
requests-toolbelt==0.9.1
rfc3986==1.3.2
rocketchat-API==0.6.36
rsa==4.0
ruamel.yaml==0.15.100
s3transfer==0.3.3
sanic==19.12.2
Sanic-Cors==0.10.0.post3
sanic-jwt==1.3.2
Sanic-Plugins-Framework==0.9.2
scikit-learn==0.22.2.post1
scipy==1.4.1
six==1.14.0
sklearn-crfsuite==0.3.6
slack==0.0.2
slackclient==2.5.0
sniffio==1.1.0
SQLAlchemy==1.3.15
tabulate==0.8.7
tensorboard==2.1.1
tensorflow==2.1.0
tensorflow-addons==0.8.3
tensorflow-estimator==2.1.0
tensorflow-hub==0.7.0
tensorflow-probability==0.7.0
tensorflow-tensorboard==0.4.0
termcolor==1.1.0
terminaltables==3.1.0
tqdm==4.31.1
twilio==6.26.3
typeguard==2.7.1
typing-extensions==3.7.4.2
tzlocal==2.0.0
ujson==1.35
urllib3==1.25.8
wcwidth==0.1.9
webexteamssdk==1.1.1
websocket-client==0.54.0
websockets==8.1
Werkzeug==1.0.1
wrapt==1.12.1
yarl==1.4.2
zipp==3.1.0

View File

@ -1,10 +0,0 @@
#!/usr/bin/env bash
# 启动服务
# 1. 启动rasa server
python -m rasa run --port 5005 -m models/20200319-162558.tar.gz --endpoints configs/endpoints.yml --credentials configs/credentials.yml --debug
# 2. 启动action server
python -m rasa run actions --port 5055 --actions actions --debug
# 3. 启动server.py
python server.py

View File

@ -1,85 +0,0 @@
"""
server.py
~~~~~~~~~
web server定义前端调用接口
:date: 2020-02-14 14:36:00
:author: by jiangdg
"""
from flask import Flask, jsonify
from flask import request
import requests
import json
import logging
app = Flask(__name__)
@app.route('/', methods=['GET', 'POST'])
def test():
return"测试"
@app.route('/ai', methods=['GET', 'POST'])
def webToBot():
"""
前端调用接口
路径/ai
请求方式GETPOST
请求参数content
:return: response rasa响应数据
"""
content = request.values.get('content')
if content is None:
return 'empty input'
response = requestRasabotServer('jiangdg', content)
return response.text.encode('utf-8').decode("unicode-escape")
def requestRasabotServer(userid, content):
"""
访问rasa服务
:param userid: 用户id
:param content: 自然语言文本
:return: json格式响应数据
"""
params = {'sender': userid, 'message': content}
botIp = '127.0.0.1'
botPort = '5005'
# rasa使用rest channel
# https://rasa.com/docs/rasa/user-guide/connectors/your-own-website/#rest-channels
# POST /webhooks/rest/webhook
rasaUrl = "http://{0}:{1}/webhooks/rest/webhook".format(botIp, botPort)
reponse = requests.post(
rasaUrl,
data=json.dumps(params),
headers={'Content-Type': 'application/json'}
)
return reponse
if __name__ == '__main__':
webIp = '127.0.0.1'
webPort = '8088'
print("##### webIp={}, webPort={}".format(webIp, webPort))
# 初始化日志引擎
fh = logging.FileHandler(encoding='utf-8', mode='a', filename='chitchat.log')
logging.basicConfig(
handlers=[fh],
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
datefmt='%a, %d %b %Y %H:%M:%S',
)
# 启动服务开启多线程、debug模式
# 浏览器访问http://127.0.0.1:8088/ai?content="你好"
app.run(
host=webIp,
port=int(webPort),
threaded=True,
debug=True
)

View File

@ -1,19 +0,0 @@
#!/usr/bin/env bash
# 训练NLU和Core模型
python -m rasa train --config configs/config.yml --domain configs/domain.yml --data data/
python -m rasa train --config configs/zh_jieba_supervised_embeddings_config.yml --domain configs/domain.yml --data data/
python -m rasa train --config configs/zh_jieba_mitie_embeddings_config.yml --domain configs/domain.yml --data data/
#usage: rasa train [-h] [-v] [-vv] [--quiet] [--data DATA [DATA ...]]
# [-c CONFIG] [-d DOMAIN] [--out OUT]
# [--augmentation AUGMENTATION] [--debug-plots]
# [--dump-stories] [--fixed-model-name FIXED_MODEL_NAME]
# [--persist-nlu-data] [--force]
# {core,nlu} ...
# 交互式学习构建样本
python -m rasa run actions --port 5055 --actions actions --debug
python -m rasa interactive -m models/20200319-162558.tar.gz --endpoints configs/endpoints.yml --config configs/zh_jieba_mitie_embeddings_config.yml

View File

@ -5,7 +5,6 @@
[春松客服机器人客服文档](https://docs.chatopera.com/products/cskefu/work-chatbot.html)
## 安装插件
安装脚本为Bash Shell脚本需要在命令行控制台执行。
```
@ -14,20 +13,7 @@
**提示**: Windows环境使用Git Bash 命令行终端执行该命令,也可以完成安装。
## RASA中文聊天机器人
参考搭建自 https://github.com/jiangdongguo/ChitChatAssistant
目录位于
```
./ChitChatAssistant
```
请求接口 http://127.0.0.1:8088/ai?content="YouInput"
## 卸载插件
卸载脚本为Bash Shell脚本需要在命令行控制台执行。
```

View File

@ -35,21 +35,7 @@ import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.internal.$Gson$Preconditions;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -66,22 +52,11 @@ import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.awt.*;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.util.Date;
import java.util.List;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.tbp.v20190627.TbpClient;
import com.tencentcloudapi.tbp.v20190627.models.TextResetRequest;
import com.tencentcloudapi.tbp.v20190627.models.TextResetResponse;
import com.google.gson.Gson;
/**
* 聊天机器人
* 请求聊天机器人服务
@ -105,7 +80,7 @@ public class ApiChatbotController extends Handler {
private final static String botServiecProvider = SystemEnvHelper.getenv(
ChatbotConstants.BOT_PROVIDER, ChatbotConstants.DEFAULT_BOT_PROVIDER);
private final static String TencentbotServiecProvider = SystemEnvHelper.getenv(ChatbotConstants.BOT_PROVIDER,ChatbotConstants.DEFAULT_TENCENTBOT_PROVIDER);
/**
* 聊天机器人
*
@ -220,101 +195,12 @@ public class ApiChatbotController extends Handler {
final String id = j.get("id").getAsString();
Chatbot c = chatbotRes.findOne(id);
final String RobotType = c.getrobottype();
if (c == null) {
resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_FAIL_4);
resp.addProperty(RestUtils.RESP_KEY_ERROR, "该聊天机器人不存在。");
return resp;
}
switch (RobotType) {
case "cosin":
resp = enableCosin(j, c, isEnabled,resp);
break;
case "tencent":
resp = enableTencent(j, c, isEnabled,resp);
break;
case "rasa":
resp = enableRASA(j, c, isEnabled,resp);
break;
}
return resp;
}
private JsonObject enableTencent(JsonObject j,Chatbot c, boolean isEnabled,JsonObject resp)
{
String BotId = c.getBotId();
String TerminalId = c.getTerminalId();
String SecretId = c.getSecretId();
String SecretKey = c.getSecretKey();
String BotEnv = c.getBotEnv();
try {
JsonObject botRes = TextReset(SecretId,SecretKey,BotId,BotEnv,TerminalId);
if (!botRes.has("Error")) {
c.setEnabled(isEnabled);
chatbotRes.save(c);
// 更新访客网站配置
CousultInvite invite = OnlineUserProxy.consult(c.getSnsAccountIdentifier(), c.getOrgi());
invite.setAi(isEnabled);
consultInviteRes.save(invite);
OnlineUserProxy.cacheConsult(invite);
resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_SUCC);
resp.addProperty(RestUtils.RESP_KEY_DATA, "完成。");
} else {
resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_FAIL_7);
resp.addProperty(RestUtils.RESP_KEY_ERROR, "智能问答引擎不存在该聊天机器人,未能正确设置。");
}
}
catch (Exception e) {
resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_FAIL_5);
resp.addProperty(RestUtils.RESP_KEY_DATA, "设置不成功,智能问答引擎服务异常。");
}
return resp;
}
private JsonObject enableRASA(JsonObject j,Chatbot c, boolean isEnabled,JsonObject resp)
{
try {
JsonObject botRes = RasaTest(c.getBaseUrl());
//System.out.println(botRes);
if (!botRes.has("Error")) {
c.setEnabled(isEnabled);
chatbotRes.save(c);
// 更新访客网站配置
CousultInvite invite = OnlineUserProxy.consult(c.getSnsAccountIdentifier(), c.getOrgi());
invite.setAi(isEnabled);
consultInviteRes.save(invite);
OnlineUserProxy.cacheConsult(invite);
resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_SUCC);
resp.addProperty(RestUtils.RESP_KEY_DATA, "完成。");
} else {
resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_FAIL_7);
resp.addProperty(RestUtils.RESP_KEY_ERROR, "智能问答引擎不存在该聊天机器人,未能正确设置。");
}
}
catch (Exception e) {
resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_FAIL_5);
resp.addProperty(RestUtils.RESP_KEY_DATA, "设置不成功,智能问答引擎服务异常。");
}
System.out.println(resp);
return resp;
}
/**
*
*/
private JsonObject enableCosin(JsonObject j,Chatbot c, boolean isEnabled,JsonObject resp)
{
try {
com.chatopera.bot.sdk.Chatbot bot = new com.chatopera.bot.sdk.Chatbot(
@ -345,6 +231,7 @@ public class ApiChatbotController extends Handler {
}
return resp;
}
/**
* Enable Chatbot 智能回复
*
@ -588,10 +475,6 @@ public class ApiChatbotController extends Handler {
return resp;
}
/**
* 创建聊天机器人
*
@ -600,423 +483,13 @@ public class ApiChatbotController extends Handler {
* @param orgi
* @return
*/
private JsonObject create(final JsonObject j, final String creater, final String orgi) throws Exception
{ JsonObject resp = new JsonObject();
String RobotType = j.get("robottype").getAsString();
//System.out.println(RobotType);
switch (RobotType) {
case "cosin":
resp = createCosinRobot(j, creater, orgi);
break;
case "tencent":
resp = createTencentRobot(j, creater, orgi);
break;
case "rasa":
//System.out.println("RASA Robot");
resp = createRASARobot(j, creater, orgi);
break;
}
//System.out.println(resp);
return resp;
}
private JsonObject TextReset(final String SecretId, final String SecretKey, final String BotId,final String BotEnv,final String TerminalId ) {
JsonObject result = new JsonObject();
try{
Credential cred = new Credential(SecretId, SecretKey);
HttpProfile httpProfile = new HttpProfile();
httpProfile.setEndpoint("tbp.tencentcloudapi.com");
ClientProfile clientProfile = new ClientProfile();
clientProfile.setHttpProfile(httpProfile);
TbpClient client = new TbpClient(cred, "", clientProfile);
String params = "{\"BotId\":\""+BotId+"\",\"BotEnv\":\""+BotEnv+"\",\"TerminalId\":\""+TerminalId+"\"}";
TextResetRequest req = TextResetRequest.fromJsonString(params, TextResetRequest.class);
TextResetResponse resp = client.TextReset(req);
result =new JsonParser().parse(TextResetResponse.toJsonString(resp)).getAsJsonObject();
//System.out.println("hello"+result);
return result;
} catch (TencentCloudSDKException e) {
System.out.println(e.toString());
}
return result;
}
/**
*
*/
private JsonObject createTencentRobot(final JsonObject j, final String creater, final String orgi)
{
JsonObject resp = new JsonObject();
String snsid = null;
String BotEnv = null;
String BotId = null;
String SecretId = null;
String SecretKey = null;
String TerminalId = null;
if ((!j.has("BotId")) || StringUtils.isBlank(j.get("BotId").getAsString())) {
resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_FAIL_3);
resp.addProperty(RestUtils.RESP_KEY_ERROR, "不合法的参数未传入【BotId】。");
return resp;
} else {
BotId = j.get("BotId").getAsString();
}
if ((!j.has("TerminalId")) || StringUtils.isBlank(j.get("TerminalId").getAsString())) {
resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_FAIL_3);
resp.addProperty(RestUtils.RESP_KEY_ERROR, "不合法的参数未传入【TerminalId】。");
return resp;
} else {
TerminalId = j.get("TerminalId").getAsString();
}
if ((!j.has("SecretId")) || StringUtils.isBlank(j.get("SecretId").getAsString())) {
resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_FAIL_3);
resp.addProperty(RestUtils.RESP_KEY_ERROR, "不合法的参数未传入【SecretId】。");
return resp;
} else {
SecretId = j.get("SecretId").getAsString();
}
if ((!j.has("SecretKey")) || StringUtils.isBlank(j.get("SecretKey").getAsString())) {
resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_FAIL_3);
resp.addProperty(RestUtils.RESP_KEY_ERROR, "不合法的参数未传入【SecretKey】。");
return resp;
} else {
SecretKey = j.get("SecretKey").getAsString();
}
if (!(j.has("BotEnv"))) {
resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_FAIL_3);
resp.addProperty(RestUtils.RESP_KEY_ERROR, "不合法的参数未传入有效【BotEnv】。");
return resp;
} else {
BotEnv = j.get("BotEnv").getAsString();
}
if ((!j.has("snsid")) || StringUtils.isBlank(j.get("snsid").getAsString())) {
resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_FAIL_3);
resp.addProperty(RestUtils.RESP_KEY_ERROR, "不合法的参数未传入【snsid】。");
return resp;
} else {
snsid = j.get("snsid").getAsString();
// #TODO 仅支持webim
if (!snsAccountRes.existsBySnsidAndSnstypeAndOrgi(snsid, Constants.CHANNEL_TYPE_WEBIM, orgi)) {
resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_FAIL_3);
resp.addProperty(RestUtils.RESP_KEY_ERROR, "不合法的参数不存在【snsid】对应的网站渠道。");
return resp;
}
if (chatbotRes.existsBySnsAccountIdentifierAndOrgi(snsid, orgi)) {
resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_FAIL_3);
resp.addProperty(RestUtils.RESP_KEY_ERROR, "不合法的参数该渠道【snsid】已经存在聊天机器人。");
return resp;
}
}
if (chatbotRes.existsByClientIdAndOrgi(BotId, orgi)) {
resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_FAIL_3);
resp.addProperty(RestUtils.RESP_KEY_ERROR, "不合法的参数,数据库中存在该聊天机器人。");
return resp;
}
try {
logger.info("create bot with ", TencentbotServiecProvider );
JsonObject botRes = TextReset(SecretId,SecretKey,BotId,BotEnv,TerminalId);
if (!botRes.has("Error")) { // 该机器人存在clientId Secret配对成功
// 创建成功
Chatbot c = new Chatbot();
//JSONObject botDetails = bot.details();
c.setId(MainUtils.getUUID());
c.setSecretId(SecretId);
c.setSecretKey(SecretKey);
c.setBotId(BotId);
c.setName(BotId);
//c.setClientId(BotId);//ClientID 不能为空 暂时设定为一样的值
c.setBotEnv(BotEnv);
c.setTerminalId(TerminalId);
c.setWorkmode("机器人客服优先");
c.setBaseUrl(TencentbotServiecProvider);
/**
c.setDescription(botDetails.getJSONObject("data").getString("description"));
c.setFallback(botDetails.getJSONObject("data").getString("fallback"));
c.setPrimaryLanguage(botDetails.getJSONObject("data").getString("primaryLanguage"));
c.setName(botDetails.getJSONObject("data").getString("name"));
c.setWelcome(botDetails.getJSONObject("data").getString("welcome"));
*/
c.setCreater(creater);
c.setOrgi(orgi);
c.setChannel(Constants.CHANNEL_TYPE_WEBIM);
c.setSnsAccountIdentifier(snsid);
Date dt = new Date();
c.setCreatetime(dt);
c.setUpdatetime(dt);
c.setrobottype(j.get("robottype").getAsString());
// 默认不开启
boolean enabled = false;
c.setEnabled(enabled);
// 更新访客网站配置
CousultInvite invite = OnlineUserProxy.consult(c.getSnsAccountIdentifier(), c.getOrgi());
invite.setAi(enabled);
//invite.setAifirst(StringUtils.equals(Constants.CHATBOT_CHATBOT_FIRST, workmode));
invite.setAiid(c.getId());
invite.setAiname(c.getName());
invite.setAisuccesstip(c.getWelcome());
consultInviteRes.save(invite);
OnlineUserProxy.cacheConsult(invite);
chatbotRes.save(c);
JsonObject data = new JsonObject();
data.addProperty("id", c.getId());
data.addProperty("robottype", c.getrobottype());
resp.add(RestUtils.RESP_KEY_DATA, data);
resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_SUCC);
return resp;
} else {
// 创建失败
resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_FAIL_6);
resp.addProperty(
RestUtils.RESP_KEY_ERROR, "Chatopera云服务该机器人不存在请先创建机器人, 登录 https://console.cloud.tencent.com/tbp");
return resp;
}
}
catch (Exception e){
System.out.println(e);
logger.error("bot create error");
resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_FAIL_5);
resp.addProperty(
RestUtils.RESP_KEY_ERROR,
"无法访问该机器人请确认【1】该服务器可以访问互联网【2】该聊天机器人已经创建【3】参数正确设置。");
return resp;
}
}
private JsonObject RasaTest(final String BotUrl)
{
String Url = BotUrl;
JsonObject result = new JsonObject();
result.addProperty("error",1);
CloseableHttpClient httpClient = HttpClients.createDefault();
try {
URIBuilder uriBuilder = new URIBuilder(Url);
uriBuilder.setParameter("content","查询广州明天的天气");
HttpGet httpGet = new HttpGet(uriBuilder.build());
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(5000) //连接超时时间
.setConnectionRequestTimeout(5000) //请求超时时间
.setSocketTimeout(5000) //socket读写超时时间
.setRedirectsEnabled(true) //是否允许重定向
.build();
httpGet.setConfig(requestConfig);
CloseableHttpResponse response = null;
response = httpClient.execute(httpGet);
if (response.getStatusLine().getStatusCode() == 200) {
String content = EntityUtils.toString(response.getEntity(), "utf8");
JsonArray tempArray = new JsonParser().parse(content).getAsJsonArray();
result = tempArray.get(0).getAsJsonObject();
//System.out.println(result);
}
//请求内容
} catch (IOException e) {
e.printStackTrace();
} catch (URISyntaxException e) {
e.printStackTrace();
}
return result;
}
/**
* 创建 RASARobot
*
* */
private JsonObject createRASARobot(final JsonObject j, final String creater, final String orgi)
{
JsonObject resp = new JsonObject();
String snsid = null;
String BotId = null;
String BotUrl = null;
String workmode = "机器人客服优先";;
String SecretId = null;
if ((!j.has("BotId")) || StringUtils.isBlank(j.get("BotId").getAsString())) {
resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_FAIL_3);
resp.addProperty(RestUtils.RESP_KEY_ERROR, "不合法的参数未传入【BotId】。");
return resp;
} else {
BotId = j.get("BotId").getAsString();
}
if ((!j.has("BotUrl")) || StringUtils.isBlank(j.get("BotUrl").getAsString())) {
resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_FAIL_3);
resp.addProperty(RestUtils.RESP_KEY_ERROR, "不合法的参数未传入【BotUrl】。");
return resp;
} else {
BotUrl = j.get("BotUrl").getAsString();
}
if ((!j.has("SecretId")) || StringUtils.isBlank(j.get("SecretId").getAsString())) {
resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_FAIL_3);
resp.addProperty(RestUtils.RESP_KEY_ERROR, "不合法的参数未传入【SecretId】。");
return resp;
} else {
SecretId = j.get("SecretId").getAsString();
}
if ((!j.has("snsid")) || StringUtils.isBlank(j.get("snsid").getAsString())) {
resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_FAIL_3);
resp.addProperty(RestUtils.RESP_KEY_ERROR, "不合法的参数未传入【snsid】。");
return resp;
} else {
snsid = j.get("snsid").getAsString();
// #TODO 仅支持webim
if (!snsAccountRes.existsBySnsidAndSnstypeAndOrgi(snsid, Constants.CHANNEL_TYPE_WEBIM, orgi)) {
resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_FAIL_3);
resp.addProperty(RestUtils.RESP_KEY_ERROR, "不合法的参数不存在【snsid】对应的网站渠道。");
return resp;
}
if (chatbotRes.existsBySnsAccountIdentifierAndOrgi(snsid, orgi)) {
resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_FAIL_3);
resp.addProperty(RestUtils.RESP_KEY_ERROR, "不合法的参数该渠道【snsid】已经存在聊天机器人。");
return resp;
}
}
if (chatbotRes.existsByClientIdAndOrgi(BotId, orgi)) {
resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_FAIL_3);
resp.addProperty(RestUtils.RESP_KEY_ERROR, "不合法的参数,数据库中存在该聊天机器人。");
return resp;
}
try {
logger.info("create bot with ",BotUrl );
JsonObject botRes = RasaTest(BotUrl);
if (!botRes.has("Error")) { // 该机器人存在clientId Secret配对成功
// 创建成功
Chatbot c = new Chatbot();
//JSONObject botDetails = bot.details();
c.setId(MainUtils.getUUID());
c.setSecretId(SecretId);
c.setBotId(BotId);
c.setName(BotId);
c.setClientId(BotId);//ClientID 不能为空 暂时设定为一样的值
//c.setBotEnv(BotEnv);
c.setBaseUrl(BotUrl);
//c.setTerminalId(TerminalId);
/**
c.setDescription(botDetails.getJSONObject("data").getString("description"));
c.setFallback(botDetails.getJSONObject("data").getString("fallback"));
c.setPrimaryLanguage(botDetails.getJSONObject("data").getString("primaryLanguage"));
c.setName(botDetails.getJSONObject("data").getString("name"));
c.setWelcome(botDetails.getJSONObject("data").getString("welcome"));
*/
c.setCreater(creater);
c.setOrgi(orgi);
c.setChannel(Constants.CHANNEL_TYPE_WEBIM);
c.setSnsAccountIdentifier(snsid);
Date dt = new Date();
c.setCreatetime(dt);
c.setUpdatetime(dt);
c.setrobottype(j.get("robottype").getAsString());
// 默认不开启
c.setWorkmode("机器人客服优先");
boolean enabled = false;
c.setEnabled(enabled);
// 更新访客网站配置
CousultInvite invite = OnlineUserProxy.consult(c.getSnsAccountIdentifier(), c.getOrgi());
invite.setAi(enabled);
invite.setAifirst(StringUtils.equals(Constants.CHATBOT_CHATBOT_FIRST, workmode));
invite.setAiid(c.getId());
invite.setAiname(c.getName());
invite.setAisuccesstip(c.getWelcome());
consultInviteRes.save(invite);
OnlineUserProxy.cacheConsult(invite);
chatbotRes.save(c);
JsonObject data = new JsonObject();
data.addProperty("id", c.getId());
data.addProperty("robottype", c.getrobottype());
resp.add(RestUtils.RESP_KEY_DATA, data);
resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_SUCC);
return resp;
} else {
// 创建失败
resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_FAIL_6);
resp.addProperty(
RestUtils.RESP_KEY_ERROR, "Chatopera云服务该机器人不存在请先创建机器人, 登录 https://console.cloud.tencent.com/tbp");
return resp;
}
}
catch (Exception e){
System.out.println(e);
logger.error("bot create error");
resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_FAIL_5);
resp.addProperty(
RestUtils.RESP_KEY_ERROR,
"无法访问该机器人请确认【1】该服务器可以访问互联网【2】该聊天机器人已经创建【3】参数正确设置。");
return resp;
}
}
/**
* 创建春松聊天机器人
*
* @param j
* @param creater
* @param orgi
* @return
*/
private JsonObject createCosinRobot(final JsonObject j, final String creater, final String orgi) throws Exception {
private JsonObject create(final JsonObject j, final String creater, final String orgi) throws Exception {
JsonObject resp = new JsonObject();
String snsid = null;
String workmode = null;
String clientId = null;
String secret = null;
if(!j.has("workmode"))
{
//System.out.println(j);
j.addProperty("workmode","机器人客服优先");
}
//System.out.println(j);
if ((!j.has("clientId")) || StringUtils.isBlank(j.get("clientId").getAsString())) {
resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_FAIL_3);
resp.addProperty(RestUtils.RESP_KEY_ERROR, "不合法的参数未传入【clientId】。");
@ -1092,7 +565,7 @@ public class ApiChatbotController extends Handler {
c.setCreatetime(dt);
c.setUpdatetime(dt);
c.setWorkmode(workmode);
c.setrobottype(j.get("robottype").getAsString());
// 默认不开启
boolean enabled = false;
c.setEnabled(enabled);
@ -1107,9 +580,9 @@ public class ApiChatbotController extends Handler {
consultInviteRes.save(invite);
OnlineUserProxy.cacheConsult(invite);
chatbotRes.save(c);
JsonObject data = new JsonObject();
data.addProperty("id", c.getId());
data.addProperty("robottype", c.getrobottype());
resp.add(RestUtils.RESP_KEY_DATA, data);
resp.addProperty(RestUtils.RESP_KEY_RC, RestUtils.RESP_RC_SUCC);
return resp;

View File

@ -20,5 +20,4 @@ public class ChatbotConstants {
public static final String THRESHOLD_FAQ_BEST_REPLY = "BOT_THRESHOLD_FAQ_BEST_REPLY";
public static final String THRESHOLD_FAQ_SUGG_REPLY = "BOT_THRESHOLD_FAQ_SUGG_REPLY";
public static final String DEFAULT_BOT_PROVIDER = "https://bot.chatopera.com";
public static final String DEFAULT_TENCENTBOT_PROVIDER = "https://console.cloud.tencent.com/tbp";
}

View File

@ -67,205 +67,7 @@ public class ChatbotController extends Handler {
logger.info("[index] chatbot id {}", chatbotid);
ModelAndView view = request(super.createAppsTempletResponse("/apps/chatbot/index"));
String Orgi = super.getOrgi(request);
System.out.println(Orgi);
List<Chatbot> chatbots = chatbotRes.findByOrgi(Orgi);
Chatbot currentbot = null;
logger.info("[index] chatbot size {}", chatbots.size());
if (chatbots.size() > 0) {
view.addObject("chatbots", chatbots);
if (StringUtils.isNotBlank(chatbotid)) {
view.addObject("currentbotid", chatbotid);
boolean resolved = false;
for (final Chatbot b : chatbots) {
if (StringUtils.equals(b.getId(), chatbotid)) {
view.addObject("currentbot", b);
currentbot = b;
resolved = true;
break;
}
}
if (!resolved) {
// TODO 优化查到不到Bot的提示
throw new CSKefuException("Can not find target chatbot by id [" + chatbotid + "]");
}
} else {
currentbot = chatbots.get(0);
view.addObject("currentbotid", currentbot.getId());
view.addObject("currentbot", currentbot);
}
}
view.addObject("botServiecProvider", botServiecProvider);
// 增加当前bot的更多信息
if (currentbot != null) {
// 创建人
final User creator = userProxy.findOne(currentbot.getCreater());
if (creator != null) {
view.addObject("creatorname", creator.getUname());
}
// 隶属渠道
if (StringUtils.isNotBlank(currentbot.getSnsAccountIdentifier())) {
snsAccountRepository.findOneBySnsTypeAndSnsIdAndOrgi(
currentbot.getChannel(),
currentbot.getSnsAccountIdentifier(),
currentbot.getOrgi()).ifPresent(p -> {
view.addObject("snsAccountName", p.getName());
view.addObject("snsAccountId", p.getId());
});
}
}
return view;
}
@RequestMapping(value = "/cosin")
@Menu(type = "chatbot", subtype = "index", access = true)
public ModelAndView cosin(ModelMap map, HttpServletRequest request, @Valid final String chatbotid) throws CSKefuException {
logger.info("[index] chatbot id {}", chatbotid);
ModelAndView view = request(super.createAppsTempletResponse("/apps/chatbot/cosin"));
String Orgi = super.getOrgi(request);
System.out.println(Orgi);
List<Chatbot> chatbots = chatbotRes.findByOrgi(Orgi);
Chatbot currentbot = null;
logger.info("[index] chatbot size {}", chatbots.size());
if (chatbots.size() > 0) {
view.addObject("chatbots", chatbots);
if (StringUtils.isNotBlank(chatbotid)) {
view.addObject("currentbotid", chatbotid);
boolean resolved = false;
for (final Chatbot b : chatbots) {
if (StringUtils.equals(b.getId(), chatbotid)) {
view.addObject("currentbot", b);
currentbot = b;
resolved = true;
break;
}
}
if (!resolved) {
// TODO 优化查到不到Bot的提示
throw new CSKefuException("Can not find target chatbot by id [" + chatbotid + "]");
}
} else {
currentbot = chatbots.get(0);
view.addObject("currentbotid", currentbot.getId());
view.addObject("currentbot", currentbot);
}
}
view.addObject("botServiecProvider", botServiecProvider);
// 增加当前bot的更多信息
if (currentbot != null) {
// 创建人
final User creator = userProxy.findOne(currentbot.getCreater());
if (creator != null) {
view.addObject("creatorname", creator.getUname());
}
// 隶属渠道
if (StringUtils.isNotBlank(currentbot.getSnsAccountIdentifier())) {
snsAccountRepository.findOneBySnsTypeAndSnsIdAndOrgi(
currentbot.getChannel(),
currentbot.getSnsAccountIdentifier(),
currentbot.getOrgi()).ifPresent(p -> {
view.addObject("snsAccountName", p.getName());
view.addObject("snsAccountId", p.getId());
});
}
}
return view;
}
@RequestMapping(value = "/tencent")
@Menu(type = "chatbot", subtype = "index", access = true)
public ModelAndView tencent(ModelMap map, HttpServletRequest request, @Valid final String chatbotid) throws CSKefuException {
logger.info("[index] chatbot id {}", chatbotid);
ModelAndView view = request(super.createAppsTempletResponse("/apps/chatbot/tencent"));
String Orgi = super.getOrgi(request);
//System.out.println(Orgi);
List<Chatbot> chatbots = chatbotRes.findByOrgi(Orgi);
Chatbot currentbot = null;
logger.info("[index] chatbot size {}", chatbots.size());
if (chatbots.size() > 0) {
view.addObject("chatbots", chatbots);
if (StringUtils.isNotBlank(chatbotid)) {
view.addObject("currentbotid", chatbotid);
boolean resolved = false;
for (final Chatbot b : chatbots) {
if (StringUtils.equals(b.getId(), chatbotid)) {
view.addObject("currentbot", b);
currentbot = b;
resolved = true;
break;
}
}
if (!resolved) {
// TODO 优化查到不到Bot的提示
throw new CSKefuException("Can not find target chatbot by id [" + chatbotid + "]");
}
} else {
currentbot = chatbots.get(0);
view.addObject("currentbotid", currentbot.getId());
view.addObject("currentbot", currentbot);
}
}
view.addObject("botServiecProvider", botServiecProvider);
// 增加当前bot的更多信息
if (currentbot != null) {
// 创建人
final User creator = userProxy.findOne(currentbot.getCreater());
if (creator != null) {
view.addObject("creatorname", creator.getUname());
}
// 隶属渠道
if (StringUtils.isNotBlank(currentbot.getSnsAccountIdentifier())) {
snsAccountRepository.findOneBySnsTypeAndSnsIdAndOrgi(
currentbot.getChannel(),
currentbot.getSnsAccountIdentifier(),
currentbot.getOrgi()).ifPresent(p -> {
view.addObject("snsAccountName", p.getName());
view.addObject("snsAccountId", p.getId());
});
}
}
return view;
}
@RequestMapping(value = "/rasa")
@Menu(type = "chatbot", subtype = "index", access = true)
public ModelAndView RASA(ModelMap map, HttpServletRequest request, @Valid final String chatbotid) throws CSKefuException {
logger.info("[index] chatbot id {}", chatbotid);
ModelAndView view = request(super.createAppsTempletResponse("/apps/chatbot/rasa"));
String Orgi = super.getOrgi(request);
List<Chatbot> chatbots = chatbotRes.findByOrgi(Orgi);
List<Chatbot> chatbots = chatbotRes.findByOrgi(super.getOrgi(request));
Chatbot currentbot = null;

View File

@ -15,7 +15,6 @@
*/
package com.chatopera.cc.plugins.chatbot;
import com.chatopera.bot.exception.ChatbotException;
import com.chatopera.cc.acd.ACDServiceRouter;
import com.chatopera.cc.basic.Constants;
import com.chatopera.cc.basic.MainContext;
@ -45,7 +44,6 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import java.net.InetSocketAddress;
import java.net.MalformedURLException;
import java.util.Date;
public class ChatbotEventHandler {
@ -108,11 +106,55 @@ public class ChatbotEventHandler {
// send out welcome message
if (invite != null) {
Chatbot chatbot = getChatbotRes().findOne(invite.getAiid());
RobotsOnconnect(chatbot,client,invite);
com.chatopera.bot.sdk.Chatbot bot = new com.chatopera.bot.sdk.Chatbot(
chatbot.getClientId(), chatbot.getSecret(), chatbot.getBaseUrl());
JSONObject details = bot.details();
// 发送欢迎语
if (details.has("rc") &&
details.getInt("rc") == 0) {
ChatMessage welcome = new ChatMessage();
String welcomeTextMessage = details.getJSONObject("data").getString("welcome");
if (StringUtils.isNotBlank(welcomeTextMessage)) {
welcome.setCalltype(MainContext.CallType.OUT.toString());
welcome.setAppid(appid);
welcome.setOrgi(orgi);
welcome.setAiid(aiid);
welcome.setMessage(welcomeTextMessage);
welcome.setTouser(user);
welcome.setMsgtype(MainContext.MessageType.MESSAGE.toString());
welcome.setUserid(user);
welcome.setUsername(invite.getAiname());
welcome.setUpdatetime(System.currentTimeMillis());
client.sendEvent(MainContext.MessageType.MESSAGE.toString(), welcome);
}
// 发送常见问题列表
JSONObject faqhotresp = bot.conversation(user, "__faq_hot_list");
logger.info("faqhot {}", faqhotresp.toString());
if (faqhotresp.getInt("rc") == 0) {
JSONObject faqhotdata = faqhotresp.getJSONObject("data");
if ((!faqhotdata.getBoolean("logic_is_fallback")) &&
faqhotdata.has("string") &&
faqhotdata.has("params")) {
ChatMessage faqhotmsg = new ChatMessage();
faqhotmsg.setCalltype(MainContext.CallType.OUT.toString());
faqhotmsg.setAppid(appid);
faqhotmsg.setOrgi(orgi);
faqhotmsg.setAiid(aiid);
faqhotmsg.setMessage(faqhotdata.getString("string"));
faqhotmsg.setExpmsg(faqhotdata.getJSONArray("params").toString());
faqhotmsg.setTouser(user);
faqhotmsg.setMsgtype(MainContext.MessageType.MESSAGE.toString());
faqhotmsg.setUserid(user);
faqhotmsg.setUsername(invite.getAiname());
faqhotmsg.setUpdatetime(System.currentTimeMillis());
client.sendEvent(MainContext.MessageType.MESSAGE.toString(), faqhotmsg);
}
}
}
}
//System.out.println("aiid:"+aiid);
InetSocketAddress address = (InetSocketAddress) client.getRemoteAddress();
String ip = MainUtils.getIpAddr(client.getHandshakeData().getHttpHeaders(), address.getHostString());
OnlineUser onlineUser = getOnlineUserRes().findOne(user);
@ -183,76 +225,6 @@ public class ChatbotEventHandler {
}
}
public void RobotsOnconnect(Chatbot chatbot,SocketIOClient client,CousultInvite invite) throws ChatbotException, MalformedURLException {
String user = client.getHandshakeData().getSingleUrlParam("userid");
String nickname = client.getHandshakeData().getSingleUrlParam("nickname");
String orgi = client.getHandshakeData().getSingleUrlParam("orgi");
String session = MainUtils.getContextID(client.getHandshakeData().getSingleUrlParam("session"));
String appid = client.getHandshakeData().getSingleUrlParam("appid");
String aiid = client.getHandshakeData().getSingleUrlParam("aiid");
String RobotType = chatbot.getrobottype();
switch (RobotType) {
case "cosin":
com.chatopera.bot.sdk.Chatbot bot = new com.chatopera.bot.sdk.Chatbot(
chatbot.getClientId(), chatbot.getSecret(), chatbot.getBaseUrl());
JSONObject details = bot.details();
// 发送欢迎语
if (details.has("rc") &&
details.getInt("rc") == 0) {
ChatMessage welcome = new ChatMessage();
String welcomeTextMessage = details.getJSONObject("data").getString("welcome");
if (StringUtils.isNotBlank(welcomeTextMessage)) {
welcome.setCalltype(MainContext.CallType.OUT.toString());
welcome.setAppid(appid);
welcome.setOrgi(orgi);
welcome.setAiid(aiid);
welcome.setMessage(welcomeTextMessage);
welcome.setTouser(user);
welcome.setMsgtype(MainContext.MessageType.MESSAGE.toString());
welcome.setUserid(user);
welcome.setUsername(invite.getAiname());
welcome.setUpdatetime(System.currentTimeMillis());
client.sendEvent(MainContext.MessageType.MESSAGE.toString(), welcome);
}
// 发送常见问题列表
JSONObject faqhotresp = bot.conversation(user, "__faq_hot_list");
logger.info("faqhot {}", faqhotresp.toString());
if (faqhotresp.getInt("rc") == 0) {
JSONObject faqhotdata = faqhotresp.getJSONObject("data");
if ((!faqhotdata.getBoolean("logic_is_fallback")) &&
faqhotdata.has("string") &&
faqhotdata.has("params")) {
ChatMessage faqhotmsg = new ChatMessage();
faqhotmsg.setCalltype(MainContext.CallType.OUT.toString());
faqhotmsg.setAppid(appid);
faqhotmsg.setOrgi(orgi);
faqhotmsg.setAiid(aiid);
faqhotmsg.setMessage(faqhotdata.getString("string"));
faqhotmsg.setExpmsg(faqhotdata.getJSONArray("params").toString());
faqhotmsg.setTouser(user);
faqhotmsg.setMsgtype(MainContext.MessageType.MESSAGE.toString());
faqhotmsg.setUserid(user);
faqhotmsg.setUsername(invite.getAiname());
faqhotmsg.setUpdatetime(System.currentTimeMillis());
client.sendEvent(MainContext.MessageType.MESSAGE.toString(), faqhotmsg);
}
}
}
break;
case "tencent":
System.out.println("腾讯");
break;
case "rasa":
System.out.println("rasa");
break;
}
}
// 添加 @OnDisconnect 事件客户端断开连接时调用刷新客户端信息
@OnDisconnect
public void onDisconnect(SocketIOClient client) {

View File

@ -27,17 +27,6 @@ import com.chatopera.cc.persistence.repository.ChatbotRepository;
import com.chatopera.cc.socketio.message.ChatMessage;
import com.chatopera.cc.util.SerializeUtil;
import com.chatopera.cc.util.SystemEnvHelper;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.tencentcloudapi.tbp.v20190627.models.Group;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
@ -47,19 +36,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.tbp.v20190627.TbpClient;
import com.tencentcloudapi.tbp.v20190627.models.TextProcessRequest;
import com.tencentcloudapi.tbp.v20190627.models.TextProcessResponse;
/**
* 发送消息给聊天机器人并处理返回结果
@ -82,10 +59,10 @@ public class ChatbotEventSubscription {
ChatbotConstants.BOT_PROVIDER, ChatbotConstants.DEFAULT_BOT_PROVIDER);
// FAQ最佳回复阀值
private final static double thresholdFaqBestReply = Double.parseDouble(SystemEnvHelper.getenv(
private final static double faqBestReplyThreshold = Double.parseDouble(SystemEnvHelper.getenv(
ChatbotConstants.THRESHOLD_FAQ_BEST_REPLY, "0.8"));
// FAQ建议回复阀值
private final static double thresholdFaqSuggReply = Double.parseDouble(SystemEnvHelper.getenv(
private final static double faqSuggReplyThreshold = Double.parseDouble(SystemEnvHelper.getenv(
ChatbotConstants.THRESHOLD_FAQ_SUGG_REPLY, "0.6"));
@Autowired
@ -98,9 +75,7 @@ public class ChatbotEventSubscription {
*/
@JmsListener(destination = Constants.INSTANT_MESSAGING_MQ_QUEUE_CHATBOT, containerFactory = "jmsListenerContainerQueue")
public void onMessage(final String payload) {
System.out.println(payload);
ChatMessage message = SerializeUtil.deserialize(payload);
System.out.println("Hello chat began");
try {
chat(message);
} catch (MalformedURLException e) {
@ -112,197 +87,18 @@ public class ChatbotEventSubscription {
private void chat(final ChatMessage request) throws MalformedURLException, ChatbotException, JSONException {
Chatbot c = chatbotRes.findOne(request.getAiid());
//System.out.println(c);
//System.out.println(request);
logger.info("[chat] chat request request baseUrl {},RobotType {}, chatbot {}, fromUserId {}, textMessage {}", botServiecProvider,c.getrobottype(), c.getName(), request.getUserid(), request.getMessage());
Chatbot c = chatbotRes
.findOne(request.getAiid());
logger.info(
"[chat] chat request baseUrl {}, chatbot {}, fromUserId {}, textMessage {}", botServiecProvider,
c.getName(),
request.getUserid(), request.getMessage());
// Get response from Conversational Engine.
String RobotType = c.getrobottype();
switch (RobotType) {
case "cosin":
CosinChat(c,request);
break;
case "tencent":
//System.out.println("腾讯");
TencentChat(c,request);
break;
case "rasa":
//System.out.println("RASA");
rasaChat(c,request);
break;
}
}
private void rasaChat(Chatbot c,ChatMessage request)
{
String BotUrl = c.getBaseUrl();
JsonObject result = new JsonObject();
CloseableHttpClient httpClient = HttpClients.createDefault();
try {
URIBuilder uriBuilder = new URIBuilder(BotUrl);
uriBuilder.setParameter("content",request.getMessage());
HttpGet httpGet = new HttpGet(uriBuilder.build());
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(5000) //连接超时时间
.setConnectionRequestTimeout(5000) //请求超时时间
.setSocketTimeout(5000) //socket读写超时时间
.setRedirectsEnabled(true) //是否允许重定向
.build();
httpGet.setConfig(requestConfig);
CloseableHttpResponse response = null;
response = httpClient.execute(httpGet);
System.out.println(response);
if (response.getStatusLine().getStatusCode() == 200) {
String content = EntityUtils.toString(response.getEntity(), "utf8");
JsonArray tempArray = new JsonParser().parse(content).getAsJsonArray();
result = tempArray.get(0).getAsJsonObject();
//System.out.println(result);
}
//请求内容
} catch (IOException e) {
e.printStackTrace();
} catch (URISyntaxException e) {
e.printStackTrace();
}
// parse response
if (result != null) {
logger.info("[chat] chat response {}", result.toString());
if (result.size()>0) {
// reply
//System.out.println(result.toString());
JSONObject data = new JSONObject(result.toString());
if (data != null) {
ChatMessage resp = new ChatMessage();
resp.setCalltype(MainContext.CallType.OUT.toString());
resp.setAppid(resp.getAppid());
resp.setOrgi(request.getOrgi());
resp.setAiid(request.getAiid());
resp.setMessage(result.get("text").getAsString());
if (data.has("logic_is_fallback"))
{
if (data.getBoolean("logic_is_fallback")) {
// 兜底回复检查FAQ
JSONArray faqReplies = data.getJSONArray("faq");
JSONArray suggs = new JSONArray();
for (int i = 0; i < faqReplies.length(); i++) {
JSONObject sugg = new JSONObject();
JSONObject faqReply = faqReplies.getJSONObject(i);
sugg.put("label", Integer.toString(i + 1) + ". " + faqReply.getString("post"));
sugg.put("text", faqReply.getString("post"));
sugg.put("type", "qlist");
suggs.put(sugg);
}
if (suggs.length() > 0) {
// TODO set help message on View Page
resp.setMessage("为您找到如下信息:");
resp.setExpmsg(suggs.toString());
}
} else if (data.has("params")) {
resp.setExpmsg(data.get("params").toString());
}
}
resp.setTouser(request.getUserid());
resp.setAgentserviceid(request.getAgentserviceid());
resp.setMsgtype(request.getMsgtype());
resp.setUserid(request.getUserid());
resp.setType(request.getType());
resp.setChannel(request.getChannel());
resp.setContextid(request.getContextid());
resp.setSessionid(request.getSessionid());
resp.setUsession(request.getUsession());
resp.setUsername(c.getName());
resp.setUpdatetime(System.currentTimeMillis());
// 更新聊天机器人累计值
updateAgentUserWithRespData(request.getUserid(), request.getOrgi(), data);
// 保存并发送
System.out.println("resp");
System.out.println(resp);
chatbotProxy.saveAndPublish(resp);
}
} else {
logger.warn("[chat] can not get expected response {}", result.toString());
}
}
}
private void TencentChat(Chatbot c,ChatMessage request){
try{
Credential cred = new Credential("AKID7yYrvk4adQx0nXHY7WfbbK1Sv84kAON5", "ZSmv33wYu0pLf162nHVSDiAMPgjW7tP9");
HttpProfile httpProfile = new HttpProfile();
httpProfile.setEndpoint("tbp.tencentcloudapi.com");
ClientProfile clientProfile = new ClientProfile();
clientProfile.setHttpProfile(httpProfile);
TbpClient client = new TbpClient(cred, "", clientProfile);
String BotId = c.getBotId();
String BotEnv = c.getBotEnv();
String TerminalId = c.getTerminalId();
String InputText = request.getMessage();
String params = "{" +
"\"BotId\":\""+BotId+"\"," +
"\"BotEnv\":\""+BotEnv+"\"," +
"\"TerminalId\":\""+TerminalId+"\"," +
"\"InputText\":\""+InputText+"\" }";
System.out.println(params);
TextProcessRequest req = TextProcessRequest.fromJsonString(params, TextProcessRequest.class);
TextProcessResponse respout = client.TextProcess(req);
//System.out.println(TextProcessResponse.toJsonString(respout));
ChatMessage resp = new ChatMessage();
resp.setCalltype(MainContext.CallType.OUT.toString());
resp.setAppid(resp.getAppid());
resp.setOrgi(request.getOrgi());
resp.setAiid(request.getAiid());
Group[] ResResult = respout.getResponseMessage().getGroupList();
if (ResResult.length==1)
{
resp.setMessage(ResResult[0].getContent());
}
resp.setTouser(request.getUserid());
resp.setAgentserviceid(request.getAgentserviceid());
resp.setMsgtype(request.getMsgtype());
resp.setUserid(request.getUserid());
resp.setType(request.getType());
resp.setChannel(request.getChannel());
resp.setContextid(request.getContextid());
resp.setSessionid(request.getSessionid());
resp.setUsession(request.getUsession());
resp.setUsername(c.getName());
resp.setUpdatetime(System.currentTimeMillis());
System.out.println(TextProcessResponse.toJsonString(respout));
JSONObject resObject = new JSONObject(TextProcessResponse.toJsonString(respout));
// 更新聊天机器人累计值
updateAgentUserWithRespData(request.getUserid(), request.getOrgi(), resObject);
// 保存并发送
chatbotProxy.saveAndPublish(resp);
} catch (TencentCloudSDKException e) {
System.out.println(e.toString());
}
}
private void CosinChat(Chatbot c,ChatMessage request) throws ChatbotException, MalformedURLException {
com.chatopera.bot.sdk.Chatbot bot = new com.chatopera.bot.sdk.Chatbot(
c.getClientId(), c.getSecret(), botServiecProvider);
JSONObject result = bot.conversation(
request.getUserid(), request.getMessage(), thresholdFaqBestReply, thresholdFaqSuggReply);
request.getUserid(), request.getMessage(), faqBestReplyThreshold, faqSuggReplyThreshold);
// parse response
if (result != null) {
@ -355,7 +151,6 @@ public class ChatbotEventSubscription {
// 更新聊天机器人累计值
updateAgentUserWithRespData(request.getUserid(), request.getOrgi(), data);
// 保存并发送
//System.out.println(resp);
chatbotProxy.saveAndPublish(resp);
}
} else {
@ -364,14 +159,11 @@ public class ChatbotEventSubscription {
}
}
/**
* 根据聊天机器人返回数据更新agentUser
*
* @param userid
* @param data
*
* 待修改 加入对腾讯对话机器人错误的兼容
*/
private void updateAgentUserWithRespData(final String userid, final String orgi, final JSONObject data) throws JSONException {
cache.findOneAgentUserByUserIdAndOrgi(userid, orgi).ifPresent(p -> {

View File

@ -1,315 +0,0 @@
<div class="layui-side layui-bg-black">
<div class="layui-side-scroll">
<#include "/apps/chatbot/include/left.html">
</div>
</div>
<div class="layui-body">
<#if currentbotid??>
<div class="row">
<div class="col-lg-12">
<h1 class="site-h1 ukefu-tab" style="border-top:1px solid #e6e6e6;height:26px;">
<span class="ukefu-bt">
<div class="ukefu-bt-text">
<div class="ukefu-bt-text-title">
春松客服智能机器人
</div>
</div>
</span>
<!-- 按钮组件 -->
<div class="ukefu-bt-text-content" style="position: absolute;right: 5px;top: 0px;">
<div class="layui-btn-group ukefu-btn-group">
<button class="layui-btn layui-btn-small" onclick="showChatbotEditDialogue('${currentbotid}')">
<i class="layui-icon">&#xe643;</i> 绑定
</button>
<button class="layui-btn layui-btn-small" onclick="openChatbotBotPlatform('${currentbot.clientId}')">
<i class="layui-icon">&#xe631;</i> 配置
</button>
<button class="layui-btn layui-btn-small" onclick="showChatbotCreateDialogue()">
<i class="layui-icon">&#xe654;</i> 新建
</button>
<button class="layui-btn layui-btn-danger layui-btn-small" onclick="showChatbotDeleteDialogue()">
<i class="layui-icon">&#xe640;</i> 删除
</button>
<button class="layui-btn layui-btn-warm layui-btn-small" onclick="openChatbotIntegrationInfoCenter()">
<i class="layui-icon">&#xe60a;</i> 文档中心
</button>
</div>
</div>
</h1>
</div>
</div>
<!-- 提示 -->
<div class="row" style="padding-left:5px;">
<div class="row">
<blockquote class="layui-elem-quote">
<p>智能机器人用于在访客端实现机器人客服,具体使用参考文档中心<a href="https://docs.chatopera.com/products/cskefu/work-chatbot.html" target="_blank">《春松客服机器人客服》</a>
</p>
</blockquote>
</div>
</div>
<!-- 工作状态 -->
<div class="row" style="padding:5px;">
<div class="col-lg-12">
<fieldset class="layui-elem-field layui-field-title">
<legend>智能客服</legend>
<div class="layui-field-box">
<blockquote class="layui-elem-quote layui-quote-nm">
<p>在开启状态下,在访客端可以看到<b>智能客服</b>对话窗口并与机器人客服对话。</p>
</blockquote>
<form class="layui-form" action="">
<div class="layui-form-item">
<div class="layui-input-block">
<input type="checkbox" lay-filter="bot-workstatus" name="switch" lay-skin="switch" lay-text="启用|禁用" <#if currentbot.enabled>checked</#if>>
</div>
</div>
</form>
</div>
<legend>知识库建议</legend>
<div class="layui-field-box">
<blockquote class="layui-elem-quote layui-quote-nm">
<p>知识库建议包括<b>知识库联想</b><b>知识库快捷</b><b>知识库联想</b>:当坐席与访客进行对话过程中,坐席输入消息时是否得到机器人的建议回复;<b>知识库快捷</b>:当坐席与访客进行对话过程中,坐席收到访客的消息时是否得到机器人的建议回复。</p>
</blockquote>
<form class="layui-form" action="">
<div class="layui-form-item">
<div class="layui-input-block">
<input type="checkbox" lay-filter="bot-aisuggest" name="bot-aisuggest" lay-skin="switch" lay-text="启用|禁用" <#if currentbot.aisuggest>checked</#if>>
</div>
</div>
</form>
</div>
</fieldset>
</div>
</div>
<!-- 绑定 -->
<div class="row" style="padding-left:5px;">
<div class="col-lg-12">
<fieldset class="layui-elem-field layui-field-title">
<legend>绑定</legend>
<div class="layui-field-box">
<blockquote class="layui-elem-quote layui-quote-nm">
<p>以下信息为春松客服使用该智能机器人集成的信息,去<a href="javascript:void(0)" onclick="showChatbotEditDialogue('${currentbotid}')">设置</a></p>
</blockquote>
<table class="layui-table" lay-even lay-skin="nob">
<colgroup>
<col width="150">
<col width="200">
<col width="400">
</colgroup>
<tbody>
<tr>
<td>渠道</td>
<td>
<#if currentbot.channel == "webim">
网站
<#elseif currentbot.channel == "skype">
Skype
<#elseif currentbot.channel == "callout">
外呼
<#else>
未知渠道类型
</#if>
</td>
<td><p style="color: #9C9C9C">访客接入的方式</p></td>
</tr>
<tr>
<td>渠道名称</td>
<td>${snsAccountName!""}</td>
<td><p style="color: #9C9C9C">限定了智能机器人出现的渠道标识。</p></td>
</tr>
<tr>
<td>创建人</td>
<td>${creatorname!"未知"}</td>
<td><p style="color: #9C9C9C">创建人初次设定了智能机器人。</p></td>
</tr>
<tr>
<td>工作模式</td>
<td>
${currentbot.workmode}
</td>
<td><p style="color: #9C9C9C">工作模式有"机器人优先""人工坐席优先"和"仅机器人客服"三种,这决定了访客连线后默认对接的方式。</p></td>
</tr>
</tbody>
</table>
</div>
</fieldset>
</div>
</div>
<!-- 配置 -->
<div class="row" style="padding:5px;">
<div class="col-lg-12">
<fieldset class="layui-elem-field layui-field-title">
<legend>配置</legend>
<div class="layui-field-box">
<blockquote class="layui-elem-quote layui-quote-nm">
<p><a href="javascript:void(0)" onclick="openChatbotBotPlatform('${currentbot.clientId}')">进入Chatopera云服务</a>设置以下信息及知识库、多轮对话、意图识别、使用情况分析和对话历史等信息。</p>
</blockquote>
<table class="layui-table" lay-even lay-skin="nob">
<colgroup>
<col width="150">
<col width="200">
<col width="300">
</colgroup>
<tbody>
<tr>
<td>描述</td>
<td>${currentbot.description}</td>
<td><p style="color: #9C9C9C">智能机器人的描述,侧重于业务,访客不会看到该信息。</p></td>
</tr>
<tr>
<td>欢迎语</td>
<td>${currentbot.welcome}</td>
<td><p style="color: #9C9C9C">与访客建立连接后,智能机器人发送的打招呼信息。</p></td>
</tr>
<tr>
<td>兜底回复</td>
<td>${currentbot.fallback}</td>
<td><p style="color: #9C9C9C">当智能机器人不清楚如何回复时的回复。</p></td>
</tr>
</tbody>
</table>
</div>
</fieldset>
</div>
</div>
<#else>
<div class="row">
<div class="col-lg-12">
<h1 class="site-h1 ukefu-tab" style="border-top:1px solid #e6e6e6;height:26px;">
<span class="ukefu-bt">
<div class="ukefu-bt-text">
<div class="ukefu-bt-text-title">
智能机器人
</div>
</div>
</span>
<!-- 按钮组件 -->
<div class="ukefu-bt-text-content" style="position: absolute;right: 5px;top: 0px;">
<div class="layui-btn-group ukefu-btn-group">
<button class="layui-btn layui-btn-small" onclick="showChatbotCreateDialogue()">
<i class="layui-icon">&#xe654;</i> 新建
</button>
<button class="layui-btn layui-btn-small" onclick="openChatbotBotPlatform()">
<i class="csfont">&#xe602;</i> 登录Chatopera云服务
</button>
<button class="layui-btn layui-btn-warm layui-btn-small" onclick="openChatbotIntegrationInfoCenter()">
<i class="layui-icon">&#xe60a;</i> 文档中心
</button>
</div>
</div>
</h1>
</div>
</div>
<div class="row" style="padding:5px;">
<div class="col-lg-12">
还没有智能机器人,<a href="javascript:void(0)" onclick="showChatbotCreateDialogue()">现在去创建!</a>
</div>
</div>
</#if>
</div>
<script>
// 打开文档中心
function openChatbotIntegrationInfoCenter(){
window.open("https://docs.chatopera.com/products/cskefu/work-chatbot.html", "_blank");
}
// 展示编辑机器人的窗口
function showChatbotEditDialogue(chatbotid) {
console.log("showChatbotEditDialogue", chatbotid);
layer.open({
title: '编辑智能机器人',
type: 2,
area: ['800px', '450px'],
content: 'edit.html?id=' + chatbotid
})
}
// 展示创建机器人的对话框
function showChatbotCreateDialogue() {
layer.open({
title: '集成智能机器人',
type: 2,
area: ['800px', '450px'],
content: 'edit.html'
})
}
// 删除机器人
function showChatbotDeleteDialogue() {
var lindex = layer.confirm('请确认是否删除?', {
btn: ['确认', '删除']
}, function () {
return restApiRequest({
path: "chatbot",
data: {
ops: 'delete',
id: '${currentbotid}'
}
}).then(function (result) {
// 刷新页面
layer.close(lindex);
setTimeout(function () {
location.href = "/apps/chatbot/index.html";
}, 300);
}, function (reason) {
// TODO 提示错误
console.log("[ChatbotDelete] error: ", reason);
layer.close(lindex);
});
}, function () {
layer.close(lindex);
});
}
// 打开机器人管理地址
function openChatbotBotPlatform(chatbotid){
var botMgrUrl = "${botServiecProvider}";
if(chatbotid){
botMgrUrl = "${botServiecProvider}/dashboard/clients/"+chatbotid+"/control-center";
}
window.open(botMgrUrl, "_blank");
}
// 设置机器人工作状态
function setChatbotWorkstatus(id, workstatus){
restApiRequest({
path: "chatbot",
silent: true,
data: {
ops: workstatus?"enable":"disable",
id: id
}
});
}
function setChatbotAiSuggest(id, aisuggest){
restApiRequest({
path: "chatbot",
silent: true,
data: {
ops: aisuggest?"enableAiSuggest":"disableAiSuggest",
id: id
}
});
}
layui.use(['form'], function(){
var form = layui.form();
form.render();
form.on('switch(bot-workstatus)', function (data) {
setChatbotWorkstatus('${currentbotid}', data.elem.checked);
});
form.on('switch(bot-aisuggest)', function (data) {
setChatbotAiSuggest('${currentbotid}', data.elem.checked);
});
});
</script>

View File

@ -1,4 +1,4 @@
<script src="/js/utils.js"></script>
<script src="/js/CSKeFu_Rest_Request.v1.js"></script>
<style>
#create {
@ -11,203 +11,68 @@
width: 400px;
}
</style>
<link rel="stylesheet" href="/layui/css/layui.css">
<div class="row">
<div class="col-lg-12">
<div id="create">
<div class="layui-tab" lay-filter="robottype">
<ul class="layui-tab-title" >
<li class="layui-this">春松客服</li>
<li>腾讯智能对话</li>
<li>Rasa NLU</li>
</ul>
<div class="layui-tab-content">
<div class="layui-tab-item layui-show">
<form class="layui-form uk-form" style="width: 700px;margin: auto;">
<input id="id" type="hidden" name="id" value="${id}">
<div class="layui-form-item">
<label class="layui-form-label">网站渠道</label>
<div class="layui-input-inline">
<#if id!=null>
<input type="text" name="snsurl" required lay-verify="required" value="${snsurl}"
autocomplete="off" class="layui-input" disabled>
<#else>
<select id="snsid" name="snsid" lay-verify="required">
<option></option>
</select>
</#if>
</div>
<div class="layui-form-mid layui-word-aux">智能机器人服务的渠道标识</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">ClientId</label>
<div class="layui-input-inline">
<input type="text" name="clientId" required lay-verify="required" placeholder="请输入ClientId" autocomplete="off"
class="layui-input" value="${bot.clientId}">
</div>
<div class="layui-form-mid layui-word-aux">智能机器人ClientId.<a href="${botServiecProvider}/dashboard" target="_blank">春松客服创建!</a></div>
</div>
<div class="layui-form-item" id="secret" style="display:" >
<label class="layui-form-label">Secret</label>
<div class="layui-input-inline">
<input type="password" name="secret" required lay-verify="required" placeholder="请输入Secret" autocomplete="off"
class="layui-input" value="${bot.secret}">
</div>
<div class="layui-form-mid layui-word-aux">智能机器人Secret</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">工作模式</label>
<div class="layui-input-inline">
<select name="workmode" lay-verify="required">
<option <#if bot.workmode=="机器人客服优先">selected="selected"</#if>>机器人客服优先</option>
<option <#if bot.workmode=="人工客服优先"></#if>>人工客服优先</option>
<option <#if bot.workmode=="仅机器人客服"></#if>>仅机器人客服</option>
</select>
</div>
<div class="layui-form-mid layui-word-aux">来自访客的会话默认以什么方式接待</div>
</div>
<div class="layui-form-item">
<div class="layui-input-inline">
<button class="layui-btn" lay-submit lay-filter="save">保存</button>
</div>
</div>
</form>
</div>
<div class="layui-tab-item">
<form class="layui-form uk-form" style="width: 700px;margin: auto;">
<input id="id-Tencent" type="hidden" name="id-Tencent" value="${id}">
<div class="layui-form-item">
<label class="layui-form-label">网站渠道</label>
<div class="layui-input-inline">
<#if id!=null>
<input type="text" name="snsurl" required lay-verify="required" value="${snsurl}"
autocomplete="off" class="layui-input" disabled>
<#else>
<select id="snsid-Tencent" name="snsid" lay-verify="required">
<option></option>
</select>
</#if>
</div>
<div class="layui-form-mid layui-word-aux">智能机器人服务的渠道标识</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">BotId</label>
<div class="layui-input-inline">
<input type="text" name="BotId" required lay-verify="required" placeholder="请输入BotId" autocomplete="off"
class="layui-input" value="${bot.BotId }">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">SecretId</label>
<div class="layui-input-inline">
<input type="text" name="SecretId" required lay-verify="required" placeholder="请输入SecretId" autocomplete="off"
class="layui-input" value="${bot.SecretId}">
</div>
</div>
<div class="layui-form-item" id="secretkey" >
<label class="layui-form-label">SecretKey</label>
<div class="layui-input-inline">
<input type="password" name="SecretKey" required lay-verify="required" placeholder="请输入Secretkey" autocomplete="off"
class="layui-input" value="${bot.secretkey}">
</div>
<div class="layui-form-mid layui-word-aux">智能机器人Secret</div>
</div>
<div class="layui-form-item" id="BotEnv" >
<label class="layui-form-label">BotEnv</label>
<div class="layui-input-inline">
<select name="BotEnv" lay-verify="">
<option value="dev">调试版本</option>
<option value="release">线上版本</option>
</select>
</div>
<div class="layui-form-mid layui-word-aux">调试/线上 版本</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">TerminalId</label>
<div class="layui-input-inline">
<input type="text" name="TerminalId" required lay-verify="required" placeholder="请输入TerminalId" autocomplete="off"
class="layui-input" value="${bot.TerminalId }">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-inline">
<button class="layui-btn" lay-submit lay-filter="save">保存</button>
</div>
</div>
</form>
<form class="layui-form uk-form" style="width: 700px;margin: auto;">
<input id="id" type="hidden" name="id" value="${id}">
<div class="layui-form-item">
<label class="layui-form-label">网站渠道</label>
<div class="layui-input-inline">
<#if id!=null>
<input type="text" name="snsurl" required lay-verify="required" value="${snsurl}"
autocomplete="off" class="layui-input" disabled>
<#else>
<select id="snsid" name="snsid" lay-verify="required">
<option></option>
</select>
</#if>
</div>
<div class="layui-tab-item">
<form class="layui-form uk-form" style="width: 700px;margin: auto;">
<div class="layui-form-item">
<input id="id" type="hidden" name="id" value="${id}">
<div class="layui-form-item">
<label class="layui-form-label">网站渠道</label>
<div class="layui-input-inline">
<#if id!=null>
<input type="text" name="snsurl" required lay-verify="required" value="${snsurl}"
autocomplete="off" class="layui-input" disabled>
<#else>
<select id="snsid-RASA" name="snsid" lay-verify="required">
<option></option>
</select>
</#if>
</div>
<div class="layui-form-mid layui-word-aux">智能机器人服务的渠道网址</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">RASA-ID</label>
<div class="layui-input-inline">
<input type="text" name="BotId" required lay-verify="required"
placeholder="请输入RASA ID" autocomplete="off"
class="layui-input" value="${bot.BotId }">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">RASA-Url</label>
<div class="layui-input-inline">
<input type="text" name="BotUrl" required lay-verify="required"
placeholder="请输入RASA URL" autocomplete="off"
class="layui-input" value="${bot.BotUrl }">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">RASA Secret</label>
<div class="layui-input-inline">
<input type="text" name="SecretId" required lay-verify="required" placeholder="请输入RASA Secret" autocomplete="off"
class="layui-input" value="${bot.SecretId}">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-inline">
<button class="layui-btn" lay-submit lay-filter="save">保存</button>
</div>
</div>
</form>
<div class="layui-form-mid layui-word-aux">智能机器人服务的渠道标识</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">ClientId</label>
<div class="layui-input-inline">
<input type="text" name="clientId" required lay-verify="required" placeholder="请输入ClientId" autocomplete="off"
class="layui-input" value="${bot.clientId}">
</div>
<div class="layui-form-mid layui-word-aux">智能机器人ClientId还没有<a href="${botServiecProvider}/dashboard" target="_blank">现在去创建!</a></div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">Secret</label>
<div class="layui-input-inline">
<input type="password" name="secret" required lay-verify="required" placeholder="请输入Secret" autocomplete="off"
class="layui-input" value="${bot.secret}">
</div>
</div>
<div class="layui-form-mid layui-word-aux">智能机器人Secret</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">工作模式</label>
<div class="layui-input-inline">
<select name="workmode" lay-verify="required">
<option <#if bot.workmode=="机器人客服优先">selected="selected"</#if>>机器人客服优先</option>
<option <#if bot.workmode=="人工客服优先">selected="selected"</#if>>人工客服优先</option>
<option <#if bot.workmode=="仅机器人客服">selected="selected"</#if>>仅机器人客服</option>
</select>
</div>
<div class="layui-form-mid layui-word-aux">来自访客的会话默认以什么方式接待</div>
</div>
<div class="layui-form-item">
<div class="layui-input-inline">
<button class="layui-btn" lay-submit lay-filter="save">保存</button>
</div>
</div>
</form>
</div>
</div>
</div>
<script>
layui.use(['form', 'upload','code'], function(){ //加载code模块
var form = layui.form()
,upload = layui.upload;
layui.code(); //引用code方法
});
// 保存成功,刷新页面
function submitChatbotSucc(bot) {
if(bot.rc != 0){
submitChatbotFail(bot);
} else {
parent.location.href = "/apps/chatbot/"+bot.data.robottype+".html?chatbotid="+bot.data.id;
parent.location.href = "/apps/chatbot/index.html?chatbotid="+bot.data.id;
}
}
@ -223,54 +88,11 @@
// 取消方法
});
}
layui.use('element', function(){
var element = layui.element();
element.on('tab(robottype)', function(data){
console.log(data);
});
});
layui.use(['element','form'], function () {
var $=layui.jquery,element = layui.element();
var type = "cosin"
element.on('tab(robottype)', function(data){
switch (data.index) {
case 0:
type = "cosin"
break;
case 1:
type = "tencent"
//console.log(type)
break;
case 2:
type = "rasa"
break;
default:
}
//console.log(type)
});
layui.use(['form'], function () {
var form = layui.form();
form.on('submit(save)', function (data) {
//if (typeof type == "undefined"){type = 'cosin'}
//console.log(type)
switch (type) {
case 'cosin':
data.field.robottype='cosin';
break;
case 'tencent':
data.field.robottype='tencent';
break;
case 'rasa':
data.field.robottype='rasa';
break;
default:
}
var field = data.field;
//console.log(field);
if (field.id) {
field.ops = 'update';
restApiRequest({
@ -279,9 +101,7 @@
data: field
}).then(submitChatbotSucc, submitChatbotFail);
} else {
console.log(field);
field.ops = 'create';
restApiRequest({
path: "chatbot",
data: field
@ -290,7 +110,7 @@
return false;
});
if ((!$('#id').val())||(!$('#id-Tencent').val())) {
if (!$('#id').val()) {
restApiRequest({
path: "chatbot",
silent: true,
@ -304,8 +124,6 @@
});
$('#snsid').html(options);
$('#snsid-Tencent').html(options);
$('#snsid-RASA').html(options);
form.render('select');
}
}, function(error){

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,2 +0,0 @@
/** layui-v2.5.6 MIT License By https://www.layui.com */
html #layuicss-skincodecss{display:none;position:absolute;width:1989px}.layui-code-h3,.layui-code-view{position:relative;font-size:12px}.layui-code-view{display:block;margin:10px 0;padding:0;border:1px solid #e2e2e2;border-left-width:6px;background-color:#F2F2F2;color:#333;font-family:Courier New}.layui-code-h3{padding:0 10px;height:32px;line-height:32px;border-bottom:1px solid #e2e2e2}.layui-code-h3 a{position:absolute;right:10px;top:0;color:#999}.layui-code-view .layui-code-ol{position:relative;overflow:auto}.layui-code-view .layui-code-ol li{position:relative;margin-left:45px;line-height:20px;padding:0 5px;border-left:1px solid #e2e2e2;list-style-type:decimal-leading-zero;*list-style-type:decimal;background-color:#fff}.layui-code-view pre{margin:0}.layui-code-notepad{border:1px solid #0C0C0C;border-left-color:#3F3F3F;background-color:#0C0C0C;color:#C2BE9E}.layui-code-notepad .layui-code-h3{border-bottom:none}.layui-code-notepad .layui-code-ol li{background-color:#3F3F3F;border-left:none}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 299 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 777 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Some files were not shown because too many files have changed in this diff Show More