def serve_forever(self): self.connect_callback() # notify that the connection occured try: while True: log.debug('waiting on queue') stanza_type, entry = self.incoming_stanza_queue.get() log.debug('message received') if entry == QUIT_MESSAGE: log.info("Stop magic message received, quitting...") break if stanza_type is STZ_MSG: msg = Message(entry) msg.frm = self.sender msg.to = self.bot_identifier # To me only self.callback_message(msg) # implements the mentions. mentioned = [ self.build_identifier(word[1:]) for word in entry.split() if word.startswith('@') ] if mentioned: self.callback_mention(msg, mentioned) elif stanza_type is STZ_PRE: log.info("Presence stanza received.") self.callback_presence(entry) elif stanza_type is STZ_IQ: log.info("IQ stanza received.") else: log.error("Unknown stanza type.") except EOFError: pass except KeyboardInterrupt: pass finally: log.debug("Trigger disconnect callback") self.disconnect_callback() log.debug("Trigger shutdown") self.shutdown()
def _handle_message(self, message): try: data = json.loads(message.data.decode('utf-8')) except Exception: log.warning('Received malformed message: {}'.format(message.data)) message.ack() return if not data.get('message') or not data.get('message', {}).get('text'): message.ack() return sender_blob = data['message']['sender'] sender = HangoutsChatUser(sender_blob['name'], sender_blob['displayName'], sender_blob['email'], sender_blob['type']) message_body = data['message']['text'] message.ack() # message.ack() may fail silently, so we should ensure our messages are somewhat idempotent time = data.get('eventTime', 0) if time == 0: log.warning('Received 0 eventTime from message') send_name = sender_blob.get('name', '') thread_name = data.get('message', {}).get('thread', {}).get('name', '') body_length = len(message_body) message_id = "{}{}{}{}".format(time, send_name, thread_name, body_length) cached = self.message_cache.get(message_id) if cached is not None: return self.message_cache[message_id] = True context = { 'space_id': data['space']['name'], 'thread_id': data['message']['thread']['name'] } msg = Message(body=message_body.strip(), frm=sender, extras=context) is_dm = data['message']['space']['type'] == 'DM' if is_dm: msg.to = self.bot_identifier self.callback_message(msg)
def serve_forever(self): if self.demo_mode: # disable the console logging once it is serving in demo mode. root = logging.getLogger() root.removeHandler(console_hdlr) root.addHandler(logging.NullHandler()) self.connect_callback() # notify that the connection occured self.callback_presence(Presence(identifier=self.user, status=ONLINE)) try: while True: if ANSI or self.demo_mode: entry = input('\n' + str(fg.cyan) + ' >>> ' + str(fx.reset)) else: entry = input('\n>>> ') msg = Message(entry) msg.frm = self.user msg.to = self.bot_identifier self.callback_message(msg) mentioned = [ self.build_identifier(word[1:]) for word in re.findall(r"@[\w']+", entry) if word.startswith('@') ] if mentioned: self.callback_mention(msg, mentioned) sleep(.5) except EOFError: pass except KeyboardInterrupt: pass finally: # simulate some real presence self.callback_presence( Presence(identifier=self.user, status=OFFLINE)) log.debug("Trigger disconnect callback") self.disconnect_callback() log.debug("Trigger shutdown") self.shutdown()
def serve_forever(self): self.jid = 'Err@localhost' # whatever self.connect() # be sure we are "connected" before the first command self.connect_callback() # notify that the connection occured try: while True: entry = raw_input("Talk to me >>").decode(ENCODING_INPUT) msg = Message(entry) msg.setFrom( config.BOT_ADMINS[0]) # assume this is the admin talking msg.setTo(self.jid) # To me only self.callback_message(self.conn, msg) except EOFError as eof: pass except KeyboardInterrupt as ki: pass finally: logging.debug("Trigger disconnect callback") self.disconnect_callback() logging.debug("Trigger shutdown") self.shutdown()
def incoming_message(self, xmppmsg): """Callback for message events""" if xmppmsg['type'] == "error": log.warning("Received error message: %s", xmppmsg) return msg = Message(xmppmsg['body']) if 'html' in xmppmsg.keys(): msg.html = xmppmsg['html'] log.debug("incoming_message from: %s", msg.frm) if xmppmsg['type'] == 'groupchat': msg.frm = self._build_room_occupant(xmppmsg['from'].full) msg.to = msg.frm.room else: msg.frm = self._build_person(xmppmsg['from'].full) msg.to = self._build_person(xmppmsg['to'].full) msg.nick = xmppmsg['mucnick'] msg.delayed = bool(xmppmsg['delay']._get_attr( 'stamp')) # this is a bug in sleekxmpp it should be ['from'] self.callback_message(msg)
def incoming_message(self, xmppmsg): """Callback for message events""" if xmppmsg["type"] == "error": log.warning("Received error message: %s", xmppmsg) return msg = Message(xmppmsg["body"]) if "html" in xmppmsg.keys(): msg.html = xmppmsg["html"] log.debug("incoming_message from: %s", msg.frm) if xmppmsg["type"] == "groupchat": msg.frm = self._build_room_occupant(xmppmsg["from"].full) msg.to = msg.frm.room else: msg.frm = self._build_person(xmppmsg["from"].full) msg.to = self._build_person(xmppmsg["to"].full) msg.nick = xmppmsg["mucnick"] msg.delayed = bool(xmppmsg["delay"]._get_attr( "stamp")) # this is a bug in slixmpp it should be ['from'] self.callback_message(msg)
def _handle_message(self, message): data = json.loads(message.data.decode('utf-8')) if not data.get('message'): message.ack() return sender_blob = data['message']['sender'] sender = HangoutsChatUser(sender_blob['name'], sender_blob['displayName'], sender_blob['email'], sender_blob['type']) message_body = data['message']['text'] message.ack() context = { 'space_id': data['space']['name'], 'thread_id': data['message']['thread']['name'] } msg = Message(body=message_body.strip(), frm=sender, extras=context) is_dm = data['message']['space']['type'] == 'DM' if is_dm: msg.to = self.bot_identifier self.callback_message(msg)
def incoming_message(self, xmppmsg): """Callback for message events""" msg = Message(xmppmsg['body']) if 'html' in xmppmsg.keys(): msg.html = xmppmsg['html'] msg.frm = self.build_identifier(xmppmsg['from'].full) msg.to = self.build_identifier(xmppmsg['to'].full) log.debug("incoming_message frm : %s" % msg.frm) log.debug("incoming_message frm node: %s" % msg.frm.node) log.debug("incoming_message frm domain: %s" % msg.frm.domain) log.debug("incoming_message frm resource: %s" % msg.frm.resource) msg.type = xmppmsg['type'] if msg.type == 'groupchat': # those are not simple identifiers, they are muc occupants. msg.frm = XMPPMUCOccupant(msg.frm.node, msg.frm.domain, msg.frm.resource) msg.to = XMPPMUCOccupant(msg.to.node, msg.to.domain, msg.to.resource) msg.nick = xmppmsg['mucnick'] msg.delayed = bool(xmppmsg['delay']._get_attr( 'stamp')) # this is a bug in sleekxmpp it should be ['from'] self.callback_message(msg)
def incoming_message(self, xmppmsg): """Callback for message events""" if xmppmsg['type'] == "error": log.warning("Received error message: %s", xmppmsg) return msg = Message(xmppmsg['body']) if 'html' in xmppmsg.keys(): msg.html = xmppmsg['html'] msg.frm = self.build_identifier(xmppmsg['from'].full) msg.to = self.build_identifier(xmppmsg['to'].full) log.debug("incoming_message from: %s", msg.frm) if xmppmsg['type'] == 'groupchat': room = self.room_factory(msg.frm.node + '@' + msg.frm.domain, self) msg.frm = self.roomoccupant_factory(msg.frm.node, msg.frm.domain, msg.frm.resource, room) msg.to = room msg.nick = xmppmsg['mucnick'] msg.delayed = bool(xmppmsg['delay']._get_attr( 'stamp')) # this is a bug in sleekxmpp it should be ['from'] self.callback_message(msg)
def incoming_message(self, xmppmsg: dict) -> None: """Callback for message events""" if xmppmsg["type"] == "error": log.warning("Received error message: %s", xmppmsg) return msg = Message(xmppmsg["body"]) if "html" in xmppmsg.keys(): msg.html = xmppmsg["html"] log.debug("incoming_message from: %s", msg.frm) if xmppmsg["type"] == "groupchat": msg.frm = self._build_room_occupant(xmppmsg["from"].full) msg.to = msg.frm.room else: msg.frm = self._build_person(xmppmsg["from"].full) msg.to = self._build_person(xmppmsg["to"].full) msg.nick = xmppmsg["mucnick"] now = datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ") delay = xmppmsg["delay"]._get_attr( "stamp") # this is a bug in sleekxmpp it should be ['from'] msg.delayed = bool(delay and delay != now) self.callback_message(msg)
def serve_forever(self): me = self.build_identifier(self.bot_config.BOT_ADMINS[0]) self.connect_callback() # notify that the connection occured self.callback_presence(Presence(identifier=me, status=ONLINE)) try: while True: if ANSI: entry = input('\n' + str(fg.cyan) + ' >>> ' + str(fx.reset)) else: entry = input('\n>>> ') msg = Message(entry) msg.frm = me msg.to = self.bot_identifier self.callback_message(msg) mentioned = [ self.build_identifier(word[1:]) for word in re.findall(r"@[\w']+", entry) if word.startswith('@') ] if mentioned: self.callback_mention(msg, mentioned) sleep(.5) except EOFError: pass except KeyboardInterrupt: pass finally: # simulate some real presence self.callback_presence(Presence(identifier=me, status=OFFLINE)) log.debug("Trigger disconnect callback") self.disconnect_callback() log.debug("Trigger shutdown") self.shutdown()
def on_privmsg(self, _, e): msg = Message(e.arguments[0]) msg.frm = IRCIdentifier(e.source.split('!')[0]) msg.to = IRCIdentifier(e.target) self.callback.callback_message(msg)
def build_reply(self, msg, text=None, private=False, threaded=False): response = Message(body=text, frm=msg.to, to=msg.frm, extras=msg.extras) return response
def on_privmsg(self, _, e): msg = Message(e.arguments[0]) msg.frm = e.source.split('!')[0] msg.to = e.target self.callback.callback_message(msg)
def build_message(self, text): return Message(text, typ='groupchat') # it is always a groupchat in campfire
def build_message(self, text): text, html = self.build_text_html_message_pair(text) return Message(text, html=html)
def build_message(self, text): txt, node = build_text_html_message_pair(text) msg = Message(txt, html=node) if node else Message(txt) msg.frm = self.jid return msg # rebuild a pure html snippet to include directly in the console html
def on_friend_message(self, friend_number, message): msg = Message(message) msg.frm = self.friend_to_idd(friend_number) logging.debug('TOX: %s: %s' % (msg.frm, message)) msg.to = self.backend.jid self.backend.callback_message(msg)
def _privmsg(self, e, notice=False): msg = Message(e.arguments[0], extras={'notice': notice}) msg.frm = IRCPerson(e.source) msg.to = IRCPerson(e.target) self.bot.callback_message(msg)
def build_message(self, text): return Message(self.build_text_html_message_pair(text) [0]) # 0 = Only retain pure text
def _message_event_handler(self, message): log.debug(message) data = message['data'] # In some cases (direct messages) team_id is an empty string if data['team_id'] != '' and self.teamid != data['team_id']: log.info("Message came from another team ({}), ignoring...".format(data['team_id'])) return broadcast = message['broadcast'] if 'channel_id' in data: channelid = data['channel_id'] elif 'channel_id' in broadcast: channelid = broadcast['channel_id'] else: log.error("Couldn't find a channelid for event {}".format(message)) return channel_type = data['channel_type'] if channel_type != 'D': channel = data['channel_name'] else: channel = channelid text = '' post_id = '' file_ids = None userid = None if 'post' in data: post = json.loads(data['post']) text = post['message'] userid = post['user_id'] if 'file_ids' in post: file_ids = post['file_ids'] post_id = post['id'] if 'type' in post and post['type'] == 'system_add_remove': log.info("Ignoring message from System") return if 'user_id' in data: userid = data['user_id'] if not userid: log.error('No userid in event {}'.format(message)) return mentions = [] if 'mentions' in data: # TODO: Only user, not channel mentions are in here at the moment mentions = self.mentions_build_identifier(json.loads(data['mentions'])) # Thread root post id root_id = post.get('root_id') if root_id is '': root_id = post_id msg = Message( text, extras={ 'id': post_id, 'root_id': root_id, 'mattermost_event': message, 'url': '{scheme:s}://{domain:s}:{port:s}/{teamname:s}/pl/{postid:s}'.format( scheme=self.driver.options['scheme'], domain=self.driver.options['url'], port=str(self.driver.options['port']), teamname=self.team, postid=post_id ) } ) if file_ids: msg.extras['attachments'] = file_ids # TODO: Slack handles bots here, but I am not sure if bot users is a concept in mattermost if channel_type == 'D': msg.frm = MattermostPerson(self.driver, userid=userid, channelid=channelid, teamid=self.teamid) msg.to = MattermostPerson( self.driver, userid=self.bot_identifier.userid, channelid=channelid, teamid=self.teamid) elif channel_type == 'O' or channel_type == 'P': msg.frm = MattermostRoomOccupant(self.driver, userid=userid, channelid=channelid, teamid=self.teamid, bot=self) msg.to = MattermostRoom(channel, teamid=self.teamid, bot=self) else: log.warning('Unknown channel type \'{}\'! Unable to handle {}.'.format( channel_type, channel )) return self.callback_message(msg) if mentions: self.callback_mention(msg, mentions)
def _message_event_handler(self, event): """Event handler for the 'message' event""" channel = event["channel"] if channel[0] not in "CGD": log.warning("Unknown message type! Unable to handle %s", channel) return subtype = event.get("subtype", None) if subtype in ("message_deleted", "channel_topic", "message_replied"): log.debug("Message of type %s, ignoring this event", subtype) return if subtype == "message_changed" and "attachments" in event["message"]: # If you paste a link into Slack, it does a call-out to grab details # from it so it can display this in the chatroom. These show up as # message_changed events with an 'attachments' key in the embedded # message. We should completely ignore these events otherwise we # could end up processing bot commands twice (user issues a command # containing a link, it gets processed, then Slack triggers the # message_changed event and we end up processing it again as a new # message. This is not what we want). log.debug( "Ignoring message_changed event with attachments, likely caused " "by Slack auto-expanding a link") return if "message" in event: text = event["message"].get("text", "") user = event["message"].get("user", event.get("bot_id")) else: text = event.get("text", "") user = event.get("user", event.get("bot_id")) text, mentioned = self.process_mentions(text) text = self.sanitize_uris(text) log.debug("Saw an event: %s", pprint.pformat(event)) log.debug("Escaped IDs event text: %s", text) msg = Message( text, extras={ "attachments": event.get("attachments"), "slack_event": event, }, ) if channel.startswith("D"): if subtype == "bot_message": msg.frm = SlackBot( self.sc, bot_id=event.get("bot_id"), bot_username=event.get("username", ""), ) else: msg.frm = SlackPerson(self.sc, user, event["channel"]) msg.to = SlackPerson( self.sc, self.username_to_userid(self.sc.server.username), event["channel"], ) channel_link_name = event["channel"] else: if subtype == "bot_message": msg.frm = SlackRoomBot( self.sc, bot_id=event.get("bot_id"), bot_username=event.get("username", ""), channelid=event["channel"], bot=self, ) else: msg.frm = SlackRoomOccupant(self.sc, user, event["channel"], bot=self) msg.to = SlackRoom(channelid=event["channel"], bot=self) channel_link_name = msg.to.name msg.extras["url"] = ( f"https://{self.sc.server.domain}.slack.com/archives/" f'{channel_link_name}/p{self._ts_for_message(msg).replace(".", "")}' ) self.callback_message(msg) if mentioned: self.callback_mention(msg, mentioned)
def _message_event_handler(self, message): log.debug(message) data = message["data"] # In some cases (direct messages) team_id is an empty string if data["team_id"] != "" and self.teamid != data["team_id"]: log.info("Message came from another team ({}), ignoring...".format( data["team_id"])) return broadcast = message["broadcast"] if "channel_id" in data: channelid = data["channel_id"] elif "channel_id" in broadcast: channelid = broadcast["channel_id"] else: log.error("Couldn't find a channelid for event {}".format(message)) return channel_type = data["channel_type"] if channel_type != "D": channel = data["channel_name"] else: channel = channelid text = "" post_id = "" file_ids = None userid = None if "post" in data: post = json.loads(data["post"]) text = post["message"] userid = post["user_id"] if "file_ids" in post: file_ids = post["file_ids"] post_id = post["id"] if "type" in post and post["type"] == "system_add_remove": log.info("Ignoring message from System") return if "user_id" in data: userid = data["user_id"] if not userid: log.error("No userid in event {}".format(message)) return mentions = [] if "mentions" in data: # TODO: Only user, not channel mentions are in here at the moment mentions = self.mentions_build_identifier( json.loads(data["mentions"])) # Thread root post id root_id = post.get("root_id", "") if root_id == "": root_id = post_id msg = Message( text, extras={ "id": post_id, "root_id": root_id, "mattermost_event": message, "url": "{scheme:s}://{domain:s}:{port:s}/{teamname:s}/pl/{postid:s}". format( scheme=self.driver.options["scheme"], domain=self.driver.options["url"], port=str(self.driver.options["port"]), teamname=self.team, postid=post_id, ), }, ) if file_ids: msg.extras["attachments"] = file_ids # TODO: Slack handles bots here, but I am not sure if bot users is a concept in mattermost if channel_type == "D": msg.frm = MattermostPerson(self.driver, userid=userid, channelid=channelid, teamid=self.teamid) msg.to = MattermostPerson( self.driver, userid=self.bot_identifier.userid, channelid=channelid, teamid=self.teamid, ) elif channel_type == "O" or channel_type == "P": msg.frm = MattermostRoomOccupant( self.driver, userid=userid, channelid=channelid, teamid=self.teamid, bot=self, ) msg.to = MattermostRoom(channel, teamid=self.teamid, bot=self) else: log.warning( "Unknown channel type '{}'! Unable to handle {}.".format( channel_type, channel)) return self.callback_message(msg) if mentions: self.callback_mention(msg, mentions)
def on_privmsg(self, c, e): msg = Message(e.arguments[0]) msg.setFrom(e.source.split('!')[0]) msg.setTo(e.target) msg.setType('chat') self.callback.callback_message(self, msg)
def _message_event_handler(self, event): """Event handler for the 'message' event""" channel = event['channel'] if channel.startswith('C'): log.debug("Handling message from a public channel") message_type = 'groupchat' elif channel.startswith('G'): log.debug("Handling message from a private group") message_type = 'groupchat' elif channel.startswith('D'): log.debug("Handling message from a user") message_type = 'chat' else: log.warning("Unknown message type! Unable to handle") return subtype = event.get('subtype', None) if subtype == "message_deleted": log.debug("Message of type message_deleted, ignoring this event") return if subtype == "message_changed" and 'attachments' in event['message']: # If you paste a link into Slack, it does a call-out to grab details # from it so it can display this in the chatroom. These show up as # message_changed events with an 'attachments' key in the embedded # message. We should completely ignore these events otherwise we # could end up processing bot commands twice (user issues a command # containing a link, it gets processed, then Slack triggers the # message_changed event and we end up processing it again as a new # message. This is not what we want). log.debug( "Ignoring message_changed event with attachments, likely caused " "by Slack auto-expanding a link") return if 'message' in event: text = event['message']['text'] user = event['message'].get('user', event.get('bot_id')) else: text = event['text'] user = event.get('user', event.get('bot_id')) text = re.sub("<[^>]*>", self.remove_angle_brackets_from_uris, text) log.debug("Saw an event: %s" % pprint.pformat(event)) msg = Message(text, type_=message_type, extras={'attachments': event.get('attachments')}) if message_type == 'chat': msg.frm = SlackIdentifier(self.sc, user, event['channel']) msg.to = SlackIdentifier( self.sc, self.username_to_userid(self.sc.server.username), event['channel']) else: msg.frm = SlackMUCOccupant(self.sc, user, event['channel']) msg.to = SlackMUCOccupant( self.sc, self.username_to_userid(self.sc.server.username), event['channel']) self.callback_message(msg)
def build_message(self, text): msg = Message(text) msg.frm = self.bot_identifier return msg # rebuild a pure html snippet to include directly in the console html
def on_privmsg(self, _, e): msg = Message(e.arguments[0]) msg.frm = IRCPerson(e.source) msg.to = IRCPerson(e.target) self.bot.callback_message(msg)
def _message_event_handler(self, event): """Event handler for the 'message' event""" channel = event['channel'] if channel[0] not in 'CGD': log.warning("Unknown message type! Unable to handle %s", channel) return subtype = event.get('subtype', None) if subtype == "message_deleted": log.debug("Message of type message_deleted, ignoring this event") return if subtype == "message_changed" and 'attachments' in event['message']: # If you paste a link into Slack, it does a call-out to grab details # from it so it can display this in the chatroom. These show up as # message_changed events with an 'attachments' key in the embedded # message. We should completely ignore these events otherwise we # could end up processing bot commands twice (user issues a command # containing a link, it gets processed, then Slack triggers the # message_changed event and we end up processing it again as a new # message. This is not what we want). log.debug( "Ignoring message_changed event with attachments, likely caused " "by Slack auto-expanding a link") return if 'message' in event: text = event['message']['text'] user = event['message'].get('user', event.get('bot_id')) else: text = event['text'] user = event.get('user', event.get('bot_id')) mentioned = [] for word in text.split(): if word.startswith('<') or word.startswith('@') or word.startswith( '#'): try: identifier = self.build_identifier(word.replace(':', '')) except Exception as e: log.debug( "Tried to build an identifier from '%s' but got exception: %s", word, e) continue log.debug('Someone mentioned') mentioned.append(identifier) text = re.sub('<@[^>]*>:*', '@%s' % mentioned[-1].username, text) text = self.sanitize_uris(text) log.debug("Saw an event: %s" % pprint.pformat(event)) log.debug("Escaped IDs event text: %s" % text) msg = Message(text, extras={'attachments': event.get('attachments')}) if channel.startswith('D'): msg.frm = SlackPerson(self.sc, user, event['channel']) msg.to = SlackPerson( self.sc, self.username_to_userid(self.sc.server.username), event['channel']) else: msg.frm = SlackRoomOccupant(self.sc, user, event['channel'], bot=self) msg.to = SlackRoom(channelid=event['channel'], bot=self) self.callback_message(msg) if mentioned: self.callback_mention(msg, mentioned)
def _message_event_handler(self, event): """Event handler for the 'message' event""" channel = event['channel'] if channel[0] not in 'CGD': log.warning("Unknown message type! Unable to handle %s", channel) return subtype = event.get('subtype', None) if subtype in ("message_deleted", "channel_topic", "message_replied"): log.debug("Message of type %s, ignoring this event", subtype) return if subtype == "message_changed" and 'attachments' in event['message']: # If you paste a link into Slack, it does a call-out to grab details # from it so it can display this in the chatroom. These show up as # message_changed events with an 'attachments' key in the embedded # message. We should completely ignore these events otherwise we # could end up processing bot commands twice (user issues a command # containing a link, it gets processed, then Slack triggers the # message_changed event and we end up processing it again as a new # message. This is not what we want). log.debug( "Ignoring message_changed event with attachments, likely caused " "by Slack auto-expanding a link") return if 'message' in event: text = event['message'].get('text', '') user = event['message'].get('user', event.get('bot_id')) else: text = event.get('text', '') user = event.get('user', event.get('bot_id')) text, mentioned = self.process_mentions(text) text = self.sanitize_uris(text) log.debug("Saw an event: %s" % pprint.pformat(event)) log.debug("Escaped IDs event text: %s" % text) msg = Message( text, extras={ 'attachments': event.get('attachments'), 'slack_event': event, }, ) if channel.startswith('D'): if subtype == "bot_message": msg.frm = SlackBot(self.sc, bot_id=event['bot_id'], bot_username=event.get('username', '')) else: msg.frm = SlackPerson(self.sc, user, event['channel']) msg.to = SlackPerson( self.sc, self.username_to_userid(self.sc.server.username), event['channel']) channel_link_name = event['channel'] else: if subtype == "bot_message": msg.frm = SlackRoomBot(self.sc, bot_id=event['bot_id'], bot_username=event.get('username', ''), channelid=event['channel'], bot=self) else: msg.frm = SlackRoomOccupant(self.sc, user, event['channel'], bot=self) msg.to = SlackRoom(channelid=event['channel'], bot=self) channel_link_name = msg.to.name msg.extras[ 'url'] = 'https://{domain}.slack.com/archives/{channelid}/p{ts}'.format( domain=self.sc.server.domain, channelid=channel_link_name, ts=self._ts_for_message(msg).replace('.', '')) self.callback_message(msg) if mentioned: self.callback_mention(msg, mentioned)
def serve_forever(self): self.readline_support() if not self._rooms: # artificially join a room if None were specified. self.query_room('#testroom').join() if self.demo_mode: # disable the console logging once it is serving in demo mode. root = logging.getLogger() root.removeHandler(console_hdlr) root.addHandler(logging.NullHandler()) self.connect_callback() # notify that the connection occured self.callback_presence(Presence(identifier=self.user, status=ONLINE)) self.send_message(Message(INTRO)) try: while True: if self._inroom: frm = TextOccupant(self.user, self.rooms[0]) to = self.rooms[0] else: frm = self.user to = self.bot_identifier print() full_msg = '' while True: prompt = '[␍] ' if full_msg else '>>> ' if ANSI or self.demo_mode: color = fg.red if self.user.person in self.bot_config.BOT_ADMINS[ 0] else fg.green prompt = f'{color}[{frm} ➡ {to}] {fg.cyan}{prompt}{fx.reset}' entry = input(prompt) else: entry = input(f'[{frm} ➡ {to}] {prompt}') if not self._multiline: full_msg = entry break if not entry: break full_msg += entry + '\n' msg = Message(full_msg) msg.frm = frm msg.to = to self.callback_message(msg) mentioned = [ self.build_identifier(word) for word in re.findall(r'(?<=\s)@[\w]+', entry) ] if mentioned: self.callback_mention(msg, mentioned) sleep(.5) except EOFError: pass except KeyboardInterrupt: pass finally: # simulate some real presence self.callback_presence( Presence(identifier=self.user, status=OFFLINE)) log.debug("Trigger disconnect callback") self.disconnect_callback() log.debug("Trigger shutdown") self.shutdown()