def test_session_manager_auto(self): import chatbot.server.config chatbot.server.config.SESSION_REMOVE_TIMEOUT = 2 from chatbot.server.session import SessionManager reload(chatbot.server.session) session_manager = SessionManager(True) sid = session_manager.start_session(user='******', key='key', test=True) session = session_manager.get_session(sid) self.assertIsNotNone(session) self.assertIsNone(session.cache.last_time) time.sleep(0.5) # session cache should have record self.assertTrue(session.add("hi", "hi there")) self.assertIsNotNone(session.cache.last_time) # session should not be removed time.sleep(1) self.assertIsNotNone(session.cache.last_time) # session should be removed time.sleep(1.5) self.assertFalse(session.add("hi", "hi there")) session = session_manager.get_session(sid) self.assertIsNone(session)
def __init__(self, host, port, botname, **kwargs): self.sc = SlackClient(SLACKBOT_API_TOKEN) self.sc.rtm_connect() self.botname = botname self.host = host self.port = str(port) self.lang = 'en' self.icon_url = 'https://avatars.slack-edge.com/2016-05-30/46725216032_4983112db797f420c0b5_48.jpg' self.session_manager = SessionManager() self.weights = kwargs.get('weights')
def __init__(self, host, port): self.sc = SlackClient(SLACKBOT_API_TOKEN) self.sc.rtm_connect() self.botname = 'sophia' self.chatbot_ip = host self.chatbot_port = str(port) self.chatbot_url = 'http://{}:{}/{}'.format( self.chatbot_ip, self.chatbot_port, VERSION) self.lang = 'en' self.session_manager = SessionManager() self.icon_url='https://avatars.slack-edge.com/2016-05-30/46725216032_4983112db797f420c0b5_48.jpg'
def __init__(self, host, port, botname, config_file=None): self.sc = SlackClient(SLACKBOT_API_TOKEN) self.sc.rtm_connect() self.botname = botname self.host = host self.port = str(port) self.lang = 'en' self.icon_url = 'https://avatars.slack-edge.com/2016-05-30/46725216032_4983112db797f420c0b5_48.jpg' self.session_manager = SessionManager() self.config = None self.weights = None if config_file is not None: if os.path.isfile(config_file): with open(config_file) as f: self.config = yaml.load(f) if 'weights' in self.config: self.weights = ','.join([ '{}={}'.format(k, v) for k, v in self.config.get('weights').iteritems() ]) else: logger.warn("Config file {} is not found".format(config_file))
def test_session_manager(self): from chatbot.server.session import SessionManager session_manager = SessionManager(False) sid = session_manager.start_session(user='******', test=True) session = session_manager.get_session(sid) self.assertIsNotNone(session) self.assertIsNone(session.cache.last_time) self.assertTrue(session.add("hi", "hi there")) self.assertIsNotNone(session.cache.last_time) session_manager.reset_session(sid) self.assertIsNotNone(session) self.assertIsNone(session.cache.last_time) session_manager.remove_session(sid) self.assertFalse(session.add("hi", "hi there")) session = session_manager.get_session(sid) self.assertIsNone(session)
def test_session_manager(self): from chatbot.server.session import SessionManager session_manager = SessionManager(False) sid = session_manager.start_session(user='******', key='key', test=True) session = session_manager.get_session(sid) self.assertIsNotNone(session) self.assertIsNone(session.cache.last_time) self.assertTrue(session.add("hi", "hi there")) self.assertIsNotNone(session.cache.last_time) session_manager.reset_session(sid) self.assertIsNotNone(session) self.assertIsNone(session.cache.last_time) session_manager.remove_session(sid) self.assertFalse(session.add("hi", "hi there")) session = session_manager.get_session(sid) self.assertIsNone(session)
class HRSlackBot(object): def __init__(self, host, port, botname, **kwargs): self.sc = SlackClient(SLACKBOT_API_TOKEN) self.sc.rtm_connect() self.botname = botname self.host = host self.port = str(port) self.lang = 'en' self.icon_url = 'https://avatars.slack-edge.com/2016-05-30/46725216032_4983112db797f420c0b5_48.jpg' self.session_manager = SessionManager() self.weights = kwargs.get('weights') self.enable_trace = kwargs.get('enable_trace') def send_message(self, channel, attachments): self.sc.api_call("chat.postMessage", channel=channel, attachments=attachments, username=self.botname.title(), icon_url=self.icon_url) def error(self, channel, msg): attachments = [{'title': msg, 'color': 'danger', 'fallback': msg}] logger.error(msg) self.send_message(channel, attachments) def info(self, channel, msg): attachments = [{'title': msg, 'color': '#36a64f', 'fallback': msg}] logger.info(msg) self.send_message(channel, attachments) def run(self): while True: time.sleep(0.2) messages = self.sc.rtm_read() if not messages: continue for message in messages: if message['type'] != u'message': continue if message.get('subtype') == u'bot_message': continue usr_obj = self.sc.api_call('users.info', token=SLACKTEST_TOKEN, user=message['user']) if not usr_obj['ok']: continue profile = usr_obj['user']['profile'] name = profile.get('first_name') or profile.get('email') question = message.get('text') channel = message.get('channel') sid = self.session_manager.get_sid(name, self.botname) session = self.session_manager.get_session(sid) if session is not None: assert hasattr(session.session_context, 'client') client = session.session_context.client else: client = Client(HR_CHATBOT_AUTHKEY, username=name, botname=self.botname, host=self.host, port=self.port, response_listener=self) client.set_marker('Slack') if self.weights: client.set_weights(self.weights) self.session_manager.add_session(name, self.botname, client.session) session = self.session_manager.get_session(client.session) if session is not None: session.session_context.client = client session.session_context.channel = channel self.info( channel, "Session <{url}/v2.0/session_history?session={sid}&Auth={auth}|{sid}>" .format(url=CHATBOT_SERVER_URL, sid=session.sid, auth=HR_CHATBOT_AUTHKEY)) else: self.error(channel, "Can't get session") continue logger.info("Question {}".format(question)) if question in [':+1:', ':slightly_smiling_face:', ':)', 'gd']: ret, _ = client._rate('good') if ret: logger.info("Rate good") answer = 'Thanks for rating' color = 'good' else: logger.info("Rate failed") answer = 'Rating failed' color = 'danger' attachments = [{ 'title': answer, 'color': color, 'fallback': answer }] self.send_message(channel, attachments) continue if question in [':-1:', ':disappointed:', ':(', 'bd']: ret, _ = client._rate('bad') if ret: logger.info("Rate bad") answer = 'Thanks for rating' color = 'good' else: logger.info("Rate failed") answer = 'Rating failed' color = 'danger' attachments = [{ 'title': answer, 'color': color, 'fallback': answer }] self.send_message(channel, attachments) continue try: client.ask(question) except Exception as ex: self.error(channel, ex.message) # session could change after ask if client.session != session.sid: self.session_manager.remove_session(session.sid) self.session_manager.add_session(name, self.botname, client.session) session = self.session_manager.get_session(client.session) session.session_context.client = client session.session_context.channel = channel self.info( channel, "Session <{url}/v2.0/session_history?session={sid}&Auth={auth}|{sid}>" .format(url=CHATBOT_SERVER_URL, sid=session.sid, auth=HR_CHATBOT_AUTHKEY)) logger.info("Session is updated") def on_response(self, sid, response): answer = '' title = '' session = self.session_manager.get_session(sid) if session is None: time.sleep(0.5) session = self.session_manager.get_session(sid) if session is None: logger.error("No such session {}".format(session)) return channel = session.session_context.channel if response is None or not response.get('text'): answer = u"Sorry, I can't answer it right now" else: answer = response.get('text') trace = response.get('trace', '') botid = response.get('botid', '') if trace and self.enable_trace: formated_trace = format_trace(trace) if formated_trace: title = 'answered by {}\n\ntrace:\n{}'.format( botid, '\n'.join(formated_trace)) attachments = [{ 'pretext': answer, 'title': title, 'color': '#3AA3E3', 'fallback': answer, }] self.send_message(channel, attachments)
class HRSlackBot(object): def __init__(self, host, port, botname, **kwargs): self.sc = SlackClient(SLACKBOT_API_TOKEN) self.sc.rtm_connect() self.botname = botname self.host = host self.port = str(port) self.lang = 'en' self.icon_url = 'https://avatars.slack-edge.com/2016-05-30/46725216032_4983112db797f420c0b5_48.jpg' self.session_manager = SessionManager() self.weights = kwargs.get('weights') def send_message(self, channel, attachments): self.sc.api_call( "chat.postMessage", channel=channel, attachments=attachments, username=self.botname.title(), icon_url=self.icon_url) def error(self, channel, msg): attachments = [{ 'title': msg, 'color': 'danger', 'fallback': msg }] logger.error(msg) self.send_message(channel, attachments) def info(self, channel, msg): attachments = [{ 'title': msg, 'color': '#36a64f', 'fallback': msg }] logger.info(msg) self.send_message(channel, attachments) def run(self): while True: time.sleep(0.2) messages = self.sc.rtm_read() if not messages: continue for message in messages: if message['type'] != u'message': continue if message.get('subtype') == u'bot_message': continue usr_obj = self.sc.api_call( 'users.info', token=SLACKTEST_TOKEN, user=message['user']) if not usr_obj['ok']: continue profile = usr_obj['user']['profile'] name = profile.get('first_name') or profile.get('email') question = message.get('text') channel = message.get('channel') sid = self.session_manager.get_sid(name, self.botname) session = self.session_manager.get_session(sid) if session is not None: assert hasattr(session.sdata, 'client') client = session.sdata.client else: client = Client(HR_CHATBOT_AUTHKEY, username=name, botname=self.botname, host=self.host, port=self.port, response_listener=self) client.set_marker('Slack') if self.weights: client.set_weights(self.weights) self.session_manager.add_session(name, self.botname, client.session) session = self.session_manager.get_session(client.session) if session is not None: session.sdata.client = client session.sdata.channel = channel self.info(channel, "Session <{url}/v1.1/session_history?session={sid}&Auth={auth}|{sid}>".format( url=CHATBOT_SERVER_URL, sid=session.sid, auth=HR_CHATBOT_AUTHKEY)) else: self.error(channel, "Can't get session") continue logger.info("Question {}".format(question)) if question in [':+1:', ':slightly_smiling_face:', ':)', 'gd']: ret, _ = client._rate('good') if ret: logger.info("Rate good") answer = 'Thanks for rating' color = 'good' else: logger.info("Rate failed") answer = 'Rating failed' color = 'danger' attachments = [{ 'title': answer, 'color': color, 'fallback': answer }] self.send_message(channel, attachments) continue if question in [':-1:', ':disappointed:', ':(', 'bd']: ret, _ = client._rate('bad') if ret: logger.info("Rate bad") answer = 'Thanks for rating' color = 'good' else: logger.info("Rate failed") answer = 'Rating failed' color = 'danger' attachments = [{ 'title': answer, 'color': color, 'fallback': answer }] self.send_message(channel, attachments) continue try: client.ask(question) except Exception as ex: self.error(channel, ex.message) # session could change after ask if client.session != session.sid: self.session_manager.remove_session(session.sid) self.session_manager.add_session( name, self.botname, client.session) session = self.session_manager.get_session(client.session) session.sdata.client = client session.sdata.channel = channel self.info(channel, "Session <{url}/v1.1/session_history?session={sid}&Auth={auth}|{sid}>".format( url=CHATBOT_SERVER_URL, sid=session.sid, auth=HR_CHATBOT_AUTHKEY)) logger.info("Session is updated") def on_response(self, sid, response): answer = '' title = '' session = self.session_manager.get_session(sid) if session is None: time.sleep(0.5) session = self.session_manager.get_session(sid) if session is None: logger.error("No such session {}".format(session)) return channel = session.sdata.channel if response is None or not response.get('text'): answer = u"Sorry, I can't answer it right now" else: answer = response.get('text') trace = response.get('trace', '') botid = response.get('botid', '') if trace: formated_trace = format_trace(trace) if formated_trace: title = 'answered by {}\n\ntrace:\n{}'.format(botid, '\n'.join(formated_trace)) attachments = [{ 'pretext': answer, 'title': title, 'color': '#3AA3E3', 'fallback': answer, }] self.send_message(channel, attachments)
class HRSlackBot(SlackClient): def __init__(self, host, port): self.sc = SlackClient(SLACKBOT_API_TOKEN) self.sc.rtm_connect() self.botname = 'sophia' self.chatbot_ip = host self.chatbot_port = str(port) self.chatbot_url = 'http://{}:{}/{}'.format( self.chatbot_ip, self.chatbot_port, VERSION) self.lang = 'en' self.session_manager = SessionManager() self.icon_url='https://avatars.slack-edge.com/2016-05-30/46725216032_4983112db797f420c0b5_48.jpg' def set_sid(self, user): params = { "Auth": KEY, "botname": self.botname, "user": user } r = None retry = 3 while r is None and retry > 0: try: r = requests.get('{}/start_session'.format(self.chatbot_url), params=params) except Exception: retry -= 1 time.sleep(1) if r is None: logger.error("Can't get session\n") return ret = r.json().get('ret') if r.status_code != 200: logger.error("Request error: {}\n".format(r.status_code)) sid = r.json().get('sid') logger.info("Get session {}\n".format(sid)) self.session_manager.add_session(user, sid) def ask(self, user, question): params = { "question": "{}".format(question), "session": self.session_manager.get_sid(user), "lang": self.lang, "Auth": KEY } r = requests.get('{}/chat'.format(self.chatbot_url), params=params) ret = r.json().get('ret') if r.status_code != 200: logger.error("Request error: {}\n".format(r.status_code)) if ret != 0: logger.error("QA error: error code {}, botname {}, question {}, lang {}\n".format( ret, self.botname, question, self.lang)) response = {'text': '', 'emotion': '', 'botid': '', 'botname': ''} response.update(r.json().get('response')) return ret, response def _rate(self, user, rate): params = { "session": self.session_manager.get_sid(user), "rate": rate, "index": -1, "Auth": KEY } r = requests.get('{}/rate'.format(self.chatbot_url), params=params) ret = r.json().get('ret') response = r.json().get('response') return ret, response def send_message(self, channel, attachments): self.sc.api_call( "chat.postMessage", channel=channel, attachments=attachments, username=self.botname.title(), icon_url=self.icon_url) def run(self): while True: time.sleep(0.2) messages = self.sc.rtm_read() if not messages: continue for message in messages: if message['type']!=u'message': continue if message.get('subtype')==u'bot_message': continue usr_obj = self.sc.api_call( 'users.info', token=SLACKTEST_TOKEN, user=message['user']) if not usr_obj['ok']: continue profile = usr_obj['user']['profile'] name = profile.get('first_name') or profile.get('email') question = message.get('text') channel = message.get('channel') logger.info("Question {}".format(question)) if question in [':+1:', ':slightly_smiling_face:', ':)', 'gd']: ret, _ = self._rate(name, 'good') if ret: logger.info("Rate good") answer = 'Thanks for rating' color = 'good' else: logger.info("Rate failed") answer = 'Rating failed' color = 'danger' attachments = [{ 'title': answer, 'color': color, 'fallback': answer }] self.send_message(channel, attachments) continue if question in [':-1:', ':disappointed:', ':(', 'bd']: ret, _ = self._rate(name, 'bad') if ret: logger.info("Rate bad") answer = 'Thanks for rating' color = 'good' else: logger.info("Rate failed") answer = 'Rating failed' color = 'danger' attachments = [{ 'title': answer, 'color': color, 'fallback': answer }] self.send_message(channel, attachments) continue ret, response = self.ask(name, question) if ret == 3: self.set_sid(name) ret, response = self.ask(name, question) answer = response.get('text') trace = response.get('trace', '') botid = response.get('botid', '') if ret != 0: answer = u"Sorry, I can't answer it right now" title = '' else: formated_trace = format_trace(trace) title = 'answered by {}\ntrace:\n{}'.format(botid, '\n'.join(formated_trace)) attachments = [{ 'pretext': answer, 'title': title, 'color': '#3AA3E3', 'fallback': answer, }] self.send_message(channel, attachments)