def send_msg(server_name, username, password, room_id, msg): client = MatrixClient(server_name) client.login(username=username, password=password) room = client.join_room(room_id) room.send_text(msg) client.logout()
def sendFunc(msgStr): # try to send a message (msgStr) via matrix protocol try: # try to read the updated credentials from a file received using previous function try: with open('updts.txt') as updts: updates = updts.read() decryptedDic = dcryptFunc(updates) martixServer = decryptedDic['martixServer'] username = decryptedDic['username'] password = decryptedDic['password'] roomAddr = decryptedDic['roomAddr'] client = MatrixClient(martixServer) token = client.login(username=username, password=password) room = client.join_room(roomAddr) room.send_text(msgStr) client.logoout() # if reading from file failed, probably due to file not being available, # connect to matrix server using hardcoded credentials except: client = MatrixClient("https://matrix.org") token = client.login(username="******", password="******") room = client.join_room( "Your_matrix_room_id") # find it in room's advanced settings room.send_text(msgStr) client.logoout() # if matrix network was not available, like the time it got hacked on April, 2019(!) # send the message via Dropbox except: dropIt(msgStr)
def process_jenkins_request(): check_token('X-Jenkins-Token') msgtype = get_msg_type() room = get_a_room() jenkins_event = request.headers.get("X-Jenkins-Event") if jenkins_event == "Post Build Hook": try: client = MatrixClient(cfg["matrix"]["server"]) client.login(username=cfg["matrix"]["username"], password=cfg["matrix"]["password"]) room = client.join_room(room_id_or_alias=room) except MatrixRequestError as e: return matrix_error(e) def extract_change_message(change): change_message = next(iter_first_line(change["message"]), "") if len(change_message) > 0: htimestamp = datetime.fromtimestamp( change['timestamp'] / 1000).strftime("%d. %b %y %H:%M") return f"{shorten(change_message)} " \ f"({shorten(change['commitId'], 7, appendix='')}) " \ f"by {change['author']} " \ f"at {htimestamp}" else: return shorten(json.dumps(change), appendix="...}") build_name = request.json["displayName"] project_name = request.json["project"]["fullDisplayName"] result_type = request.json["result"]["type"] result_color = request.json["result"]["color"] change_messages = list( map(extract_change_message, request.json["changes"])) html_changes = "\n".join( (f" <li>{msg}</li>" for msg in change_messages)) text_changes = "\n".join((f"- {msg}" for msg in change_messages)) try: room.send_html( f"<p><strong>Build {build_name} on project {project_name} complete: " f"<font color=\"{result_color}\">{result_type}</font></strong>, " f"{len(change_messages)} commits</p>\n" "" + (f"<ul>\n{html_changes}\n</ul>\n" if len(change_messages) > 0 else ""), body= f"**Build {build_name} on project {project_name} complete: {result_type}**, " f"{len(change_messages)} commits\n" "" + (f"{text_changes}\n" if len(change_messages) > 0 else ""), msgtype=msgtype) except MatrixRequestError as e: return matrix_error(e) # see Flask.make_response, this is interpreted as (body, status) return "", 204
class Matrix(object): def __init__(self, main): self.main = main self.login = login self.client = MatrixClient(address, encryption=encryption) self.client.login(login, passwd, device_id=device_id) self.rooms = [] self.room_data = {} for room_id, room in self.client.get_rooms().items(): self.main.system(f'add matrix room {room_id}') self.rooms.append(room_id) self.room_data[room_id] = { 'history': [], 'last_read': 0, 'name': room.name or room_id, 'topic': room.topic or '', } for event in room.events: if event['type'] == 'm.room.message': self.room_data[room_id]['history'].append( self.event_to_history(event)) if chan in room.aliases: self.main.active_room_idx = len(self.rooms) - 1 self.main.active_account_idx = 1 room.add_listener(self.listener) self.client.start_listener_thread() def __str__(self): return f'Matrix {self.login}' def event_to_history(self, event): self.add_sender(event['sender']) return datetime.fromtimestamp( event['origin_server_ts'] / 1000), event['sender'], event['content']['body'] def add_sender(self, sender): if sender not in self.main.users: self.main.users[sender] = self.client.api.get_display_name(sender) def listener(self, room, event): if event['type'] == 'm.room.message': history = self.room_data[room.room_id]['history'] history.append(self.event_to_history(event)) if self.main.account == self and room.room_id == self.main.room_id: self.main.update_text(history) else: self.main.system(str(event)) def send(self, text, room_id): self.client.rooms[room_id].send_text(text)
def test_enable_encryption(): pytest.importorskip('olm') client = MatrixClient(HOSTNAME, encryption=True) login_path = HOSTNAME + MATRIX_V2_API_PATH + "/login" responses.add(responses.POST, login_path, json=response_examples.example_success_login_response) upload_path = HOSTNAME + MATRIX_V2_API_PATH + '/keys/upload' responses.add(responses.POST, upload_path, body='{"one_time_key_counts": {}}') client.login("@example:localhost", "password", sync=False) assert client.olm_device
def __init__(self, server, username, password, rooms, nick=None): client = MatrixClient(server) self.viewer_url = server.strip('/') + "/_matrix/media/v1/download/" try: client.login(username, password, sync=False) except MatrixRequestError as e: if e.code == 403: logger.error("403 Bad username or password.") sys.exit(4) else: logger.error("{} Check your server details are correct.".format(e)) sys.exit(2) except MissingSchema as e: logger.error("{} Bad URL format.".format(e)) sys.exit(3) self.username = client.user_id logger.info("logged in as: {}".format(self.username)) if nick is not None: u = client.get_user(client.user_id) logger.info("Setting display name to {}".format(nick)) try: u.set_display_name(nick) except MatrixRequestError as e: logger.error("Fail to set display name: error = {}".format(e)) self.joined_rooms = {} self.room_id_to_alias = {} self.displaynames = {} for room_id_alias in rooms: try: room = client.join_room(room_id_alias) except MatrixRequestError as e: if e.code == 400: logger.error("400 Room ID/Alias in the wrong format") sys.exit(11) else: logger.error("{} Couldn't find room {}".format(e, room_id_alias)) sys.exit(12) logger.info("Joined room {}".format(room_id_alias)) self.joined_rooms[room_id_alias] = room self.room_id_to_alias[room.room_id] = room_id_alias room.add_listener(self.on_message) self.client = client self.bot_msg_pattern = config['matrix'].get('bot_msg_pattern', None)
def connect(host, user_id, password): global client try: client = MatrixClient(host, encryption=True, restore_device_id=True) client.login(username=user_id, password=password, sync=False) #client.start_listener_thread(timeout_ms=30000, exception_handler=None) #client.bad_sync_timeout_limit = 0 #client.start_listener_thread() #client.should_listen=30000 client.add_key_forward_listener( lambda x: writetolog('got new keys' + x)) except: logging.exception('') quit() return (client)
def example(host, user, password, token): """run the example.""" client = None try: if token: print('token login') client = MatrixClient(host, token=token) else: print('password login') client = MatrixClient(host) token = client.login(user, password) print('got token: %s' % token) except MatrixRequestError as e: print(e) if e.code == 403: print("Bad username or password") exit(2) elif e.code == 401: print("Bad username or token") exit(3) else: print("Verify server details.") exit(4) except MissingSchema as e: print(e) print("Bad formatting of URL.") exit(5) except InvalidSchema as e: print(e) print("Invalid URL schema") exit(6) print("is in rooms") for room_id, room in client.get_rooms().items(): print(room_id)
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)
class Logger: address: str port: int token: str room: dict def __init__(self, *args, **kwargs): self.address, self.port = args[0] _room_name = args[1] _room = LOGGER[_room_name] if 'username' not in kwargs: kwargs.update({'username': _room["user"]}) if 'password' not in kwargs: kwargs.update({'password': _room["password"]}) try: # TODO: Make also dynamic self._client = MatrixClient(f"http://localhost:8008") self.token = self._client.login(**kwargs) self.room = self._client.join_room(_room_name) except MatrixHttpLibError as matrix_error: logging.error(matrix_error) def log(self, message): # TODO: Allow reconnection with room name as param if not self.token: logging.error( f"MatrixClient was not properly intialized. No log can be done" ) return logging.info(f"Sending {message} to {self.room}") self.room.send_text(message)
def matrix_connect(): global log global lock client = MatrixClient(conf.matrix_server) try: token = client.login(username=conf.matrix_username, password=conf.matrix_password, device_id=conf.matrix_device_id) except MatrixRequestError as e: log.error(e) log.debug(e) if e.code == 403: log.error("Bad username or password.") return None else: log.error("Check your sever details are correct.") return None except MatrixHttpLibError as e: log.error(e) return None except MissingSchema as e: log.error("Bad URL format.") log.error(e) log.debug(e) return None except: log.error("unknown error at client.login()") return None return client
def process_gitlab_request(): check_token('X-Gitlab-Token') msgtype = get_msg_type() room = get_a_room() gitlab_event = request.headers.get("X-Gitlab-Event") if gitlab_event == "Push Hook": try: client = MatrixClient(cfg["matrix"]["server"]) client.login(username=cfg["matrix"]["username"], password=cfg["matrix"]["password"]) room = client.join_room(room_id_or_alias=room) except MatrixRequestError as e: return matrix_error(e) def sort_commits_by_time(commits): return sorted(commits, key=lambda commit: commit["timestamp"]) def extract_commit_info(commit): msg = shorten( next(iter_first_line(commit["message"]), "$EMPTY_COMMIT_MESSAGE - impossibruh")) url = commit["url"] return msg, url username = request.json["user_name"] commit_messages = list( map(extract_commit_message, sort_commits_by_time(request.json["commits"]))) project_name = request.json["project"]["name"] html_commits = "\n".join((f' <li><a href="{url}">{msg}</a></li>' for (msg, url) in commit_messages)) text_commits = "\n".join( (f"- [{msg}]({url})" for (msg, url) in commit_messages)) try: room.send_html( f"<strong>{username} pushed {len(commit_messages)} commits to {project_name}</strong><br>\n" f"<ul>\n{html_commits}\n</ul>\n", body= f"{username} pushed {len(commit_messages)} commits to {project_name}\n{text_commits}\n", msgtype=msgtype) except MatrixRequestError as e: return matrix_error(e) # see Flask.make_response, this is interpreted as (body, status) return "", 204
def run_module(): module_args = dict( msg_plain=dict(type='str', required=True), msg_html=dict(type='str', required=True), room_id=dict(type='str', required=True), hs_url=dict(type='str', required=True), token=dict(type='str', required=False, no_log=True), user_id=dict(type='str', required=False), password=dict(type='str', required=False, no_log=True), ) result = dict(changed=False, message='') module = AnsibleModule(argument_spec=module_args, mutually_exclusive=[['password', 'token']], required_one_of=[['password', 'token']], required_together=[['user_id', 'password']], supports_check_mode=True) if not matrix_found: module.fail_json( msg= "Python 'matrix-client' module is required. Install via: $ pip install matrix-client" ) if module.check_mode: return result # create a client object client = MatrixClient(module.params['hs_url']) if module.params['token'] is not None: client.api.token = module.params['token'] else: client.login(module.params['user_id'], module.params['password'], sync=False) # make sure we are in a given room and return a room object for it room = client.join_room(module.params['room_id']) # send an html formatted messages room.send_html(module.params['msg_html'], module.params['msg_plain']) module.exit_json(**result)
def __init__(self): print("Initializing client...") client = MatrixClient("https://matrix.org") print("Loggin in...") token = client.login(credentials["login"], credentials["password"]) print("Reinitializing client") self.client = MatrixClient("https://matrix.org", token=token, user_id="@isbur:matrix.org") print("Entering the room...") self.room = client.join_room("!BeLEKkRmKBJzNOdqxB:matrix.org")
class Cmatrix: def __init__(self, _serverUrl, _username, _pass, _roomId): self.matrixClient = MatrixClient(_serverUrl) self.token = self.matrixClient.login(username=_username, password=_pass) self.api = MatrixHttpApi(_serverUrl, token=self.token) self.roomId = _roomId def sendMessage(self, message): response = self.api.send_message(self.roomId, message) return response
def get_token(config): """Returns a login token. """ loginargs = {} client = MatrixClient( "https://{0}:{1}".format(config['homeserver'], int(config['port'])), **loginargs) token = client.login(username=config['username'], password=config['password'], device_id='zabbixbot') logging.info("Authenticated, add the following to your config:\ntoken: %s", token) return token
def notify(title, message, url, roomId, userId=None, token=None, password=None, retcode=None): client = MatrixClient(url) if password is not None: if userId is None: raise Exception("Must supply 'userid' when using 'password'") client.login(userId, password, sync=False) elif token is not None: client.api.token = token else: raise Exception("Must supply 'token' or 'password'") msg_plain = "**{}** {}".format(title, message) msg_html = "<b>{}</b> {}".format(title, message) room = client.join_room(roomId) room.send_html(msg_html, msg_plain)
class Bot: def __init__(self, homeserver, userID, password, ownerID, dialogflow_project): self.ownerID = ownerID self.userID = userID self.client = MatrixClient(homeserver) token = self.client.login(username=userID, password=password) self.project = dialogflow_project rooms = self.client.get_rooms() for name, room in self.client.get_rooms().items(): room.add_listener(self.onEvent) def report_mainloop_error(self): pass def run(self): self.client.add_invite_listener(self.accept_invite) while True: try: self.client.listen_forever() except KeyboardInterrupt: raise except: self.report_mainloop_error() def accept_invite(self, room_id, state): self.client.join_room(room_id) session_client = dialogflow.SessionsClient() session = session_client.session_path(self.project, room_id) query_input = dialogflow.types.QueryInput( event=dialogflow.types.EventInput(name='WELCOME', language_code='en')) def onEvent(self, room, event): if event['sender'] != self.userID: print("New event in room {} : {}".format(room, event)) if event['type'] == "m.room.message" and event['content'][ 'msgtype'] == "m.text": if event['sender'] == self.ownerID: # admin commands leaveCommand = re.match("!leave (.+)", event['content']['body']) if leaveCommand: self.client.get_rooms()[leaveCommand.group(1)].leave() response = detect_intent(self.project, room.room_id, event['content']['body'], 'en') print("Got DialogFlow response: {}".format(response)) for message in response: for text in message.text.text: room.send_text("{}".format(text))
def main(host, username, password, room_id_alias): client = MatrixClient(host) try: client.login(username, password) 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) try: room = client.join_room(room_id_alias) 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(on_message) client.start_listener_thread() while True: msg = samples_common.get_input() if msg == "/quit": break else: room.send_text(msg)
def init(): config = configparser.ConfigParser() config.read("tztipbot.cfg") homeserver = config.get("server", "host") print(f"homeserver={homeserver}") client = MatrixClient(homeserver) username = config.get("client", "username") password = config.get("client", "password") print(f"username={username}") token = client.login(username=username, password=password) print(f"token={token}") return client
def main(): # connect to server and join room client = MatrixClient("https://matrix.org") token = client.login(username="******", password=os.environ['KLO_PW']) room = client.join_room("#klotest:matrix.org") # create FeatureHandler fh = FeatureHandler(room, client) # add features to FeatureHandler that are called when the specified command is posted in the Matrix room fh.add_feature("!echo", FeatureExamples.echo) fh.add_feature("!room", find_room) # run script until it's stopped manually while True: pass
def delete_all_devices(): client = MatrixClient(conf.matrix_server) token = client.login(username=conf.matrix_username, password=conf.matrix_password, device_id=conf.matrix_device_id) response = client.api.get_devices() #print(response) devices = response["devices"] print("len(devices)=%d" % len(response["devices"])) # sys.exit() device_list = [] index = 0 for device in response["devices"]: if device["device_id"] != conf.matrix_device_id: device_list.append(device["device_id"]) index += 1 #if index > 1000: # break # stage1 - берём сессию: try: #response=client.api.delete_device(auth_body={"auth":{}},device_id=device["device_id"]) response = client.api.delete_devices({"auth": {}}, [device["device_id"]]) except MatrixRequestError as e: if e.code == 401: print("response=", e.content) response_data = json.loads(e.content) session = response_data["session"] # stage2 передаём пароль: print("session=", session) auth_body = {} auth_body["type"] = "m.login.password" auth_body["session"] = session auth_body["user"] = conf.matrix_username auth_body["password"] = conf.matrix_password response = client.api.delete_devices(auth_body, device_list) return True
def delete_device(): client = MatrixClient(conf.server) token = client.login(username=conf.username, password=conf.password, device_id=conf.device_id) response = client.api.get_devices() #print(response) devices = response["devices"] print("len(devices)=%d" % len(response["devices"])) print("len(device_list)=%d" % len(device_list)) print("device_list=", device_list) for device in response["devices"]: if device["device_id"] != conf.device_id: #print(device) print("delete device: %s" % device["device_id"]) # stage1 - берём сессию: try: #response=client.api.delete_device(auth_body={"auth":{}},device_id=device["device_id"]) response = client.api.delete_devices({"auth": {}}, [device["device_id"]]) except MatrixRequestError as e: if e.code == 401: print("response=", e.content) response_data = json.loads(e.content) session = response_data["session"] # stage2 передаём пароль: print("session=", session) auth_body = {} auth_body["type"] = "m.login.password" auth_body["session"] = session auth_body["user"] = conf.username auth_body["password"] = conf.password response = client.api.delete_device(auth_body=auth_body, device_id=device["device_id"]) # FIXME break return True
def edit_message(): client = MatrixClient(conf.matrix_server) token = client.login(username=conf.matrix_username, password=conf.matrix_password, device_id=conf.matrix_device_id) room_id = "!XXXXX:corp.ru" print("send message") ret = client.api.send_message(room_id, "test") print("success send message") print("event_id=", ret["event_id"]) print("edit message") ret = edit_matrix_message(client, room_id, ret["event_id"], "test2", msgtype="m.text") if ret is not None: print("success edit message") else: print("error edit message") return ret
def startup(config): if os.path.isfile(config): with open(config, "r") as cfg: conf = json.load(cfg) client = MatrixClient( conf["homeserver"], conf["token"], "@" + conf["username"] + ":" + conf["homeserver"]) parkendd_server = conf["parkendd_server"] else: homeserver = input("homeserver: ") username = input("username: "******"password: "******"parkendd_server: ") client = MatrixClient(homeserver) token = client.login(username, password) with open(config, "w") as cfg: json.dump( { "homeserver": homeserver, "token": token, "username": username, "parkendd_server": parkendd_server }, cfg) return client, parkendd_server
# 4 - Bad username/password. import sys import samples_common # Common bits used between samples from matrix_client.client import MatrixClient from matrix_client.api import MatrixRequestError from requests.exceptions import MissingSchema host, username, password = samples_common.get_user_details(sys.argv) client = MatrixClient(host) try: client.login(username, password) except MatrixRequestError as e: print(e) if e.code == 403: print("Bad username or password.") sys.exit(4) else: print("Check your server details are correct.") sys.exit(2) except MissingSchema as e: print("Bad URL format.") print(e) sys.exit(3) if len(sys.argv) > 4: userid = sys.argv[4]
class TinyMatrixtBot(): def __init__(self, path_config): signal.signal(signal.SIGHUP, self.on_signal) signal.signal(signal.SIGINT, self.on_signal) signal.signal(signal.SIGTERM, self.on_signal) self.config = configparser.ConfigParser() self.config.read(path_config) _path_current = os.path.dirname(os.path.realpath(__file__)) self.enabled_scripts = self.config.get("tiny-matrix-bot", "enabled_scripts", fallback="").strip() self.path_lib = self.config.get("tiny-matrix-bot", "lib", fallback=os.path.join( _path_current, "scripts")).strip() logger.debug("path_lib = {}".format(self.path_lib)) if os.access(self.path_lib, os.R_OK): self.scripts = self.load_scripts(self.path_lib) else: logger.error("{} not readable".format(self.path_lib)) sys.exit(1) self.path_var = self.config.get("tiny-matrix-bot", "var", fallback=os.path.join( _path_current, "data")).strip() logger.debug("path_var = {}".format(self.path_var)) if os.access(self.path_var, os.W_OK): os.chdir(self.path_var) else: logger.error("{} not writeable".format(self.path_var)) sys.exit(1) self.path_run = self.config.get("tiny-matrix-bot", "run", fallback=os.path.join( _path_current, "sockets")).strip() if os.access(self.path_run, os.W_OK): logger.debug("path_run = {}".format(self.path_run)) else: logger.debug("path_run = {}".format(self.path_run) + " (not writeable, disabling sockets)") self.path_run = False self.inviter_whitelist = self.config.get("tiny-matrix-bot", "inviter_whitelist", fallback="").strip() self.connect() self.user = self.client.get_user(self.client.user_id) self.user.set_display_name(self.config.get("tiny-matrix-bot", "name")) for room_id in self.client.get_rooms(): self.join_room(room_id) self.client.start_listener_thread( exception_handler=self.listener_exception_handler) self.client.add_invite_listener(self.on_invite) self.client.add_leave_listener(self.on_leave) while True: sleep(1) def connect(self): _host = self.config.get("tiny-matrix-bot", "host") _user = self.config.get("tiny-matrix-bot", "user") _pass = self.config.get("tiny-matrix-bot", "pass") try: self.client = MatrixClient(_host) self.client.login(username=_user, password=_pass, limit=0) logger.info("connected to {}".format(_host)) except Exception: logger.warning("connection to {} failed".format(_host) + ", retrying in 5 seconds...") sleep(5) self.connect() def listener_exception_handler(self, e): self.connect() def on_signal(self, signal, frame): if signal == 1: self.scripts = self.load_scripts(self.path_lib) elif signal in [2, 15]: self.client.logout() sys.exit(0) def load_scripts(self, path): _scripts = {} for _script in os.listdir(path): _script_path = os.path.join(path, _script) if self.enabled_scripts: if _script not in self.enabled_scripts: continue if (not os.access(_script_path, os.R_OK) or not os.access(_script_path, os.X_OK)): continue _regex = subprocess.Popen( [_script_path], env={ "CONFIG": "1" }, stdout=subprocess.PIPE, universal_newlines=True).communicate()[0].strip() if not _regex: continue _scripts[_regex] = _script_path logger.info("script load {}".format(_script)) logger.debug("script regex {}".format(_regex)) return _scripts def on_invite(self, room_id, state): _sender = "someone" for _event in state["events"]: if _event["type"] != "m.room.join_rules": continue _sender = _event["sender"] break logger.info("invited to {} by {}".format(room_id, _sender)) if self.inviter_whitelist: if not re.search(self.inviter_whitelist, _sender, re.IGNORECASE): logger.info( "no whitelist match, ignoring invite from {}".format( _sender)) return self.join_room(room_id) def join_room(self, room_id): logger.info("join {}".format(room_id)) _room = self.client.join_room(room_id) _room.add_listener(self.on_room_event) if self.path_run is not False: _thread = Thread(target=self.create_socket, args=(_room, )) _thread.daemon = True _thread.start() def create_socket(self, room): _socket_name = re.search("^!([a-z]+):", room.room_id, re.IGNORECASE).group(1) _socket_path = os.path.join(self.path_run, _socket_name) try: os.remove(_socket_path) except OSError: pass _socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) _socket.bind(_socket_path) _socket.listen(1) logger.info("socket bind {}".format(_socket_path)) while True: _conn, _addr = _socket.accept() _recv = _conn.recv(4096).decode('utf-8').strip() logger.debug("socket recv {} {}".format(_socket_path, _recv)) room.send_text(_recv) def on_leave(self, room_id, state): _sender = "someone" for _event in state["timeline"]["events"]: if not _event["membership"]: continue _sender = _event["sender"] logger.info("kicked from {} by {}".format(room_id, _sender)) def on_room_event(self, room, event): if event["sender"] == self.client.user_id: return if event["type"] != "m.room.message": return if event["content"]["msgtype"] != "m.text": return _args = event["content"]["body"].strip() for _regex, _script in self.scripts.items(): if not re.search(_regex, _args, re.IGNORECASE): continue self.run_script(room, event, [_script, _args]) def run_script(self, room, event, args): logger.debug("script room_id {}".format(event["room_id"])) logger.debug("script sender {}".format(event["sender"])) logger.debug("script run {}".format(args)) _script = subprocess.Popen(args, env={ "MXROOMID": event["room_id"], "MXSENDER": event["sender"] }, stdout=subprocess.PIPE, universal_newlines=True) _output = _script.communicate()[0].strip() if _script.returncode != 0: logger.debug("script exit {}".format(_script.returncode)) return sleep(0.5) for _p in _output.split("\n\n"): for _l in _p.split("\n"): logger.debug("script output {}".format(_l)) room.send_text(_p) sleep(0.8)
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 matrix_utils_ext(object): __MODULE_NAME__ = "Matrix Bot" __VERSION__ = "v0.0.1a" __MAX_SERVICE__ = 32 # Number of services that can be simultaneously installed. room_tuple = namedtuple("room_tuple", "room_addr listener") def __init__(self, config_path="config.json"): self.room_dic = {} self.services_sensitive_on_clock = set() self.is_timer_on = False self.is_on = False self.nb_current_service = 0 self.service_list = {} # self.logger.setLevel(logging.DEBUG) ; try: with open(config_path) as f: self.config = json.loads(f.read()) except IOError as e: print(e) self.login = self.config["login"] self.password = self.config["password"] module.config = self.config.copy() try: self.client = MatrixClient(self.config["host"]) self.client.login(self.login, self.password) except MatrixRequestError as e: print(e) sys.exit() def add_service_to_room(self, room, service, message_on_start=None): ret = False if self.nb_current_service < matrix_utils_ext.__MAX_SERVICE__: if service.add_room( room): # if room has been added to the service correctly if service in self.service_list: self.service_list[service] += 1 else: self.service_list[service] = 1 ret = True else: #raise Exception("Maximum number of services ({}) reached".format(str(matrix_utils.__MAX_SERVICE__))) ; pass return ret def remove_service_from_room(self, room, service): ret = False if service.remove_room(room): ret = True # if service is not linked to any room, remove from service_list self.service_list[service] -= 1 if self.service_list[service] == 0: del self.service_list[service] else: #raise Exception("Service {} does not exist in room {}.".format(service, room)) ; pass return ret # TODO ; eventuellement vérifier si une room avec une même adresse n'existe pas ? def add_room(self, room_addr, message_on_start=""): room = self.client.join_room(room_addr) listener = room.add_listener(self.callback) self.room_dic[room] = matrix_utils_ext.room_tuple( room_addr, listener ) # (room object address, room_name (room address), listener object) if message_on_start: # Conversion to HTML format message_on_start = message_on_start.replace("\n", "<br>") message_on_start = message_on_start.replace("\t", " ") room.send_html(message_on_start, msgtype="m.notice") return room def remove_room(self, room): if not (room in self.room_dic): return False for service in service_list.keys(): if (room in service.get_room_list()): # there are still some services linked to room. return False listener = self.room_dic[room].listener self.client.remove_listener(listener) room.leave() del self.room_dic[room] return True def callback(self, room, event): if event["type"] == "m.room.message": login = re.search("@[aA-zZ]+[0-9]*", event["sender"]).group(0) login = login[1:] tmp_log = "Event from " + bcolors.OKGREEN + self.room_dic[ room].room_addr + bcolors.ENDC + " at " + str( datetime.datetime.now()) + " by " + login print(tmp_log) text = str(event["content"]["body"]) ## Stop Service Management if text == self.config["bot_down_cmd"]: self.exit() ## Otherwise, run services for service in self.service_list.keys(): if (room in service.get_room_list()): ret = service.run(text, login, room) if ret: for msg in ret: # Conversion to HTML format msg = msg.replace("\n", "<br>") msg = msg.replace("\t", " ") room.send_html(msg, msgtype="m.notice") def spawn(self): self.client.start_listener_thread(exception_handler=self.error_handle) self.is_on = True print(bcolors.OKGREEN + "\n---------------------------------------------------\n" + "---- Matrix Bot v0.0.1 ----------------------------\n" + "---------------------------------------------------\n" + bcolors.ENDC) while (self.is_on): time.sleep(0.5) def timer_callback(self, t): while (self.is_timer_on): if self.is_on: for service in self.service_list: if service.is_clock_sensitive(): service.clock_update() ret = service.run_on_clock() if ret: # Conversion to HTML format ret = ret.replace("\n", "<br>") ret = ret.replace("\t", " ") for room in service.get_room_list(): room.send_html(ret, msgtype="m.notice") time.sleep(t) def start_timer(self, t=1): if not (self.is_timer_on): self.is_timer_on = True t1 = threading.Thread(target=self.timer_callback, args=(t, )) t1.start() def stop_timer(self): self.is_timer_on = False def exit(self): self.is_timer_on = False self.is_on = False for service in self.service_list: print("Module {} {} {} is shutting down.".format( bcolors.OKGREEN, service.module_name, bcolors.ENDC)) tmp_msg = service.exit() if tmp_msg: for room in service.get_room_list(): room.send_text(tmp_msg) # for room in self.room_dic: # room.send_text(self.config["bot_stop_txt"]); sys.exit() def error_handle(self, err): print("Server is not {} responding {} ({}). Restarting ...".format( bcolors.FAIL, bcolors.ENDC, err)) self.exit()
#!/usr/bin/env python3 import getpass from matrix_client.client import MatrixClient from greet_newcomers import get_gepetto HOME = "https://matrix.laas.fr" ROOM = "#gepetto:laas.fr" if __name__ == "__main__": client = MatrixClient(HOME) client.login(username=getpass.getuser(), password=getpass.getpass()) room = client.rooms[client.api.get_room_id(ROOM)] members = [ m.user_id.split(":")[0][1:] for m in room.get_joined_members() if m.user_id.endswith(":laas.fr") ] for member in get_gepetto(): print("v" if member in members else "x", member)