ChatScript初始化机器人

发布 : 2017-07-21 分类 : ChatScript 浏览 :

CS目录结构

准备

  • filesxiaola.txt
  • BOTDATA/XIAOLA/simplecontrol.top
  • BOTDATA/XIAOLA/cmd.top
  • BOTDATA/KWDL/kwdl.top
  • bot_init.py
  • pychatscript.py[工具文件]

filesxiaola.txt

1
2
../BOTDATA/XIAOLA/
../BOTDATA/KWDL/

BOTDATA/XIAOLA/simplecontrol.top

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
# refer to ChatScript-Control-Scripts.html (above 7.53) for more info

# This is a BOT MACRO (bot definition scripts)
# the system must look for the outputmacro with botname
# this function is executed once for every new user chatting with xiaola
# inside the outputmacro, some basic $var is initialized.
outputmacro: xiaola()
# refer to doc and bot harry for more available cs_token
$cs_token = #DO_NUMBER_MERGE | #DO_DATE_MERGE | #DO_PROPERNAME_MERGE
$cs_control_main = ~xmain_control
$cs_control_post = ~xpost_control
$userprompt = ^"%user: >"
$botprompt = ^"xiaola: "

# table's name defaultbot is just for documentation convenience
# you can name the table whatever you want
# what make it special this the fact(defaultbot) it created inside
# defaultbot is a special fact CS looking when a bot is not given
# it find the defaultbot fact, and try to use its subject as defaultbot
# refer to https://www.chatbots.org/ai_zone/viewthread/2953/ post#3
# for a complete startup process. Other related discussion.
# https://www.chatbots.org/ai_zone/viewthread/2769/
# https://www.chatbots.org/ai_zone/viewthread/1708/
# when multibots are needed.
table: defaultbot (^name)
^createfact(^name defaultbot defaultbot)
DATA:
xiaola

topic: ~xmain_control system ()

# on startup, do introduction
u: ( %input<%userfirstline )
# gambit(~welcome)

# main per-sentence processing
u: ( )
# always pop ~plcmd if it is ever in the topic stack
# since it's useless at main_control part
^poptopic(~plcmd)

# get the current topic at start of volley
# %topic is system defined variable: name of the current "real" topic.
# refer to system defined variable doc for more info
$$currenttopic = %topic

# process any cmd to CS from platform first
if (%response == 0) { nofail(TOPIC ^respond(~cscmd)) }

# Try for rejoinders. might generate an answer directly
# Rejoinder is global, it does not matter which topic the input rejoinder
# is in. There is no such thing as "current topic's rejoinder"
if (%response == 0) { nofail(TOPIC ^rejoinder()) }

# rejoinder previously cached rule to emulate interruption
# if the rule tag does not have rejonders
# it does not hurt to just try out. So it does not hurt if $tag var
# is not reset when the selection process is done.
# system rejoinder always takes priority as above.
if (%response == 0 AND $tag_rejoinder_sl != null) {
^nofail(TOPIC ^rejoinder($tag_rejoinder_sl))
}

# try user defined topic right after rejoinder as it takes priority
# the following two topics are bot specific restricted.
if (%response == 0) { nofail(TOPIC ^respond(~kwwechat)) }
if (%response == 0) { nofail(TOPIC ^respond(~dluserdefined)) }

# current topic tries to respond to this input
if (%response == 0) { nofail(TOPIC ^respond($$currenttopic)) }

# gambit current topic since no input (usually start of conversation)
if (%length == 0 AND %response == 0 )
{ nofail(TOPIC ^gambit($$currenttopic)) }

# try some other topic with keywords matching input given no response yet
if (%response == 0)
{
# list topics and priority values for matching keywords in input.
# refer to manual for more details.
# it returns a fact-set, which can be labeled @0, @1, etc. through @20.
# we just pikc @8 to store this fact-set.
@8 = ^keywordtopics()
loop()
{
# ^first not only return the first but also remove it from the set
$$topic = ^first(@8subject)
nofail(TOPIC ^respond($$topic))
if (%response != 0)
{
# we are done, this terminates the loop (not the rule)
^end(RULE)
}
}
}

# if no topic reacts, loop keywordless topics in a carefully designed order
if (%response == 0) { nofail(TOPIC ^respond(~systemfixed)) }

if (%response == 0) { nofail(TOPIC ^respond(~introduction)) }

if (%response == 0) { nofail(TOPIC ^respond(~qababyformula)) }

if (%response == 0) { nofail(TOPIC ^respond(~qaguessbaby)) }

if (%response == 0) { nofail(TOPIC ^respond(~qababyfood)) }

# if we have rejoinders for what we said OR we asked a question, stop here
if (%outputrejoinder OR %lastquestion) { end(TOPIC) }

# gambit current topic since keywords match current topic
if (%response == 0 AND ^marked($$currenttopic))
{ nofail(TOPIC ^gambit($$currenttopic)) }

# gambit from ANY matching topic
if (%response == 0)
{
# get topics referred in input
@8 = ^keywordtopics()
loop()
{
$$topic = first(@8subject)
nofail(TOPIC ^Gambit($$topic)) # gambit in best matching topic
# stop when we find something
if (%response != 0) { ^end(RULE) }
}
}

# gambit from current topic even though no keywords matched
if (%response == 0) { nofail(TOPIC ^gambit($$currenttopic)) }

if (%response == 0)
{
# all topics with gambits (excluding system topics)
@8 = ^GambitTopics()
loop()
{
# retrieve a topic at random, and also remove it from the set
$$topic = ^pick(@8subject)
nofail(TOPIC ^gambit($$topic))
if (%response != 0) { ^end(RULE) }
}
}

# plcmd will definitely response.
# put it to a seperate non-system topic so that it's in the pending topics
# Then it could be correctly print before output by looking $currenttopic
if (%response == 0) { nofail(TOPIC ^respond(~plcmd)) }

topic: ~xpost_control system repeat keep()
# pre and post control scripts always invoked in gambit mode (hence t: rules)
t: ()
if (%topic == ~slbabyformula1) {
#({^responseruleid (-1)}) return all why part in log
# at this point ~slbabyformula is the first and only one output
# so the id is always 1
$tag_rejoinder_sl = ^responseruleid(1)
$$pos_end = -1
# this finds position right after .~, and we move forward 2 position
$$pos_end = ^nofail(RULE ^findtext($tag_rejoinder_sl .~ 0))
# not sure whether $$pos_end will be set to null when the rule fails
if ($$pos_end == null) {
# 25 shall be long enough to get the end of the rule tag
$tag_rejoinder_sl = ^extract($tag_rejoinder_sl 4 25)
^postprintafter (null)
}
else if ($$pos_end == -1) {
$tag_rejoinder_sl = ^extract($tag_rejoinder_sl 4 25)
^postprintafter (-1)
}
else {
# move back 2 pos so we find the end of the first rule tag
$$pos_end = $$pos_end - 2
# because the string start with Why:
# 4 is used to offset the string position
$tag_rejoinder_sl = ^extract($tag_rejoinder_sl 4 $$pos_end)
# ^postprintafter ($tag_rejoinder_sl)
}
}

^postprintbefore ({%topic})

BOTDATA/KWDL/kwdl.top

1
2
3
4
5
6
7
8
9
10
11
12
13
14
outputmacro: kwdl()
$cs_token = #DO_NUMBER_MERGE | #DO_DATE_MERGE | #DO_PROPERNAME_MERGE
$cs_control_main = ~xmain_control
$cs_control_post = ~xpost_control
$userprompt = ^"%user: >"
$botprompt = ^"kwdl: "

topic: ~kwwechat bot=kwdl keep repeat ()
u: (< kw >)
this is keyword.

topic: ~dluserdefined bot=kwdl keep repeat ()
u: (< dl >)
this is dialogue.

BOTDATA/XIAOLA/cmd.top

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
outputmacro: ^execute-print(^arg)
^arg \n

# PLCMD is the command from CS to platform to carry control info
topic: ~plcmd repeat keep ()
u: ()
PLCMD-NO-ANSWER-CS

# CSCMD is the command from platform to CS to carry control info
topic: ~cscmd repeat keep()
u: (CSCMD-REJOINDER-CLEAR)
# disable the system rejoinder only when it is the selection rejoinder
if (%inputrejoinder == $tag_rejoinder_sl) {
# disable input rejoinder shall be enough
# as result output rejoinder shall be gone as well
^disable(inputrejoinder)
}
$tag_rejoinder_sl = null
# the below response will cancle the system rejoinder as well
# so do not need explictly disable any inputrejoinder or outputrejoinder
CSCMD-REJOINDER-CLEAR is done.

u: (CSCMD-BOT-INIT _*)
^popen(^join("python ../bot_init.py "'_0) '^execute-print)

u: (CSCMD-BOT-INIT-TEST _*)
^popen(^join("python ../bot_init_test.py "'_0) '^execute-print)

u: (CSCMD-TEST-BOT-INIT _*)
[ Test ^join("python ../bot_init.py "'_0) ]

bot_init.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
#!/usr/bin/python
# -*- coding: utf-8 -*-
import os
import re
import sys
import json
import socket
import requests
import traceback
import urllib

argv = sys.argv

timeout = 3
socket.setdefaulttimeout(timeout)

regex = re.compile(
u'([\u2014\u00b0\u2103\u201c\u2264\u201d\u2265\u00B7\u3400-\u4DB5\u4E00-\u9FA5\u9FA6-\u9FBB\uF900-\uFA2D\uFA30-\uFA6A\uFA70-\uFAD9\uFF00-\uFFEF\u2E80-\u2EFF\u3000-\u303F\u31C0-\u31EF\u2F00-\u2FDF\u2FF0-\u2FFF\u3100-\u312F\u31A0-\u31BF\u3040-\u309F\u30A0-\u30FF\u31F0-\u31FF\uAC00-\uD7AF\u1100-\u11FF\u3130-\u318F\u4DC0-\u4DFF\uA000-\uA48F\uA490-\uA4CF\u2800-\u28FF\u3200-\u32FF\u3300-\u33FF\u2700-\u27BF\u2600-\u26FF\uFE10-\uFE1F\uFE30-\uFE4F])') # 匹配中文


def quote(data):
"""
将中文转为url编码
:param data: 要转的数据。格式可以是:dict,list,tuple,set,str
:return: 转换后的数据
"""
if isinstance(data, dict):
tmp_dict = {}
for k, v in data.items():
tmp_dict[k] = quote(v)
return tmp_dict
elif isinstance(data, list) or isinstance(data, tuple):
tmp_list = []
for d in data:
tmp_list.append(quote(d))
return tmp_list
elif isinstance(data, set):
tmp_set = set()
for s in data:
tmp_set.add(quote(s))
return tmp_set
elif isinstance(data, str):
lst = regex.findall(data)
for s in lst:
data = data.replace(s, urllib.parse.quote(s))
return data
else:
return data


def rpc(func, data={}):
"""
post方式请求数据
:param func: 远程调用的接口函数名
:param data: 远程调用传入的参数
:return:
"""
url = 'http://beta.api.xiaolabot.com/service/%s?token=123456' % func
try:
headers = {'Content-Type': 'application/json; encoding=utf-8'}
response = requests.post(
url,
data=json.dumps(data).encode('utf8'),
headers=headers,
timeout=timeout
)
response.encoding = 'utf8'
result = response.json()
return result
except socket.timeout:
return {'code': -3, 'data': [], 'msg': '请求接口超时:url=%s,data=%s' % (url, data)}
except:
return {'code': -1, 'data': [], 'msg': traceback.format_exc()}


def get(url):
"""
get方式请求数据
:param url:
:return:
"""
try:
response = requests.get(url)
response.encoding = 'utf8'
return response.json()
except socket.timeout:
return {'code': -3, 'data': [], 'msg': '请求接口超时:url=%s' % (url)}
except:
print(traceback.format_exc())
return {'code': -1, 'data': [], 'msg': traceback.format_exc()}


def post(url, data, _type='form'):
"""
post方式请求数据
:param url:
:param data:
:param _type: post类型(form:提交表单,json:提交json body)
:return:
"""
try:
if _type == 'form':
# 表单提交
req = urllib.request.Request(url, urllib.parse.urlencode(data).encode('utf8'))
response = urllib.request.urlopen(req)
response.encoding = 'utf8'
content = response.read().decode('utf8')
return json.loads(content)
elif _type == 'json':
# json body方式提交
headers = {'Content-Type': 'application/json; encoding=utf-8'}
response = requests.post(
url,
data=urllib.parse.unquote(json.dumps(quote(data))).encode('utf8'),
headers=headers,
timeout=timeout
)
response.encoding = 'utf8'
return response.json()
else:
return {'code': -2, 'data': [], 'msg': '不支持%s方式提交' % _type}
except socket.timeout:
return {'code': -3, 'data': [], 'msg': '请求接口超时:url=%s,_type=%s,data=%s' % (url, _type, data)}
except:
print(traceback.format_exc())
return {'code': -1, 'data': [], 'msg': traceback.format_exc()}


class InitCS(object):
def __init__(self, appid):
self.bot_info = rpc('get_bot_info', {'appid': appid}).get('data', {})
self.access_token = rpc('get_access_token', {'appid': appid}).get('access_token', '')

def split_str(self, s=''):
"""
分隔中文
:param s:
:return:
"""
return re.sub('\s+', ' ', regex.sub(r' \1 ', s))

def get_current_autoreply_info(self):
"""
获取公众号的自动回复规则
:return:
"""
url = 'https://api.weixin.qq.com/cgi-bin/get_current_autoreply_info?access_token=%s' % self.access_token
response = get(url)
if not response.get('keyword_autoreply_info'):
print(response)
return response.get('keyword_autoreply_info', {}).get('list', [])

def save_userdefine_to_cstopic(self):
"""
负责将数据库chat_user_ask、chat_robot_answer表中相同parent_id(会话列表)的ask、answer取出,并转换为cs Topic规则
:param bot_dir: 存储Topic的目录
:return:
"""
bid = self.bot_info.get('bid', 0)
# 会话类型:1:文本 2:图片 3:音频 4:视频
ask_type = 1
query_sql = """ SELECT a.bid,a.uid,a.ask_name,b.answer_name,a.parent_id FROM chatplus.chat_user_ask a JOIN chatplus.chat_robot_answer b
ON a.parent_id = b.parent_id
WHERE a.ask_type = %s
AND a.bid = %s
AND a.uid = b.uid;
""" % (ask_type, bid)
query_res = self.db_conn.execute(query_sql)

if not query_res:
print("%s 没有为 bid=%s 创建文本会话对" % (self.bot_info.get('nick_name', 0), bid))
else:
ask_dict = {}
answer_dict = {}
data_list = []
for data in query_res:
parent_id = 'parent_id:' + str(data.get('bid', '')) + ":" + str(data.get('uid', '')) + ":" + str(
data.get('parent_id', ''))
data_list.append(parent_id)
keys = set(data_list)

for key in keys:
ask_name_key = key + '|ask_name'
answer_name_key = key + '|answer_name'
ask_dict.update({ask_name_key: []})
answer_dict.update({answer_name_key: []})
# print(ask_dict)
# print(answer_dict)

for data in query_res:
for key in keys:
parent_id = 'parent_id:' + str(data.get('bid', '')) + ":" + str(data.get('uid', '')) + ":" + str(
data.get('parent_id', ''))
ask_name_key = key + '|ask_name'
answer_name_key = key + '|answer_name'
if key == parent_id:
ask_name = ask_dict[ask_name_key]
ask_name.append(data.get('ask_name', '').strip())

answer_name = answer_dict[answer_name_key]
answer_name.append(data.get('answer_name', ''))
ask_dict.update({ask_name_key: ask_name})
answer_dict.update({answer_name_key: answer_name})
# print(ask_dict)
# print(answer_dict)

topic_data = []
for ask in ask_dict:
for answer in answer_dict:
if ask.split('|')[0] == answer.split('|')[0]:
ask_str_list = []
for ask_strs in set(ask_dict[ask]):
if len(ask_strs) > 4:
ask_str = '( %s )' % self.split_str(ask_strs).strip()
ask_str_list.append(ask_str)
else:
ask_str = '"%s"' % self.split_str(ask_strs).strip()
ask_str_list.append(ask_str)
answer_str = '[%s]' % (']\n\t['.join(set(answer_dict[answer])))
topic_str = '\n\nu: ([' + ' '.join(ask_str_list) + '])' + '\r\n\t' + answer_str + '\r\n\n'
# print("topic_str:", topic_str)
topic_data.append(topic_str)
return topic_data

def save_wechatkeyword_to_cstopic(self):
"""
微信自动回复规则转换为cs Topic规则
:param user_bot_dir:
:return:
"""
keyword_list_info = self.get_current_autoreply_info()
if keyword_list_info:
str_list = []
for info in keyword_list_info:
rule_name = info.get('rule_name', [])
reply_mode = info.get('reply_mode', [])
keyword_list_info = info.get('keyword_list_info', [])
reply_list_info = info.get('reply_list_info', [])

keyword_list = []
for keyword in keyword_list_info:
match_mode = keyword.get('match_mode', '')
content = keyword.get('content', '')
type = keyword.get('type', '')
if type == 'text':
keyword_list.append(content + "|" + match_mode)

reply_list = []
news_list = []
for reply in reply_list_info:
content = reply.get('content', '')
type = reply.get('type', '')
if type == 'news':
news_info_list = reply.get('news_info', {}).get('list', [])
if news_info_list:
for news_info in news_info_list:
digest = news_info.get('digest', '')
title = news_info.get('title', '')
content_url = news_info.get('content_url', '')
reply_str = digest + " " + "<a href=" + content_url + ">" + title + "</a>"
news_list.append(reply_str.strip())
else:
news_list.append(content)
reply_list.append(' '.join(news_list))
else:
reply_list.append(content)

contain_list = []
equal_list = []
if reply_list:
for kw in set(keyword_list):
if not kw.split("|")[0].isdigit():
if len(kw.split("|")[0]) > 4:
match_keyword = '( %s )' % self.split_str(kw.split("|")[0]).strip()
if kw.split("|")[1] == 'contain':
contain_list.append(match_keyword)
else:
equal_list.append(match_keyword)
else:
match_keyword = '"%s"' % self.split_str(kw.split("|")[0]).strip()
if kw.split("|")[1] == 'contain':
contain_list.append(match_keyword)
else:
equal_list.append(match_keyword)
else:
if kw.split("|")[1] == 'contain':
contain_list.append(kw.split("|")[0])
else:
equal_list.append(kw.split("|")[0])

rule_list = []
if contain_list:
rule = 'u: ([ %s ])' % (' '.join(contain_list)).strip()
rule_list.append(rule)
if equal_list:
rule = 'u: (<[ %s ]>)' % (' '.join(equal_list)).strip()
rule_list.append(rule)

for rule in rule_list:
if reply_mode == 'random_one':
if len(reply_list) >= 2:
rule += ''.join(['|[' + reply + ']' for reply in reply_list])
str_list.append(
rule.replace('“', '"').replace('”', '"'))
else:
rule += ''.join(['|' + reply + '' for reply in reply_list])
str_list.append(
rule.replace('“', '"').replace('”', '"'))
else:
rule += '\n\t%s' % ''.join([reply + ' PLCMD-MSG-SEP ' for reply in reply_list])
str_list.append(
rule.replace('“', '"').replace('”', '"'))
return str_list
else:
return None

def init_rule_to_cstopic(self):
"""
根据模板文件、微信关键词自动回复规则生成cs topic文件
:return:
"""
apikey = self.bot_info.get('apikey', '')

bot_name = 'bot_{}'.format(apikey)
bot_top = "{}/{}.top".format('../BOTDATA/KWDL', bot_name)
absolutePath = "{}/{}".format(os.getcwd(), '../BOTDATA/KWDL')

print("当前目录:", os.getcwd())
print("创建文件:", bot_top)
print("绝对路径:", absolutePath)
print("Bot:%s" % bot_name)

kwdl_top = open('../BOTDATA/KWDL/kwdl.top', 'r', encoding='utf-8')
f = open(bot_top, 'w', encoding='utf-8')
for b in kwdl_top.readlines():
b = b.replace('kwdl', bot_name)
if 'topic' in b:
break
else:
f.write(b)
f.close()
kwdl_top.close()

wechatkeyword_list = self.save_wechatkeyword_to_cstopic()

if wechatkeyword_list:
f = open(bot_top, 'a+', encoding='utf-8')
f.write('topic: ~{} bot={} keep repeat ()\n'.format('kwwechat', bot_name))
for i in wechatkeyword_list:
rule_arr = i.split('|')
rule_name = "\n%s\r\n" % rule_arr[0]
f.write(rule_name)
for num in range(1, len(rule_arr)):
response = "\t%s\r\n" % rule_arr[num]
f.write(response)
f.close()


if __name__ == '__main__':
if argv[1]:
appid = argv[1]
# appid = 'wx4834ee84edeed705'
c = InitCS(appid)
c.init_rule_to_cstopic()

pychatscript.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import socket
import re

BUFSIZE = 1024

regex = re.compile(
u'([\u2014\u00b0\u2103\u201c\u2264\u201d\u2265\u00B7\u3400-\u4DB5\u4E00-\u9FA5\u9FA6-\u9FBB\uF900-\uFA2D\uFA30-\uFA6A\uFA70-\uFAD9\uFF00-\uFFEF\u2E80-\u2EFF\u3000-\u303F\u31C0-\u31EF\u2F00-\u2FDF\u2FF0-\u2FFF\u3100-\u312F\u31A0-\u31BF\u3040-\u309F\u30A0-\u30FF\u31F0-\u31FF\uAC00-\uD7AF\u1100-\u11FF\u3130-\u318F\u4DC0-\u4DFF\uA000-\uA48F\uA490-\uA4CF\u2800-\u28FF\u3200-\u32FF\u3300-\u33FF\u2700-\u27BF\u2600-\u26FF\uFE10-\uFE1F\uFE30-\uFE4F])') # 匹配中文


def split_str(s=''):
return re.sub('\s+', ' ', regex.sub(r' \1 ', s))


def send(query, user='', bot=''):
env = os.getenv('FLASK_CONFIG') or 'default'
env = 'beta'
if env == 'production':
CONNECT_HOST = '192.168.1.239'
CONNECT_PORT = 51025
elif env == 'beta':
CONNECT_HOST = '192.168.1.239'
CONNECT_PORT = 51024
else:
CONNECT_HOST = '192.168.0.25'
CONNECT_PORT = 1024
print('CSBots:host=%s,port=%s,bot=%s,user=%s,query=%s' % (CONNECT_HOST, CONNECT_PORT, bot, user, query))
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((CONNECT_HOST, CONNECT_PORT))
query = split_str(query)
if user == '':
user = 'xiaolaclient'
text = '%s\x00%s\x00%s\x00' % (user, bot, query)
s.send(text.encode('utf8'))

data = b''
while 1:
block = s.recv(BUFSIZE)
if block:
data += block
else:
break
try:
data = data.decode('utf-8')
except UnicodeDecodeError:
try:
data.decode('gb2312')
except UnicodeDecodeError:
data.decode('iso-8859-1')
return data


def bot_init(user=None, query=None):
if user:
build = send(':build xiaola', user, "xiaola")
print(build)
bot = send(':bot xiaola', user, 'xiaola')
print(bot)
if query:
cs_res = send(query, user, "xiaola")
print(cs_res)
build = send(':build xiaola', user, "xiaola")
print(build)


if __name__ == '__main__':
while 1:
query = input('query>')
print(send(query.strip(), 'user', 'bot_e9fb5a38296043d7b972d303b3dd4f17'))
if query == ':exit':
break

启动stand-alone模式调试

1
[root@sparsematrix Bots-master]# ./start_local_7.52.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[root@sparsematrix Bots-master]# vi start_local_7.52.sh
#!/bin/sh

# 使用系统编译的版本
# chmod +x ./ChatScript/BINARIES/LinuxChatScript64
# cd ChatScript && BINARIES/LinuxChatScript64 livedata=../LIVEDATA system=LIVEDATA/SYSTEM users=../USERS logs=../LOGS local

# 使用自己编译的版本
chmod +x ./ChatScript-7.52/BINARIES/ChatScript
cd ChatScript-7.52 && BINARIES/ChatScript \
users=../USERS \
logs=../LOGS \
topic=../TOPIC \
login=user \
local

启动Server模式调试

1
[root@sparsematrix Bots-master]# ./start_server_7.52.sh
1
2
3
4
5
6
7
8
9
[root@sparsematrix Bots-master]# vi start_server_7.52.sh
#!/bin/sh
# 使用自己编译的版本
chmod +x ./ChatScript-7.52/BINARIES/ChatScript
cd ChatScript-7.52 && nohup BINARIES/ChatScript \
users=../USERS \
logs=../LOGS \
topic=../TOPIC \
port=51024 &
本文作者 : Matrix
原文链接 : https://matrixsparse.github.io/2017/07/21/ChatScript初始化机器人/
版权声明 : 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!

知识 & 情怀 | 二者兼得

微信扫一扫, 向我投食

微信扫一扫, 向我投食

支付宝扫一扫, 向我投食

支付宝扫一扫, 向我投食

留下足迹