def messageHandler(self, msg): if(self.opt('matrix.debug')): self.log.debug(str(msg)) try: # Create a new Message to send to Sibyl u = self.new_user(msg['sender'], Message.GROUP) r = self.new_room(msg['room_id']) msgtype = msg['content']['msgtype'] if(msgtype == 'm.text'): m = Message(u, msg['content']['body'], room=r, typ=Message.GROUP) self.log.debug('Handling m.text: ' + msg['content']['body']) self.msg_queue.put(m) elif(msgtype == 'm.emote'): m = Message(u, msg['content']['body'], room=r, typ=Message.GROUP, emote=True) self.log.debug('Handling m.emote: ' + msg['content']['body']) self.msg_queue.put(m) elif(msgtype == 'm.image' or msgtype == 'm.audio' or msgtype == 'm.file' or msgtype == 'm.video'): media_url = urlparse(msg['content']['url']) http_url = self.client.api.base_url + "/_matrix/media/r0/download/{0}{1}".format(media_url.netloc, media_url.path) if(msgtype == 'm.image'): body = "{0} uploaded {1}: {2}".format(msg['sender'], msg['content'].get('body', 'an image'), http_url) elif(msgtype == 'm.audio'): body = "{0} uploaded {1}: {2}".format(msg['sender'], msg['content'].get('body', 'an audio file'), http_url) elif(msgtype == 'm.video'): body = "{0} uploaded {1}: {2}".format(msg['sender'], msg['content'].get('body', 'a video file'), http_url) elif(msgtype == 'm.file'): body = "{0} uploaded {1}: {2}".format(msg['sender'], msg['content'].get('body', 'a file'), http_url) m = Message(u, body, room=r, typ=Message.GROUP) self.log.debug("Handling " + msgtype + ": " + body) self.msg_queue.put(m) elif(msgtype == 'm.location'): body = "{0} sent a location: {1}".format(msg['sender'], msg['content']['geo_uri']) m = Message(u, body, room=r, typ=Message.GROUP) self.log.debug('Handling m.location: ' + body) self.msg_queue.put(m) else: self.log.debug('Not handling message, unknown msgtype') except KeyError as e: self.log.debug("Incoming message did not have all required fields: " + e.message)
def process(self): while not self.thread.msgs.empty(): mail = self.thread.msgs.get() if isinstance(mail, Exception): raise mail frm = email.utils.parseaddr(mail['From'])[1] user = MailUser(self, frm) body = mail.get_payload().split('\n')[0].strip() msg = Message(user, body) self.log.debug('Got mail from "%s"' % frm) self.bot._cb_message(msg)
def send(self,text,to,broadcast=False,frm=None,users=None, hook=True,emote=False): """send a message (this function is thread-safe)""" broadcast = (broadcast and isinstance(to,Room)) frm = (frm if broadcast else to.get_protocol().get_user()) users = (users if broadcast else None) msg = Message(frm,text, to=to, broadcast=broadcast, users=users, hook=hook, emote=emote) self.__pending_send.put(msg)
def process(self): if not self.event_data.is_set(): return (address, text) = self.queue.get() usr = Client(self, address) if self.special_cmds(text): return msg = Message(usr, text) self.bot._cb_message(msg) if self.queue.empty(): self.event_data.clear()
def process(self): # every time SibylBot calls process(), this method synchronously checks for # new messages that the IMAPThread added while we were doing other things while not self.thread.msgs.empty(): # check if there was a problem connecting and raise it syncronously mail = self.thread.msgs.get() if isinstance(mail, Exception): raise mail # parse the sender frm = email.utils.parseaddr(mail['From'])[1] user = MailUser(self, frm) # handle multi-part messages body = mail.get_payload() if isinstance(body, list): for b in body: if b.get_content_type() == 'plain': body = b.replace('\r', '').strip() if isinstance(body, list): self.log.warning( 'Ignoring multi-part from "%s"; no plaintext' % frm) self._send( 'Unable to process multi-part message; no plaintext', user) return # check for authentication key if configured if self.opt('email.key') and self.opt( 'email.key').get() not in body: self.log.warning('Invalid key from "%s"; dropping message' % user) self._send('Invalid or missing key; commands forbidden', user) continue # finish parsing the e-mail and send it body = body.split('\n')[0].strip() msg = Message(user, body) ellip = ('...' if len(body) > 20 else '') self.log.debug('mail from "%s" with body "%.20s%s"' % (user, body, ellip)) # pass the message on to the bot for command execution self.bot._cb_message(msg)
def broadcast(self,mess): """send a message to every user in a room""" (text,room,frm) = (mess.get_text(),mess.get_to(),mess.get_user()) users = self.get_occupants(room)+(mess.get_users() or []) # Matrix has no built-in broadcast, so we'll just highlight everyone s = 'all: %s --- ' % text if frm: self.log.debug('Broadcast message from: ' + str(frm)) s += frm.get_name()+' --- ' me = self.get_user() names = [u.get_name() for u in users if (u!=me and (not frm or u!=frm))] s += ', '.join(set(names)) self.send(Message(self.get_user(),s,to=room)) return s
def process(self): if not self.event_data.is_set(): return usr = Admin(self, USER) text = self.queue.get() if self.special_cmds(text): return msg = Message(usr, text) self.bot._cb_message(msg) if self.queue.empty(): self.event_data.clear() if self.bot._SibylBot__finished: self.event_close.set() self.event_proc.set()
def broadcast(self, mess): """send a message to every user in a room""" (text, room, frm) = (mess.get_text(), mess.get_to(), mess.get_user()) users = self.get_occupants(room) + (mess.get_users() or []) # XMPP has no built-in broadcast, so we'll just highlight everyone s = 'all: %s --- ' % text if frm: s += frm.get_name() + ' --- ' me = JID(self, room.get_name() + '/' + self.get_nick(room), typ=Message.GROUP) names = [ u.get_name() for u in users if (u != me and (not frm or u != frm)) ] s += ', '.join(set(names)) self.send(Message(self.get_user(), s, to=room)) return s
def _send(self, text, to): msg = Message(self.get_user(), text, to=to) self.bot.send(msg)
def callback_message(self, conn, mess): """Messages sent to the bot will arrive here. Command handling + routing is done in this function.""" typ = mess.getType() jid = mess.getFrom() props = mess.getProperties() text = mess.getBody() username = self.__get_sender_username(mess) room = None emote = False if text is None: return if typ not in ("groupchat", "chat"): self.log.debug("unhandled message type: %s" % typ) return if typ == 'groupchat': # Ignore messages from before we joined if xmpp.NS_DELAY in props: return # Ignore messages from myself room = jid.getStripped() if ((self.jid == jid) or (room in self.__get_current_mucs() and jid.getResource() == self.mucs[room]['nick'])): return # Ignore messages from users not seen by this bot real = [j.getStripped() for j in self.real_jids.values()] if (jid not in self.seen) and (jid.getStripped() not in real): self.log.info('Ignoring message from unseen guest: %s' % jid) self.log.debug("I've seen: %s" % ["%s" % x for x in self.seen.keys() + real]) return if len(text) > 40: txt = text[:40] + '...' else: txt = text self.log.debug('Got %s from %s: "%s"' % (typ, jid, txt)) typ = self.TYPES[typ] real = None if jid in self.real_jids: real = JID(self, self.real_jids[jid]) user = JID(self, jid, typ=typ, real=real) if room: room = MUC(self, room) # handle /me messages if text.startswith('/me '): text = text[3:].strip() emote = True self.bot._cb_message( Message(user, text, typ=typ, room=room, emote=emote))
real = None room = None if jid.getStripped( ) in self.__get_current_mucs() + self.__get_pending_mucs(): jid_typ = Message.GROUP room = MUC(self, jid.getStripped()) if jid in self.real_jids: real = JID(self, self.real_jids[jid]) frm = JID(self, jid, typ=jid_typ) if real: frm.set_real(real) # call SibylBot's message callback msg = Message(frm, None, typ=typ, status=status, msg=status_msg, room=room) self.bot._cb_message(msg) ################################################################################ # Helper functions ################################################################################ def __status_type_changed(self, jid, new_status_type): """Callback for tracking status types (dnd, away, offline, ...)""" self.log.debug('user %s changed status to %s' % (jid, new_status_type)) def __status_message_changed(self, jid, new_status_message): """Callback for tracking status messages (the free-form status text)""" self.log.debug('user %s updated text to %s' %
def messageHandler(self, msg): if(self.opt('matrix.debug')): self.log.debug(str(msg)) try: # Create a new Message to send to Sibyl u = self.new_user(msg['sender'], Message.GROUP) r = self.new_room(msg['room_id']) if(r in self.join_timestamps and datetime.datetime.fromtimestamp(msg['origin_server_ts']/1000, pytz.utc) < self.join_timestamps[r]): self.log.info('Message received in {} from before room join, ignoring'.format(msg['room_id'])) return None if('msgtype' in msg['content']): msgtype = msg['content']['msgtype'] if(msgtype == 'm.text'): m = Message(u, msg['content']['body'], room=r, typ=Message.GROUP) self.log.debug('Handling m.text: ' + msg['content']['body']) self.msg_queue.put(m) elif(msgtype == 'm.emote'): m = Message(u, msg['content']['body'], room=r, typ=Message.GROUP, emote=True) self.log.debug('Handling m.emote: ' + msg['content']['body']) self.msg_queue.put(m) elif(msgtype == 'm.image' or msgtype == 'm.audio' or msgtype == 'm.file' or msgtype == 'm.video'): media_url = urlparse(msg['content']['url']) http_url = self.client.api.base_url + "/_matrix/media/r0/download/{0}{1}".format(media_url.netloc, media_url.path) if(msgtype == 'm.image'): body = "{0} uploaded {1}: {2}".format(msg['sender'], msg['content'].get('body', 'an image'), http_url) elif(msgtype == 'm.audio'): body = "{0} uploaded {1}: {2}".format(msg['sender'], msg['content'].get('body', 'an audio file'), http_url) elif(msgtype == 'm.video'): body = "{0} uploaded {1}: {2}".format(msg['sender'], msg['content'].get('body', 'a video file'), http_url) elif(msgtype == 'm.file'): body = "{0} uploaded {1}: {2}".format(msg['sender'], msg['content'].get('body', 'a file'), http_url) m = Message(u, body, room=r, typ=Message.GROUP) self.log.debug("Handling " + msgtype + ": " + body) self.msg_queue.put(m) elif(msgtype == 'm.location'): body = "{0} sent a location: {1}".format(msg['sender'], msg['content']['geo_uri']) m = Message(u, body, room=r, typ=Message.GROUP) self.log.debug('Handling m.location: ' + body) self.msg_queue.put(m) else: self.log.debug('Not handling message, unknown msgtype') elif('membership' in msg): if(msg['membership'] == 'join'): self.room_occupants[r].add(self.new_user(msg['state_key'], Message.GROUP)) elif(msg['membership'] == 'leave'): self.room_occupants[r].remove(self.new_user(msg['state_key'], Message.GROUP)) except KeyError as e: self.log.debug("Incoming message did not have all required fields: " + e.message)