From f2fc79862d4b5080df38422935145d2269837fba Mon Sep 17 00:00:00 2001 From: Guy Van Sanden Date: Mon, 4 May 2026 22:35:36 +0200 Subject: [PATCH] Fix config --- client/src/tellme.py | 2 +- server/src/tellmesrv.py | 147 ++++++++++++++++++++++++++++++---------- 2 files changed, 112 insertions(+), 37 deletions(-) diff --git a/client/src/tellme.py b/client/src/tellme.py index 2794c75..5658885 100755 --- a/client/src/tellme.py +++ b/client/src/tellme.py @@ -39,7 +39,7 @@ def sendmessage(message): ran = True -__version__ = "3.0.0" +__version__ = "2.3.0" versionstring='Taurix TellMe v' + __version__ signal.signal(signal.SIGINT, signal_handler) diff --git a/server/src/tellmesrv.py b/server/src/tellmesrv.py index 1ff81dc..5c18712 100644 --- a/server/src/tellmesrv.py +++ b/server/src/tellmesrv.py @@ -24,25 +24,41 @@ logging.basicConfig( ) log = logging.getLogger(__name__) +hooks = {} +config = {} + app = Flask(__name__) # context = zmq.Context() # socket = context.socket(zmq.REQ) # socket.connect("tcp://localhost:5555") -hooks = {} -config = {} - - def read_configs(): global hooks, config - with open(r'/etc/tellme/hooks.yml') as hooksfile: - hooks = yaml.load(hooksfile, Loader=yaml.FullLoader) + print("DEBUG: read_configs() called") # Temporary debug + log.info("read_configs() called") + + if not os.path.isfile('/etc/tellme/hooks.yml'): + log.error("hooks.yml not found at /etc/tellme/hooks.yml") + else: + try: + with open(r'/etc/tellme/hooks.yml') as hooksfile: + loaded = yaml.load(hooksfile, Loader=yaml.FullLoader) + hooks = {str(k): v for k, v in loaded.items()} if loaded else {} + log.info("Loaded hooks: %s" % (list(hooks.keys()) if hooks else 'empty')) + except Exception as e: + log.error("Failed to load hooks.yml: %s" % (e)) if os.path.isfile('/etc/tellme/config.yml'): - with open(r'/etc/tellme/config.yml') as configfile: - config = yaml.load(configfile, Loader=yaml.FullLoader) + try: + with open(r'/etc/tellme/config.yml') as configfile: + config = yaml.load(configfile, Loader=yaml.FullLoader) + log.info("Loaded config") + except Exception as e: + log.error("Failed to load config.yml: %s" % (e)) + else: + log.error("config.yml not found at /etc/tellme/config.yml") def send_smp_message(target, message): @@ -58,20 +74,41 @@ def send_smp_message(target, message): json_command = json.dumps(command) uri = "ws://localhost:5080" - ws = websocket.create_connection(uri) - - ws.send(json_command) # Send message to WebSocket - responsejson = ws.recv() # Receive response - response = json.loads(responsejson) - ws.close() - - if response is not None: - log.info("Sent message to SimpleX with %s" % (response)) - return True - else: - log.error("Failed to send message to SimpleX with %s" % (response)) + try: + ws = websocket.create_connection(uri) + except Exception as e: + log.error("Failed to connect to SimpleX WebSocket at %s: %s" % (uri, e)) return False + try: + log.info("Sending to SimpleX WebSocket: %s" % (json_command)) + ws.send(json_command) # Send message to WebSocket + responsejson = ws.recv() # Receive response + log.info("SimpleX raw response: %s" % (responsejson)) + response = json.loads(responsejson) + + if response and isinstance(response, dict): + resp = response.get('resp', {}) + if isinstance(resp, dict) and resp.get('type') == 'subscriptionStatus': + log.warning("SimpleX response indicates subscription status, not message delivery: %s" % (response)) + elif resp and resp.get('type') == 'sent': + log.info("SimpleX message sent successfully") + return True + else: + log.info("SimpleX response: %s" % (response)) + return True + else: + log.error("Unexpected SimpleX response format: %s" % (response)) + return False + except Exception as e: + log.error("Error sending SimpleX message: %s" % (e)) + return False + finally: + try: + ws.close() + except: + pass + async def matrix_login_and_send(homeserver, access_token, user_id, target, message): client = AsyncClient(homeserver, user_id) @@ -79,31 +116,52 @@ async def matrix_login_and_send(homeserver, access_token, user_id, target, messa invited_rooms = [] - async def auto_join_callback(room: MatrixRoom, event: RoomMessageText, client: AsyncClient): + async def auto_join_callback(room: MatrixRoom, event: RoomMessageText): pass - async def invited_callback(room: MatrixRoom, event: RoomMessageText, client: AsyncClient): - invited_rooms.append(room.room_id) - client.add_event_callback(auto_join_callback, RoomMessageText) try: - response = await client.sync(full_state=True) + await client.sync(full_state=True) for room_id, invite_state in client.invited_rooms.items(): await client.join(room_id) invited_rooms.append(room_id) - if target not in client.rooms and target not in invited_rooms: - await client.join(target) + room = None + room_id = None - room = client.rooms.get(target) - if room: + if target.startswith('#'): + for room_obj in client.rooms.values(): + if hasattr(room_obj, 'canonical_alias') and room_obj.canonical_alias == target: + room = room_obj + room_id = room_obj.room_id + break + + if not room or not room_id: + try: + join_response = await client.join(target) + log.info("Join response: %s" % (join_response)) + if hasattr(join_response, 'room_id'): + room_id = join_response.room_id + await client.sync(full_state=True) + room = client.rooms.get(room_id) + elif hasattr(join_response, 'room'): + room_id = join_response.room.room_id + room = join_response.room + except Exception as join_error: + log.error("Join failed for %s: %s" % (target, join_error)) + + if not room_id: + log.error("Could not get room_id for %s" % (target)) + return False + + if room_id: await client.room_send( - room_id=target, + room_id=room_id, message_type="m.room.message", content={"msgtype": "m.text", "body": message} ) - log.info("Sent message to Matrix room %s" % (target)) + log.info("Sent message to Matrix room %s (room_id: %s)" % (target, room_id)) return True else: log.error("Could not join Matrix room %s" % (target)) @@ -125,6 +183,13 @@ def send_matrix_message(target, message): log.error("Matrix credentials not configured") return False + return asyncio.run( + matrix_login_and_send(homeserver, access_token, user_id, target, message) + ) + except Exception as e: + log.error("Failed to send message to Matrix: %s" % (e)) + return False + return asyncio.get_event_loop().run_until_complete( matrix_login_and_send(homeserver, access_token, user_id, target, message) ) @@ -134,7 +199,10 @@ def send_matrix_message(target, message): def get_hook(hook_id): - return hooks.get(str(hook_id)) + global hooks + hook = hooks.get(str(hook_id)) + log.info("Looking up hook_id=%s, found=%s, available_keys=%s" % (hook_id, hook, list(hooks.keys()))) + return hook @app.route("/webhook/", methods=['POST']) @@ -169,7 +237,8 @@ def webhook_receiver(id): hook = get_hook(id) if hook is None: - return jsonify({'message': 'Hook not found'}), 404 + log.error("Webhook %s found, dropping message" % (id)) + return jsonify({'message': 'Hook not found'}), 400 transport = hook.get('transport') target = hook.get('target') @@ -179,9 +248,11 @@ def webhook_receiver(id): if target is not None: log.info(target) if message is not None: - send_smp_message(target, message) + if not send_smp_message(target, message): + return jsonify({'message': 'Failed to send SimpleX message'}), 500 else: log.error("No message, dropping") + return jsonify({'message': 'No message, dropping'}), 400 else: log.error("No target found, dropping message") return jsonify({'message': 'No target found, dropping message'}), 400 @@ -189,9 +260,11 @@ def webhook_receiver(id): if target is not None: log.info(target) if message is not None: - send_matrix_message(target, message) + if not send_matrix_message(target, message): + return jsonify({'message': 'Failed to send Matrix message'}), 500 else: log.error("No message, dropping") + return jsonify({'message': 'No message, dropping'}), 400 else: log.error("No target found, dropping message") return jsonify({'message': 'No target found, dropping message'}), 400 @@ -205,7 +278,9 @@ def webhook_receiver(id): return jsonify({'message': 'Webhook received successfully'}), 200 +read_configs() +log.info("Config loaded: %s" % (config)) + if __name__ == '__main__': log.info("Started %s" % (versionstring)) - read_configs() app.run()