def __init__(self, settings): self.sync_token = None self.logger = utils.get_logger() self.cache = utils.create_cache(settings) self.cache_timeout = int(settings["memcached"]["timeout"]) self.settings = settings self.period = settings["DEFAULT"]["period"] self.uri = settings["matrix"]["uri"] self.username = settings["matrix"]["username"].lower() self.password = settings["matrix"]["password"] self.room_ids = settings["matrix"]["rooms"] self.domain = self.settings["matrix"]["domain"] self.only_local_domain = self.settings["matrix"]["only_local_domain"] self.subscriptions_room_ids = settings["subscriptions"].keys() self.revokations_rooms_ids = settings["revokations"].keys() self.allowed_join_rooms_ids = filter(lambda x: x != 'default', settings["allowed-join"].keys()) self.default_allowed_join_rooms = settings["allowed-join"]["default"] self.client = MatrixClient(self.uri) self.token = self.client.login_with_password(username=self.username, password=self.password) self.api = MatrixHttpApi(self.uri, token=self.token) self.rooms = [] self.room_aliases = {} self.plugins = [] for plugin in settings['plugins'].itervalues(): mod = __import__(plugin['module'], fromlist=[plugin['class']]) klass = getattr(mod, plugin['class']) self.plugins.append(klass(self, plugin['settings']))
def __init__(self, token, server, roomid): self.server = server self.roomid = roomid self.token = token self.APIWrapper = MatrixHttpApi("https://{}".format(self.server), token=self.token) self.next_batch = self.APIWrapper.sync().get("next_batch") print("client initialized")
class MatrixClient: """ Provides minimal interface to MatrixHttpApi and holds its state. :param server: Matrix server to use. :param token: Matrix token. :param room: Room id for sending data. """ def __init__(self, server: str, token: str, room: str): """Construct a new MatrixClient and init and sync MatrixHttpApi.""" self.server = server self.token = token self.room = room self.api = MatrixHttpApi(self.server, token=self.token) self.api.initial_sync() def send_event(self, event_type: str, content: dict): """Send an event of arbitrary type.""" return self.api.send_message_event(self.room, event_type, content) @staticmethod def get_token(server: str, user: str, password: str) -> str: """Get an access_token via password login.""" return MatrixHttpApi(server).login("m.login.password", user=user, password=password)
def handleNotification(): req = request.get_json() print(req) matrix = MatrixHttpApi(HOMESERVER, token=req['notification']['devices'][0]['pushkey']) print(matrix.send_message_event(room_id=ROOMID, event_type='net.terracrypt.matrix.push', content=req)) return jsonify({})
def announce(text, token, room=None): from matrix_client.api import MatrixHttpApi matrix = MatrixHttpApi("https://matrix.org", token=token) matrix.sync() roomid = matrix.get_room_id(room) matrix.join_room(roomid) matrix.send_message(roomid, text)
class Matrix: def __init__(self): logger.info('logging in to Matrix as %s', config.matrix.username) self._client = MatrixClient(config.matrix.server) self._token = self._client.login(username=config.matrix.username, password=config.matrix.password, sync=False) self._api = MatrixHttpApi(config.matrix.server, self._token) def send_text(self, room_id, text): self._api.send_message(room_id, text) def send_notice_html(self, room_id, text): content = dict( body=text, format='org.matrix.custom.html', formatted_body=text, msgtype=MsgType.NOTICE ) self._api.send_message_event(room_id, event_type='m.room.message', content=content) def send_text_html(self, room_id, text): content = dict( body=text, format='org.matrix.custom.html', formatted_body=text, msgtype=MsgType.TEXT ) self._api.send_message_event(room_id, event_type='m.room.message', content=content) def send_notice(self, room_id, text): self._api.send_notice(room_id, text)
def main(config): # setup api/endpoint matrix = MatrixHttpApi(config.base_url, config.token) log.debug("Setting up plugins...") plugins = [ SmartHomePlugin # TimePlugin, # Base64Plugin, # GuessNumberPlugin, # #JiraPlugin, # UrlPlugin, # #GithubPlugin, # #JenkinsPlugin, # PrometheusPlugin, ] # setup engine engine = Engine(matrix, config) for plugin in plugins: engine.add_plugin(plugin) engine.setup() while True: try: log.info("Listening for incoming events.") engine.event_loop() except Exception as e: log.error("Ruh roh: %s", e) time.sleep(5) log.info("Terminating.")
def main(config): # setup api/endpoint matrix = MatrixHttpApi(config.base_url, config.token) log.debug("Setting up plugins...") plugins = [ ToDoPlugin, UrlPlugin, GuessNumberPlugin, ] # setup engine engine = Engine(matrix, config) for plugin in plugins: engine.add_plugin(plugin) engine.setup() while True: try: log.info("Listening for incoming events.") engine.event_loop() except Exception as e: log.error("Ruh roh: %s", e) time.sleep(5)
def _get_matrix(): try: return g.matrix except AttributeError: g.matrix = MatrixHttpApi('https://matrix.org', token=current_app.config['MATRIX_TOKEN']) return g.matrix
def __init__(self, server: str, token: str, room: str): """Construct a new MatrixClient and init and sync MatrixHttpApi.""" self.server = server self.token = token self.room = room self.api = MatrixHttpApi(self.server, token=self.token) self.api.initial_sync()
def announce(text, cred): matrix = MatrixHttpApi(cred.get("url", "https://matrix.org"), token=cred['access_token']) for room in cred['rooms']: roomid = matrix.get_room_id(room) matrix.join_room(roomid) if not cred.get('mock', False): matrix.send_message(roomid, text)
def __init__( self, base_url, room_id, username=None, password=None, token=None, use_m_text=False, format='[%(levelname)s] [%(asctime)s] [%(name)s] - %(message)s'): logging.Handler.__init__(self) self.base_url = base_url self.username = username self.password = password self.room_id = room_id self.token = token self.use_m_text = use_m_text self.matrix = MatrixHttpApi(base_url, token=self.token) self.formatter = logging.Formatter(format)
def __init__(self): self.BOTUSERNAME = "******" self.BOTPASSWORD = "******" self.BOTSERVO = "matrix.org" self.RID = "!RnpiUpFIsfzZfHdHQf:matrix.org" self.realRID = "!obQcCWaLRAUgiGBvMg:postmarketos.org" self.MainClient = MatrixClient("https://" + self.BOTSERVO) self.token = self.MainClient.login_with_password( username=self.BOTUSERNAME, password=self.BOTPASSWORD) self.APIWrapper = MatrixHttpApi("https://" + self.BOTSERVO, token=self.token) self.target_room = Room(self.MainClient, self.RID) print("ready")
def __init__(self, host=bothost, user=botuser, pwd=botpwd, room=botroom): print("Logging to matrix server...") self.chatclient = MatrixClient(host) try: self.chattoken = self.chatclient.login(username=user, password=pwd, sync=True) except MatrixRequestError as e: print(e) if e.code == 403: print("Bad username or password.") sys.exit(4) else: print("Check your sever details are correct.") sys.exit(2) except MissingSchema as e: print("Bad URL format.") print(e) sys.exit(3) self.chatapi = MatrixHttpApi(host, self.chattoken) print("Login OK") ### handle messages print("Setting up listener") try: room = self.chatclient.join_room(room) except MatrixRequestError as e: print(e) if e.code == 400: print("Room ID/Alias in the wrong format") sys.exit(11) else: print("Couldn't find room.") sys.exit(12) room.add_listener(self.on_message) self.listener_thread_id = self.chatclient.start_listener_thread() print('Listener set.. OK!')
def send_message(matrix_room, message_plain, message): ''' One day ''' # Init matrix API matrix = MatrixHttpApi(settings.MATRIX_SERVER, token=settings.MATRIX_TOKEN) try: response = matrix.send_message_event( room_id=matrix_room, event_type="m.room.message", content={ "msgtype": "m.text", "format": "org.matrix.custom.html", "body": message_plain, "formatted_body": message, } ) except MatrixRequestError as ex: LOG.error('send_message_event failure %s', ex) return json.dumps({'success': False}), 417, {'ContentType':'application/json'} LOG.debug('Matrix Response: %s', response) return json.dumps({'success': True}), 200, {'ContentType':'application/json'}
def connect(self): ''' log in to the server and get connected rooms''' password = self.config['bot']['password'] username = self.username server = self.config['bot']['host'] room_id = self.config['bot']['room'] try: BOT_LOG.debug("Trying to log in as %s pw: %s", self.username, "".join(['*' for p in password])) token = self.client.login(username, password) BOT_LOG.debug("Got Token %s..%s", token[0:3], token[-3:-1]) except MatrixRequestError as error: BOT_LOG.error("Login Failed: Code: %s, Content: %s", error.code, error.content) #this is a second connection with different interface BOT_LOG.debug("Creating matrix API endpoint") self.api = MatrixHttpApi(server, token) if str(room_id).startswith('!'): self.current_room = room_id else: self.current_room = self.get_room_id_by_name(room_id) BOT_LOG.debug("Joining room with id %s", self.current_room) self.api.join_room(self.current_room) BOT_LOG.debug("Getting member info") self.members = self.api.get_room_members(self.current_room) BOT_LOG.debug( "Members in room: %s", ",".join([ a['sender'] if 'sender' in a.keys() else "" for a in self.members['chunk'] ])) rooms = [] for _, room in self.client.get_rooms().items(): rooms.append(room) self.all_rooms = VirtualRoom(rooms)
def __init__(self, settings): self.sync_token = None self.logger = utils.get_logger() self.settings = settings self.period = settings["DEFAULT"]["period"] self.uri = settings["matrix"]["uri"] self.username = settings["matrix"]["username"].lower() self.password = settings["matrix"]["password"] self.room_ids = settings["matrix"]["rooms"] self.domain = self.settings["matrix"]["domain"] self.subscriptions_room_ids = settings["subscriptions"]["rooms"] self.revokations_rooms_ids = settings["revokations"]["rooms"] self.client = MatrixClient(self.uri) self.token = self.client.login_with_password(username=self.username, password=self.password) self.api = MatrixHttpApi(self.uri, token=self.token)
def _get_messages(request, sync_token, direction): storage = get_messages(request) for message in storage: user_name = message print("MESSAGE : ", message) print("_get_message username: "******" : ", direction) messages.add_message(request, messages.INFO, user_name) sys.stdout.flush() session = Session.objects.get(matrix_user_name=user_name.message) api = MatrixHttpApi(session.matrix_server, token=session.matrix_token) synced = api.get_room_messages(api.get_room_id(session.matrix_room_name), session.matrix_sync_token, direction, limit=session.message_count) session.matrix_sync_token = synced[sync_token] session.save() room_topic = api.get_room_topic(api.get_room_id( session.matrix_room_name))['topic'] synced['chunk'] = _parse_messages(synced['chunk']) return synced
class MatrixEngine(object): chatapi = '' chatclient = '' chattoken = '' listener_thread_id = 0 new_msg_queue = [] new_msg_senders = [] def __init__(self, host=bothost, user=botuser, pwd=botpwd, room=botroom): print("Logging to matrix server...") self.chatclient = MatrixClient(host) try: self.chattoken = self.chatclient.login(username=user, password=pwd, sync=True) except MatrixRequestError as e: print(e) if e.code == 403: print("Bad username or password.") sys.exit(4) else: print("Check your sever details are correct.") sys.exit(2) except MissingSchema as e: print("Bad URL format.") print(e) sys.exit(3) self.chatapi = MatrixHttpApi(host, self.chattoken) print("Login OK") ### handle messages print("Setting up listener") try: room = self.chatclient.join_room(room) except MatrixRequestError as e: print(e) if e.code == 400: print("Room ID/Alias in the wrong format") sys.exit(11) else: print("Couldn't find room.") sys.exit(12) room.add_listener(self.on_message) self.listener_thread_id = self.chatclient.start_listener_thread() print('Listener set.. OK!') def sendmsg(self, msg, chatid=botroom): room = self.chatclient.join_room(chatid) response = self.chatapi.send_message(chatid, msg) def sendhtml(self, msg, chatid=botroom): room = self.chatclient.join_room(chatid) room.send_html(msg) def create_room(self, alias): ex_room = matrix_mongo.matrix_chats.find_one({"alias": alias}) if ex_room: room_id = ex_room['room_id'] room = self.chatclient.join_room(room_id) room.invite_user(ebuser) else: try: aldt = datetime.datetime.strftime(datetime.datetime.now(), '%Y%m%d%H%M%S') new_room = self.chatclient.create_room(alias=alias + "_" + aldt, is_public=False, invitees=[ebuser]) room_id = new_room.room_id dtime = datetime.datetime.strftime(datetime.datetime.now(), '%Y-%m-%d %H:%M:%S') chatdata = { "created_date": dtime, "alias": alias, "room_alias": alias + "_" + aldt, "room_id": room_id, "room_data": room } recordID = matrix_mongo.matrix_chats.insert_one(chatdata) except MatrixRequestError as e: print(str(e)) return room_id def sendfile(self, filename, chatid=botroom): room = self.chatclient.join_room(chatid) with open(filename, 'rb') as datafile: data = datafile.read() uri = self.chatclient.upload(content=data, content_type='image/jpg') print(uri) filedate = datetime.datetime.strftime(datetime.datetime.now(), '%Y-%m-%d %H:%M:%S') room.send_image( uri, filedate + '_' + filename.replace('/', '_') + '.jpg') def on_message(self, room, event): try: # Called when a message is recieved. if event['type'] == "m.room.member": if event['membership'] == "join": # print("{0} joined".format(event['content']['displayname'])) dtime = datetime.datetime.strftime(datetime.datetime.now(), '%Y-%m-%d %H:%M:%S') print(dtime + " new user joined to the room ") elif event['type'] == "m.room.message": if event['content']['msgtype'] == "m.text": # print("{0}: {1}".format(event['sender'], event['content']['body'])) dtime = datetime.datetime.strftime(datetime.datetime.now(), '%Y-%m-%d %H:%M:%S') print(dtime + "| '" + event['content']['body'] + "' msg received from " + event['sender']) if event['sender'] != "@mybot:matrix.org": self.new_msg_senders.append(event['sender']) self.new_msg_queue.append(event['content']['body']) else: print('new event in room:' + event['type']) except Exception as e: print('error @ on_message: ' + str(e)) def parsemsg(self): for i in range(len(self.new_msg_queue)): origMsg = self.new_msg_queue[i] sender = self.new_msg_senders[i] msg = origMsg.lower() print("PARSER: '" + origMsg + "' msg received from " + sender) def doshit(): print('shit done') if msg == "test": doshit() elif msg == "msg": sendmsg("your msg responded!") elif msg == "html": sendhtml("your <b>html</b> message <h1>responded</h1>!") else: print("message not understood") self.new_msg_queue.remove(origMsg) self.new_msg_senders.remove(sender)
class CrawlerMatrixClient: def __init__(self, token, server, roomid): self.server = server self.roomid = roomid self.token = token self.APIWrapper = MatrixHttpApi("https://{}".format(self.server), token=self.token) self.next_batch = self.APIWrapper.sync().get("next_batch") print("client initialized") def getChunk(self): b = self.APIWrapper.get_room_messages(self.roomid, self.next_batch, "b", limit=100) c = b.get("chunk") self.next_batch = b.get("end") return c def try_recover_suspend(self, output_file, contents, timestamps, names, message_count): with open(output_file, "r") as handle: a = handle.readlines() if a[len(a)-1] == "sus": print("\n\nrestoring from suspend'\n\n") self.next_batch = a[len(a)-2] a = a[:-2] for element in a: b = element.split(";") timestamps.append(b[0]) names.append(b[1]) contents.append(b[2]) print("restored") return message_count - len(a) + 1 def suspend(self, contents, timestamps, names, output_file): print("suspending to output_file") with open(output_file, "w+") as handle: for i in range(len(contents)-1): handle.write(str(timestamps[i])) handle.write(";") handle.write(str(names[i])) handle.write(";") content = base64.b64encode(str.encode(str(contents[i]))).decode() handle.write(content) handle.write("\n") handle.write(self.next_batch) handle.write("\n") handle.write("sus") def dump_message_events(self, message_count, output_file): contents = [] timestamps = [] names = [] try: message_count = self.try_recover_suspend(output_file, contents, timestamps, names, message_count) except: pass try: count = message_count // 100 for progress in range(count): chunk = self.getChunk() for element in chunk: content = element.get("content").get("body") if content is not None: timestamps.append(element.get("origin_server_ts")) contents.append(content) names.append(element.get("sender")) print("haha progress bar go brr {} out of {}".format(progress, count), end='\r') with open(output_file, "w+") as handle: for i in range(len(contents)-1): handle.write(str(timestamps[i])) handle.write(";") handle.write(str(names[i])) handle.write(";") content = base64.b64encode(str.encode(str(contents[i]))).decode() handle.write(content) handle.write("\n") handle.write(self.next_batch) handle.write("\n") handle.write("sus") except KeyboardInterrupt: self.suspend(contents, timestamps, names, output_file)
settings = yaml.load(stream) except IOError as e: sys.exit("no settings.yaml found!") # CONSTANTS DOMAIN = settings['DOMAIN'] SERVICES = settings['SERVICES'] ROOMS = settings['ROOMS'] TOKEN = settings['TOKEN'] def online(service): stat = os.system('systemctl is-active --quiet {}'.format(service)) if not stat: return True return False matrix = MatrixHttpApi(DOMAIN, token=TOKEN) status = False for service in SERVICES: if not online(service): status = True message = "Service: '{}' is offline".format(service) print(message) for room in ROOMS: matrix.join_room(room) response = matrix.send_message(room, message) if not status: print("everything is fine")
from auth import url, host, room, token import pprint from matrix_client.api import MatrixHttpApi from matrix_client.api import MatrixRequestError pp = pprint.PrettyPrinter(indent=4) pp = pp.pprint matrix = MatrixHttpApi(host, token=token) try: # pp(matrix.get_room_state(room)) msg = input("Message : ") print(msg) print(matrix.send_message(room, msg)) except MatrixRequestError as e: print(e) if e.code == 400: print("Room ID/Alias in the wrong format") else: print("Couldn't find room.")
class MatrixBot: """The main bot, connecting to the server and handling plugins""" def __init__(self, config): self.username = config['bot']['username'] server = config['bot']['host'] self.fullname = "@" + str( self.username).lower() + ':' + urlparse(server).hostname self.plugins = [] self.api = None self.current_room = "" self.members = [] self.all_rooms = None self.config = config # Connect to server BOT_LOG.debug("creating matrix client for server %s", server) self.client = MatrixClient(server) def connect(self): ''' log in to the server and get connected rooms''' password = self.config['bot']['password'] username = self.username server = self.config['bot']['host'] room_id = self.config['bot']['room'] try: BOT_LOG.debug("Trying to log in as %s pw: %s", self.username, "".join(['*' for p in password])) token = self.client.login(username, password) BOT_LOG.debug("Got Token %s..%s", token[0:3], token[-3:-1]) except MatrixRequestError as error: BOT_LOG.error("Login Failed: Code: %s, Content: %s", error.code, error.content) #this is a second connection with different interface BOT_LOG.debug("Creating matrix API endpoint") self.api = MatrixHttpApi(server, token) if str(room_id).startswith('!'): self.current_room = room_id else: self.current_room = self.get_room_id_by_name(room_id) BOT_LOG.debug("Joining room with id %s", self.current_room) self.api.join_room(self.current_room) BOT_LOG.debug("Getting member info") self.members = self.api.get_room_members(self.current_room) BOT_LOG.debug( "Members in room: %s", ",".join([ a['sender'] if 'sender' in a.keys() else "" for a in self.members['chunk'] ])) rooms = [] for _, room in self.client.get_rooms().items(): rooms.append(room) self.all_rooms = VirtualRoom(rooms) def init_scheduler(self): ''' initialize a thread that handles the event loop for the scheduler for all plugins''' BOT_LOG.debug("Spinning up scheduler thread") self.schedule = schedule self.killswitch = Event() self.killswitch.clear() self.thread = Thread(target=self.schedule_loop, args=(self.killswitch, )) #self.thread.daemon = True self.thread.start() def stop_scheduler(self): ''' wind down the scheduler thread gracefully before exit''' BOT_LOG.debug("Trying to end scheduler thread ..") self.killswitch.set() self.thread.join() BOT_LOG.debug("..successful") def schedule_loop(self, stop_event): ''' this event loop is run inside the scheduler thread''' BOT_LOG.debug("Scheduler thread started successfully") while not stop_event.is_set(): #BOT_LOG.debug("Scheduler loop runs") self.schedule.run_pending() sleep(10) def add_plugin(self, plugin): """Puts a plugin in the internal list where it will be registered as a listener""" self.plugins.append(plugin) def get_room_id_by_name(self, name): """Translate human-readable room name into internal room id""" BOT_LOG.debug("Getting room ID for name '%s'", name) if str(name).startswith('#'): rid = self.api.get_room_id(name) else: rid = self.api.get_room_id('#' + name) if rid is None: BOT_LOG.warning("Room name '%s' not found", name) rid = "" return rid def send(self, text): """Sending initial message to room to announce startup""" BOT_LOG.debug("Sending sample text to room") self.api.send_message(self.current_room, text) def start_polling(self): """Starts syncing and polling for new messages in a new thread""" # Starts polling for messages self.client.start_listener_thread() return self.client.sync_thread def register_listeners(self): ''' register the added plugins as listeners into the rooms the bot si connected to''' rooms = [] for room_id, room in self.client.get_rooms().items(): BOT_LOG.debug("Registering plugins in room %s (%s)", room.name, room_id) rooms.append(room) for plugin in self.plugins: room.add_listener(plugin.handle_message)
def startup(config): # setup api/endpoint login = config.json['user_id'][1:].split(":")[0] if not config.json['token']: matrix = MatrixHttpApi(config.json['url']) matrix.validate_certificate(config.json['cert_verify']) try: res = matrix.login(login_type="m.login.password", user=login, password=config.json['password']) except MatrixRequestError as err: log.error("Login error: %r" % err) exit() log.debug("Login result: %r" % res) config.json['token'] = res["access_token"] matrix.token = config.json['token'] else: matrix = MatrixHttpApi(config.json['url'], config.json['token']) matrix.validate_certificate(config.json['cert_verify']) config.save() # Update Display Name if needed cur_dn = matrix.get_display_name(config.json['user_id']) if not login == cur_dn: matrix.set_display_name(config.json['user_id'], login) # root path for plugin search and locale load config.rootf = os.path.dirname(os.path.abspath(matrix_bot.__file__)) log.debug("Matrix_bot root folder: %s" % config.rootf) log.debug("Matrix_bot configuration: %s" % json.dumps(config.json, indent=4, sort_keys=True)) # setup engine engine = Engine(matrix, config) # Dytnamic plugin load from plugins folder osppath = os.path.join(config.rootf, "plugins") lst = os.listdir(osppath) for fil in lst: name, ext = os.path.splitext(fil) if (not os.path.isdir(os.path.join(osppath, fil)) and not fil[0] == "_" and ext in (".py")): try: mod = __import__("matrix_bot.plugins." + name, fromlist=["*"]) for cls in inspect.getmembers(mod, inspect.isclass): if hasattr(cls[1], "name"): if not config.json['plugins'] or cls[ 1].name in config.json['plugins']: engine.add_plugin(cls[1]) log.info("Load plugin %s (%s) from %s" % (cls[1].name, cls[0], os.path.join("plugins", fil))) else: log.info( "Skip plugin %s (%s) from %s - not listed in config" % (cls[1].name, cls[0], os.path.join("plugins", fil))) except ImportError as err: log.error("Plugin module %s import error: %r" % ("plugins." + fil, err)) engine.setup() while True: try: log.info("Listening for incoming events.") engine.event_loop() except Exception as e: log.error("Ruh roh: %s", e) time.sleep(5) log.info("Terminating.")
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")
if homeserver.endswith('/'): homeserver = homeserver[:-1] if username.startswith('@'): username = username[1:] if username.find(':') > 0: username = username.split(':')[0] matrix = None for retry in range(0, 4): try: client = MatrixClient(homeserver) token = client.login(username, password) matrix = MatrixHttpApi(homeserver, token) break except MatrixHttpLibError: sys.stderr.write('Connection failed, retrying...\n') time.sleep(0.25) if matrix == None: sys.stderr.write('Could not connect to homeserver. Message not sent.\n') sys.exit(-2) try: client.rooms[room_id].send_text(message) except: sys.stderr.write('Failed to send message to room.\n') sys.exit(-3)
class MatrixBot(): def __init__(self, settings): self.sync_token = None self.logger = utils.get_logger() self.cache = utils.create_cache(settings) self.cache_timeout = int(settings["memcached"]["timeout"]) self.settings = settings self.period = settings["DEFAULT"]["period"] self.uri = settings["matrix"]["uri"] self.username = settings["matrix"]["username"].lower() self.password = settings["matrix"]["password"] self.room_ids = settings["matrix"]["rooms"] self.domain = self.settings["matrix"]["domain"] self.only_local_domain = self.settings["matrix"]["only_local_domain"] self.subscriptions_room_ids = settings["subscriptions"].keys() self.revokations_rooms_ids = settings["revokations"].keys() self.allowed_join_rooms_ids = filter(lambda x: x != 'default', settings["allowed-join"].keys()) self.default_allowed_join_rooms = settings["allowed-join"]["default"] self.client = MatrixClient(self.uri) self.token = self.client.login_with_password(username=self.username, password=self.password) self.api = MatrixHttpApi(self.uri, token=self.token) self.rooms = [] self.room_aliases = {} self.plugins = [] for plugin in settings['plugins'].itervalues(): mod = __import__(plugin['module'], fromlist=[plugin['class']]) klass = getattr(mod, plugin['class']) self.plugins.append(klass(self, plugin['settings'])) def _get_selected_users(self, groups_users_list): def _add_or_remove_user(users, username, append): username = self.normalize_user_id(username) if append and username not in users["in"]: users["in"].append(username) if not append and username not in users["out"]: users["out"].append(username) ldap_settings = self.settings["ldap"] append = True users = {"in": [], "out": []} for item in groups_users_list: if item == ("but"): append = False elif item.startswith("+"): group_name = item[1:] groups_members = bot_ldap.get_ldap_groups_members( ldap_settings) if group_name in groups_members.keys(): map(lambda x: _add_or_remove_user(users, x, append), groups_members[group_name]) else: _add_or_remove_user(users, item, append) selected_users = filter(lambda x: x not in users["out"], users["in"]) return selected_users def normalize_user_id(self, user_id): if not user_id.startswith("@"): user_id = "@" + user_id self.logger.debug("Adding missing '@' to the username: %s" % user_id) if user_id.count(":") == 0: user_id = "%s:%s" % (user_id, self.domain) return user_id def get_user_id(self, username=None, normalized=True): if not username: username = self.username normalized_username = self.normalize_user_id(username) if normalized: return normalized_username else: return normalized_username[1:].split(':')[0] def is_local_user_id(self, username): normalized_username = self.get_user_id(username, normalized=True) if normalized_username.split(':')[1] == self.domain: return True return False def get_real_room_id(self, room_id): if room_id.startswith("#"): room_id = self.api.get_room_id(room_id) return room_id def get_room_members(self, room_id): key = "get_room_members-%s" % room_id res = self.cache.get(key) if res: self.logger.debug("get_room_members (cached): %s" % (key)) return res res = self.call_api("get_room_members", 2, room_id) self.cache.set(key, res, self.cache_timeout) self.logger.debug("get_room_members (non cached): %s" % (key)) return res def is_room_member(self, room_id, user_id): try: r = Room(self.client, room_id) return user_id in r.get_joined_members().keys() except Exception, e: return False return False
Info: {HOSTOUTPUT} When: {LONGDATETIME} {COMMENT_PLAIN} {ICINGA_WEBURL}/monitoring/host/show?host={HOSTNAME} """.format(**DATA) # Message in markdown MSG_MD = """**<font color="{COLOR}">[{NOTIFICATIONTYPE}] Host {HOSTDISPLAYNAME} is {HOSTSTATE}</font>** > *Info:* > > {HOSTOUTPUT} {COMMENT_MD} > *{LONGDATETIME} - [Show in Icinga2]({ICINGA_WEBURL}/monitoring/host/show?host={HOSTNAME})* """.format(**DATA) # Init matrix API matrix = MatrixHttpApi(environ['MATRIX_SERVER'], token=environ['MATRIX_TOKEN']) # Send message in both formats to channel response = matrix.send_message_event( room_id=environ['MATRIX_CHANNEL'], event_type="m.room.message", content={ "msgtype": "m.text", "format": "org.matrix.custom.html", "body": MSG_PLAIN, "formatted_body": Markdown().convert(MSG_MD), } )
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 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 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 __init__(self): logger.info('logging in to Matrix as %s', config.matrix.username) self._client = MatrixClient(config.matrix.server) self._token = self._client.login(username=config.matrix.username, password=config.matrix.password, sync=False) self._api = MatrixHttpApi(config.matrix.server, self._token)
def matrix_sender(homeserver: str, token: str, room: str): """ Matrix sender wrapper: execute func, send a Matrix message with the end status (sucessfully finished or crashed) at the end. Also send a Matrix message before executing func. `homeserver`: str The homeserver address which was used to register the BOT. It is e.g. 'https://matrix-client.matrix.org'. It can be also looked up in Riot by looking in the riot settings, "Help & About" at the bottom. Specifying the schema (`http` or `https`) is required. `token`: str The access TOKEN of the user that will send the messages. It can be obtained in Riot by looking in the riot settings, "Help & About" , down the bottom is: Access Token:<click to reveal> `room`: str The alias of the room to which messages will be send by the BOT. After creating a room, an alias can be set. In Riot, this can be done by opening the room settings under 'Room Addresses'. """ matrix = MatrixHttpApi(homeserver, token=token) room_id = matrix.get_room_id(room) def decorator_sender(func): def send_message(text, room_id=room_id): matrix.send_message(room_id, text) @functools.wraps(func) def wrapper_sender(*args, **kwargs): start_time = datetime.datetime.now() host_name = socket.gethostname() func_name = func.__name__ text = "" if include_details: text += f'{func_name} called on {host_name} at {start_time.strftime(DATE_FORMAT)}' if message: text += f'{func_name}: {message}' if not include_details else f'\nMessage: {message}' if notify_end: text += '\nWe\'ll let you know when it\'s done.' send_message(text=text) try: value = func(*args, **kwargs) if notify_end: end_time = datetime.datetime.now() elapsed_time = end_time - start_time text = "" text += f'✅ {func_name} finished on {host_name} at {end_time.strftime(DATE_FORMAT)}' text += f'\nDuration: {elapsed_time}' try: str_value = str(value) text += f'\nReturned value: {str_value}' except: text += f'\nReturned value: ERROR - Couldn\'t parse the returned value.' send_message(text=text) return value except Exception as ex: end_time = datetime.datetime.now() elapsed_time = end_time - start_time contents = [f"☠️ {func_name} has crashed on {host_name} at {end_time.strftime(DATE_FORMAT)}", "Here's the error:", '%s\n\n' % ex, "Traceback:", '%s' % traceback.format_exc()] text = '\n'.join(contents) send_message(text=text) raise ex return wrapper_sender return decorator_sender
def matrix_sender(homeserver: str, token: str, room: str): """ Matrix sender wrapper: execute func, send a Matrix message with the end status (sucessfully finished or crashed) at the end. Also send a Matrix message before executing func. `homeserver`: str The homeserver address which was used to register the BOT. It is e.g. 'https://matrix-client.matrix.org'. It can be also looked up in Riot by looking in the riot settings, "Help & About" at the bottom. Specifying the schema (`http` or `https`) is required. `token`: str The access TOKEN of the user that will send the messages. It can be obtained in Riot by looking in the riot settings, "Help & About" , down the bottom is: Access Token:<click to reveal> `room`: str The alias of the room to which messages will be send by the BOT. After creating a room, an alias can be set. In Riot, this can be done by opening the room settings under 'Room Addresses'. """ matrix = MatrixHttpApi(homeserver, token=token) room_id = matrix.get_room_id(room) def decorator_sender(func): @functools.wraps(func) def wrapper_sender(*args, **kwargs): start_time = datetime.datetime.now() host_name = socket.gethostname() func_name = func.__name__ # Handling distributed training edge case. # In PyTorch, the launch of `torch.distributed.launch` sets up a RANK environment variable for each process. # This can be used to detect the master process. # See https://github.com/pytorch/pytorch/blob/master/torch/distributed/launch.py#L211 # Except for errors, only the master process will send notifications. if 'RANK' in os.environ: master_process = (int(os.environ['RANK']) == 0) host_name += ' - RANK: %s' % os.environ['RANK'] else: master_process = True if master_process: contents = [ 'Your training has started 🎬', 'Machine name: %s' % host_name, 'Main call: %s' % func_name, 'Starting date: %s' % start_time.strftime(DATE_FORMAT) ] text = '\n'.join(contents) matrix.send_message(room_id, text) try: value = func(*args, **kwargs) if master_process: end_time = datetime.datetime.now() elapsed_time = end_time - start_time contents = [ "Your training is complete 🎉", 'Machine name: %s' % host_name, 'Main call: %s' % func_name, 'Starting date: %s' % start_time.strftime(DATE_FORMAT), 'End date: %s' % end_time.strftime(DATE_FORMAT), 'Training duration: %s' % str(elapsed_time) ] try: str_value = str(value) contents.append('Main call returned value: %s' % str_value) except: contents.append( 'Main call returned value: %s' % "ERROR - Couldn't str the returned value.") text = '\n'.join(contents) matrix.send_message(room_id, text) return value except Exception as ex: end_time = datetime.datetime.now() elapsed_time = end_time - start_time contents = [ "Your training has crashed ☠️", 'Machine name: %s' % host_name, 'Main call: %s' % func_name, 'Starting date: %s' % start_time.strftime(DATE_FORMAT), 'Crash date: %s' % end_time.strftime(DATE_FORMAT), 'Crashed training duration: %s\n\n' % str(elapsed_time), "Here's the error:", '%s\n\n' % ex, "Traceback:", '%s' % traceback.format_exc() ] text = '\n'.join(contents) matrix.send_message(room_id, text) raise ex return wrapper_sender return decorator_sender