def run_bot(homeserver, authorize, username, password): allowed_users = authorize shell_env = os.environ.copy() shell_env['TERM'] = 'vt100' child_pid, master = pty.fork() if child_pid == 0: # we are the child os.execlpe('sh', 'sh', shell_env) pin = os.fdopen(master, 'w') stop = threading.Event() client = MatrixClient(homeserver) client.login_with_password_no_sync(username, password) # listen for invites during initial event sync so we don't miss any client.add_invite_listener(lambda room_id, state: on_invite( client, room_id, state, allowed_users)) client.listen_for_events() # get rid of initial event sync client.add_listener(lambda event: on_message(event, pin, allowed_users), event_type='m.room.message') shell_stdout_handler_thread = threading.Thread(target=shell_stdout_handler, args=(master, client, stop)) shell_stdout_handler_thread.start() while True: try: client.listen_forever() except KeyboardInterrupt: stop.set() sys.exit(0) except requests.exceptions.Timeout: logger.warn("timeout. Trying again in 5s...") time.sleep(5) except requests.exceptions.ConnectionError as e: logger.warn(repr(e)) logger.warn("disconnected. Trying again in 5s...") time.sleep(5)
content = event[u'content'] body = content[u'body'] if body.startswith("."): body = body.replace(".", "", 1) splitstuff = body.split() command = splitstuff[0] args = " ".join(splitstuff[1:]) cmd = match_command(command) if cmd in bot.commands: room.send_text(bot.commands[cmd][0](args)) else: for func, args in bot.plugs["regex"]: m = args['re'].search(body) if m: room.send_text(func(m)) elif u'invite_room_state' in event: for user in config["masters"]: if event[u'user_id'] == user: client.join_room(event[u'room_id']) print user, "asked me to join", event[u'room_id'] #else: # print dump(event) for room in rooms: rooms[room].add_listener(room_callback) while True: client.listen_for_events() sleep(0.25)
from matrix_client.client import MatrixClient import time client = MatrixClient("http://167.99.238.80:8008") # New user #token = client.register_with_password(username="******", password="******") def listener(event): print(event) # Existing user token = client.login_with_password(username="******", password="******") client.add_listener(listener) #room = client.create_room("my_room_alias") room = client.join_room("#my_room_alias:teamspeak.sigmapenguinplace.net") room.send_text("Hello!") while True: client.listen_for_events()
class MatrixBackend(ErrBot): def __init__(self, config): super().__init__(config) if not hasattr(config, 'MATRIX_HOMESERVER'): log.fatal(""" You need to specify a homeserver to connect to in config.MATRIX_HOMESERVER. For example: MATRIX_HOMESERVER = "https://matrix.org" """) sys.exit(1) self._homeserver = config.MATRIX_HOMESERVER self._username = config.BOT_IDENTITY['username'] self._password = config.BOT_IDENTITY['password'] self._api = None self._token = None def serve_once(self): def dispatch_event(event): log.info("Received event: %s" % event) if event['type'] == "m.room.member": if event['membership'] == "invite" and event['state_key'] == self._client.user_id: room_id = event['room_id'] self._client.join_room(room_id) log.info("Auto-joined room: %s" % room_id) if event['type'] == "m.room.message" and event['sender'] != self._client.user_id: sender = event['sender'] room_id = event['room_id'] body = event['content']['body'] log.info("Received message from %s in room %s" % (sender, room_id)) # msg = Message(body) # msg.frm = MatrixPerson(self._client, sender, room_id) # msg.to = MatrixPerson(self._client, self._client.user_id, room_id) # self.callback_message(msg) msg = self.build_message(body) room = MatrixRoom(room_id) msg.frm = MatrixRoomOccupant(self._api, room, sender) msg.to = room self.callback_message(msg) self.reset_reconnection_count() self.connect_callback() self._client = MatrixClient(self._homeserver) try: self._token = self._client.register_with_password(self._username, self._password,) except MatrixRequestError as e: if e.code == 400 or e.code == 403: try: self._token = self._client.login_with_password(self._username, self._password,) except MatrixRequestError: log.fatal(""" Incorrect username or password specified in config.BOT_IDENTITY['username'] or config.BOT_IDENTITY['password']. """) sys.exit(1) self._api = MatrixHttpApi(self._homeserver, self._token) self.bot_identifier = MatrixPerson(self._api) self._client.add_listener(dispatch_event) try: while True: self._client.listen_for_events() except KeyboardInterrupt: log.info("Interrupt received, shutting down...") return True finally: self.disconnect_callback() def rooms(self): rooms = [] raw_rooms = self._client.get_rooms() for rid, robject in raw_rooms: # TODO: Get the canonical alias rather than the first one from # `Room.aliases`. log.debug('Found room %s (aka %s)' % (rid, rid.aliases[0])) def send_message(self, mess): super().send_message(mess) room_id = mess.to.room.id text_content = item_url = mess.body if item_url.startswith("http://") or item_url.startswith("https://"): if item_url.endswith("gif"): self._api.send_content(room_id, item_url, "image", "m.image") return # text_content = Markdown().convert(mess.body) self._api.send_message(room_id, text_content) def connect_callback(self): super().connect_callback() def build_identifier(self, txtrep): raise Exception( "XXX" ) def build_reply(self, mess, text=None, private=False): log.info("build_reply") response = self.build_message(text) response.frm = self.bot_identifier response.to = mess.frm return response def change_presence(self, status: str = '', message: str = ''): raise Exception( "XXX" ) @property def mode(self): return 'matrix' def query_room(self, room): raise Exception( "XXX" )
def main(): global client global config global github global repo global msc_labels global logger global room_specific_data # Retrieve login information from config file with open("config.toml", "r") as f: try: config = toml.loads(f.read()) except: log_fatal("Error reading config file:") return # Configure logging # Determine whether we are using a logfile or not logging_format = "[%(levelname)s] %(asctime)s: %(message)s" if "logfile" in config["logging"]: logging.basicConfig( level=logging.INFO if config["logging"]["level"] != "DEBUG" else logging.DEBUG, format=logging_format, filename=config["logging"]["logfile"]) else: logging.basicConfig( level=logging.INFO if config["logging"]["level"] != "DEBUG" else logging.DEBUG, format=logging_format) logger = logging.getLogger() # Retrieve room-specific data if config file exists if "data_filepath" in config["bot"]: data_filepath = config["bot"]["data_filepath"] if os.path.exists(config["bot"]["data_filepath"]): with open(data_filepath, 'r') as f: room_specific_data = json.loads(f.read()) # Schedule daily summary messages per-room for room_id in room_specific_data.keys(): # Check if summaries are enabled in this room if get_room_setting(room_id, "summary_enabled") == False: continue # Check if this room has a custom summary time if get_room_setting(room_id, "summary_time"): # Set a scheduler for that time # Tag with the room ID so we can easily cancel later if necessary schedule.every().day.at(config["bot"]["daily_summary_time"]).do(send_summary, room_id).tag( room_id) # Schedule daily summary messages to rooms that do not have a custom time set_up_default_summaries() # Login to Github github = Github(config["github"]["token"]) repo = github.get_repo(config["github"]["repo"]) log_info("Connected to Github") # Get MSC-related label objects from specified Github repository labels = config["github"]["labels"] msc_labels = {label.name: label for label in repo.get_labels() if label.name in labels} # Login to Matrix and listen for messages homeserver = "https://" + config["matrix"]["user_id"].split(":")[-1] client = MatrixClient(homeserver, user_id=config["matrix"]["user_id"], token=config["matrix"]["token"]) client.add_invite_listener(invite_received) client.add_listener(event_received, event_type="m.room.message") log_info("Connected to Matrix") # Sync continuously and check time for daily summary sending while True: try: client.listen_for_events() except: log_warn("Unable to contact /sync") schedule.run_pending() time.sleep(config["matrix"]["sync_interval"]) # Wait a few seconds between syncs
class MatrixBackend(ErrBot): def __init__(self, config): super().__init__(config) if not hasattr(config, 'MATRIX_HOMESERVER'): log.fatal(""" You need to specify a homeserver to connect to in config.MATRIX_HOMESERVER. For example: MATRIX_HOMESERVER = "https://matrix.org" """) sys.exit(1) self._homeserver = config.MATRIX_HOMESERVER self._username = config.BOT_IDENTITY['username'] self._password = config.BOT_IDENTITY['password'] self._api = None self._token = None def serve_once(self): def dispatch_event(event): log.info("Received event: %s" % event) if event['type'] == "m.room.member": if event['membership'] == "invite" and event[ 'state_key'] == self._client.user_id: room_id = event['room_id'] self._client.join_room(room_id) log.info("Auto-joined room: %s" % room_id) if event['type'] == "m.room.message" and event[ 'sender'] != self._client.user_id: sender = event['sender'] room_id = event['room_id'] body = event['content']['body'] log.info("Received message from %s in room %s" % (sender, room_id)) # msg = Message(body) # msg.frm = MatrixPerson(self._client, sender, room_id) # msg.to = MatrixPerson(self._client, self._client.user_id, room_id) # self.callback_message(msg) msg = self.build_message(body) room = MatrixRoom(room_id) msg.frm = MatrixRoomOccupant(self._api, room, sender) msg.to = room self.callback_message(msg) self.reset_reconnection_count() self.connect_callback() self._client = MatrixClient(self._homeserver) try: self._token = self._client.register_with_password( self._username, self._password, ) except MatrixRequestError as e: if e.code == 400: try: self._token = self._client.login_with_password( self._username, self._password, ) except MatrixRequestError: log.fatal(""" Incorrect username or password specified in config.BOT_IDENTITY['username'] or config.BOT_IDENTITY['password']. """) sys.exit(1) self._api = MatrixHttpApi(self._homeserver, self._token) self.bot_identifier = MatrixPerson(self._api) self._client.add_listener(dispatch_event) try: while True: self._client.listen_for_events() except KeyboardInterrupt: log.info("Interrupt received, shutting down...") return True finally: self.disconnect_callback() def rooms(self): rooms = [] raw_rooms = self._client.get_rooms() for rid, robject in raw_rooms: # TODO: Get the canonical alias rather than the first one from # `Room.aliases`. log.debug('Found room %s (aka %s)' % (rid, rid.aliases[0])) def send_message(self, mess): super().send_message(mess) room_id = mess.to.room.id text_content = item_url = mess.body if item_url.startswith("http://") or item_url.startswith("https://"): if item_url.endswith("gif"): self._api.send_content(room_id, item_url, "image", "m.image") return # text_content = Markdown().convert(mess.body) self._api.send_message(room_id, text_content) def connect_callback(self): super().connect_callback() def build_identifier(self, txtrep): raise Exception("XXX") def build_reply(self, mess, text=None, private=False): log.info("build_reply") response = self.build_message(text) response.frm = self.bot_identifier response.to = mess.frm return response def change_presence(self, status: str = '', message: str = ''): raise Exception("XXX") @property def mode(self): return 'matrix' def query_room(self, room): raise Exception("XXX")