-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathchatbot.py
154 lines (143 loc) · 4.91 KB
/
chatbot.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
from chatterbot import response_selection
from chatterbot import ChatBot
from chatterbot.tagging import LowercaseTagger
from chatterbot.ext.sqlalchemy_app.models import Statement
import discord
import os
import re
import typing
import functools
# Uncomment the following lines to enable verbose logging
import logging
# from chatterbot.trainers import ChatterBotCorpusTrainer
import psycopg2
from urllib.parse import urlparse
result = urlparse(os.environ['DATABASE_URL'])
username = result.username
password = result.password
database = result.path[1:]
hostname = result.hostname
port = result.port
connection = psycopg2.connect(
database = database,
user = username,
password = password,
host = hostname,
port = port
)
# import spacy
# nlp = spacy.load("xx_sent_ud_sm")
logging.basicConfig(level=logging.INFO)
up=0
istyping=0
TOKEN = os.environ['TOKEN']
channel=None
intents = discord.Intents.all()
client = discord.Client(intents=intents)
# Create a new instance of a ChatBot
bot = ChatBot(
'AtWaker',
storage_adapter='chatterbot.storage.SQLStorageAdapter',
logic_adapters=[
{
"import_path": "chatterbot.logic.BestMatch",
"statement_comparison_function": "chatterbot.comparisons.SentimentComparison",
"response_selection_method": response_selection.get_random_response
}
],
tagger=LowercaseTagger,
database_uri=os.environ['DATABASE_URL']
)
async def run_blocking(blocking_func: typing.Callable, *args, **kwargs) -> typing.Any:
"""Runs a blocking function in a non-blocking way"""
func = functools.partial(blocking_func, *args, **kwargs) # `run_in_executor` doesn't support kwargs, `functools.partial` does
return await client.loop.run_in_executor(None, func)
async def learn_and_send(channel,user_input):
global istyping
istyping+=1
async with channel.typing():
z=await run_blocking(bot.get_response,user_input)
istyping-=1
if istyping!=0:
channel.typing()
mentions=re.findall("<@.+>",z.text)
for m in mentions:
mid=int(re.sub("[<@!&>]","",m))
if re.search("&",m):
if channel.guild.get_role(mid):
nm=channel.guild.get_role(mid).name
else:
nm="deleted_role"
else:
if channel.guild.get_member(mid):
nm=channel.guild.get_member(mid).display_name
else:
nm="deleted_member"
z.text=re.sub(m,"@."+nm,z.text)
await channel.send(z)
return
# trainer = ChatterBotCorpusTrainer(bot)
# trainer.train(
# "chatterbot.corpus.japanese"
# )
@client.event
async def on_ready():
cur = connection.cursor()
sql=("CREATE TABLE IF NOT EXISTS statement ("
+"text varchar(65535) NOT NULL, "
+"search_text varchar(65535), "
+"conversation varchar(255), "
+"created_at date, "
+"tags varchar(255), "
+"in_response_to varchar(65535), "
+"search_in_response_to varchar(65535), "
+"persona varchar(255), "
+"PRIMARY KEY (text) "
+");")
cur.execute(sql)
cur.execute("SELECT COUNT(*) FROM statement;")
for row in cur:
print(row)
cur.execute("DELETE FROM statement WHERE created_at < (now() - '10 days'::interval);")
cur.execute("SELECT COUNT(*) FROM statement;")
for row in cur:
print(row)
cur.close()
connection.commit()
connection.close()
# 起動したらターミナルにログイン通知が表示される
print('おはよー!')
@client.event
async def on_message(message):
global up
global channel
if not message.author.bot:
if message.content == 'AtWakerちゃん!':
up=1
channel=message.channel
await channel.send("なーに?")
elif (up==1 and 'AtWakerちゃん' in message.content
and 'ばいばい' in message.content and channel==message.channel):
await channel.send("じゃあね!")
up=0
elif len(message.content)>0:
last_input=await run_blocking(bot.get_latest_response,conversation=str(message.channel.id))
if up==1 and channel==message.channel:
user_input={
"text":message.content,
"conversation":str(message.channel.id),
"in_response_to":last_input.text if (not last_input is None) else None,
"persona":str(message.author.id)
}
await learn_and_send(channel,user_input)
else:
user_input = Statement(
text=message.content,
conversation=str(message.channel.id),
in_response_to= last_input.text if (not last_input is None) else None,
persona= str(message.author.id)
)
await run_blocking(bot.learn_response,user_input)
return
# Botの起動とDiscordサーバーへの接続
client.run(TOKEN)