-
Notifications
You must be signed in to change notification settings - Fork 0
/
mainbot.py
219 lines (167 loc) · 7.65 KB
/
mainbot.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
import os
import logging
from flask import Flask, request
from slack import WebClient
from slackeventsapi import SlackEventAdapter
from ai_bot import OnboardingMessage
import ai_bot
import ssl as ssl_lib
import certifi
import threading
import requests
ssl_context = ssl_lib.create_default_context(cafile=certifi.where())
# Initialize a Flask app to host the events adapter
app = Flask(__name__)
slack_events_adapter = SlackEventAdapter(os.environ["SLACK_SIGNING_SECRET"], "/slack/events", app)
# Initialize a Web API client
slack_web_client = WebClient(token=os.environ['SLACK_BOT_TOKEN'])
# For simplicity we'll store our app data in-memory with the following data structure.
# onboarding_tutorials_sent = {"channel": {"user_id": OnboardingMessage}}
onboarding_tutorials_sent = {}
# Load model once and for all (using load data function)
data = ai_bot.LoadingData()
cat_to_tag,tag_to_response = data.cat_to_tag,data.tag_to_response
_clean_text,_tensorize = data._clean_text,data._tensorize
X_shape,Y_shape = data.X,data.Y # Need data for the shaped to be used
model_obj_1 = ai_bot.ModelFcnn()
model_obj_1.build(X_shape,Y_shape, _clean_text)
X,Y = model_obj_1.get_input_array(X_shape,_clean_text,_tensorize),Y_shape
model_obj_1.model.load_weights("model/FCNN.h5")
model_obj_2 = ai_bot.ModelLstm()
X,Y = model_obj_2.get_input_array(X_shape,_clean_text,_tensorize),Y_shape
model_obj_2._build(X,Y,EMBEDDING_DIM = 128)
model_obj_2.model.load_weights("model/LSTM.h5")
model_obj_3 = ai_bot.ModelRnnlm()
X,Y = model_obj_3.get_input_array(X_shape,_clean_text,_tensorize),Y_shape
model_obj_3._build(X,Y)
model_obj_3.model.load_weights("model/RNNLM.h5")
model_obj_4 = ai_bot.ModelBert(512,Y_shape.shape[1])
model_obj_4._build()
model_obj_4.model.load_weights("model/Bert.h5")
model_objects = [model_obj_1,model_obj_2,model_obj_3,model_obj_4]
def start_onboarding(user_id: str, channel: str):
# Create a new onboarding tutorial.
onboarding_tutorial = OnboardingMessage(channel)
# Get the onboarding message payload
message = onboarding_tutorial.get_message_payload()
# Post the onboarding message in Slack
response = slack_web_client.chat_postMessage(**message)
# Capture the timestamp of the message we've just posted so
# we can use it to update the message after a user
# has completed an onboarding task.
onboarding_tutorial.timestamp = response["ts"]
# Store the message sent in onboarding_tutorials_sent
if channel not in onboarding_tutorials_sent:
onboarding_tutorials_sent[channel] = {}
onboarding_tutorials_sent[channel][user_id] = onboarding_tutorial
# ================ Team Join Event =============== #
# When the user first joins a team, the type of the event will be 'team_join'.
# Here we'll link the onboarding_message callback to the 'team_join' event.
@slack_events_adapter.on("team_join")
def onboarding_message(payload):
"""Create and send an onboarding welcome message to new users. Save the
time stamp of this message so we can update this message in the future.
"""
event = payload.get("event", {})
# Get the id of the Slack user associated with the incoming event
user_id = event.get("user", {}).get("id")
# Open a DM with the new user.
response = slack_web_client.im_open(user=user_id)
channel = response["channel"]["id"]
# Post the onboarding message.
start_onboarding(user_id, channel)
# ============= Reaction Added Events ============= #
# When a users adds an emoji reaction to the onboarding message,
# the type of the event will be 'reaction_added'.
# Here we'll link the update_emoji callback to the 'reaction_added' event.
@slack_events_adapter.on("reaction_added")
def update_emoji(payload):
"""Update the onboarding welcome message after receiving a "reaction_added"
event from Slack. Update timestamp for welcome message as well.
"""
event = payload.get("event", {})
channel_id = event.get("item", {}).get("channel")
user_id = event.get("user")
if channel_id not in onboarding_tutorials_sent:
return
# Get the original tutorial sent.
onboarding_tutorial = onboarding_tutorials_sent[channel_id][user_id]
# Mark the reaction task as completed.
onboarding_tutorial.reaction_task_completed = True
# Get the new message payload
message = onboarding_tutorial.get_message_payload()
# Post the updated message in Slack
updated_message = slack_web_client.chat_update(**message)
# Update the timestamp saved on the onboarding tutorial object
onboarding_tutorial.timestamp = updated_message["ts"]
# =============== Pin Added Events ================ #
# When a users pins a message the type of the event will be 'pin_added'.
# Here we'll link the update_pin callback to the 'pin_added' event.
@slack_events_adapter.on("pin_added")
def update_pin(payload):
"""Update the onboarding welcome message after receiving a "pin_added"
event from Slack. Update timestamp for welcome message as well.
"""
event = payload.get("event", {})
channel_id = event.get("channel_id")
user_id = event.get("user")
# Get the original tutorial sent.
onboarding_tutorial = onboarding_tutorials_sent[channel_id][user_id]
# Mark the pin task as completed.
onboarding_tutorial.pin_task_completed = True
# Get the new message payload
message = onboarding_tutorial.get_message_payload()
# Post the updated message in Slack
updated_message = slack_web_client.chat_update(**message)
# Update the timestamp saved on the onboarding tutorial object
onboarding_tutorial.timestamp = updated_message["ts"]
# ============== Message Events ============= #
# When a user sends a DM or a message in channel, the event type will be 'message'.
# Here we'll link the message callback to the 'message' event.
@slack_events_adapter.on("message")
def message(payload):
"""Display the onboarding welcome message after receiving a message
that contains "start".
"""
event = payload.get("event", {})
channel_id = event.get("channel")
user_id = event.get("user")
text = event.get("text")
if text and text.lower() == "start":
return start_onboarding(user_id, channel_id)
# ============== App_mention Events ============= #
# When a user sends a message with mention "@amexbot", the event type will be 'app_mention'.
# Here we'll link the message callback to the 'app_mention' event.
@slack_events_adapter.on("app_mention")
def slash_response(payload):
"""endpoint for receiving all slash command requests from Slack"""
# get the full request from Slack
slack_request = request.form
print(slack_request)
# starting a new thread for doing the actual processing
x = threading.Thread(
target=ai_message,
args=(slack_request,payload,)
)
x.start()
## respond to Slack with quick message
# and end the main thread for this request
return "Let me think.... Please wait :robot_face:"
def ai_message(slack_request,payload):
"""Respond using the ML model when the bot is mentioned with "@amexbot"
using the text
"""
event = payload.get("event", {})
channel_id = event.get("channel")
text = event.get("text")
# Create a message structure with an intent prediction.
ai_chatbot = ai_bot.SlackMessage(channel_id, text)
# Get the response predicted
message = ai_chatbot.get_message_payload(model_objects,_clean_text,_tensorize,cat_to_tag,tag_to_response)
# Post the AI message in Slack
response = slack_web_client.chat_postMessage(**message)
if __name__ == "__main__":
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
logger.addHandler(logging.StreamHandler())
app.run(port=3000)