From 97d1e48bf4f5170810cc98e067b8b8cde3baa3bd Mon Sep 17 00:00:00 2001 From: Gabriel Wong Date: Sat, 21 Sep 2024 11:54:10 +0800 Subject: [PATCH] feat: allow admin to respond directly in telegram Allow admins to respond to feedback messages by replying to the message in Telegram, instead of the current process of having to manually POST to the telemsg API. This should make it extremely easy to respond to future feedback. Determine responses by parsing the message that the admin is replying to, but this is a pretty bad implementation that couples the new handler with how the current `/feedback` handler sends messages to admin. To fix this, we'd have to offload the messaging to a separate service, but it isn't worth doing now. Messages are sent by POST-ing to the telemsg API. This responsibility should also be offloaded to a separate service, along with the POST-ing done in the `/feedback` handler, but again it isn't worth doing. --- docker-compose.yml | 1 + hosts/telebot/src/bot/bot.py | 3 +- hosts/telebot/src/bot/config.py | 2 ++ hosts/telebot/src/bot/handlers/message.py | 34 +++++++++++++++++++++++ 4 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 hosts/telebot/src/bot/handlers/message.py diff --git a/docker-compose.yml b/docker-compose.yml index 6e6b451..a81574c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -88,6 +88,7 @@ services: image: evs-telebot:latest environment: TELEGRAM_TOKEN: "${TELEGRAM_TOKEN}" + TELEGRAM_ADMIN_ID: "${TELEGRAM_ADMIN_ID}" DB_API_HOST: "db_api" DB_API_PORT: 8080 TELEMSG_API_HOST: "telemsg_api" diff --git a/hosts/telebot/src/bot/bot.py b/hosts/telebot/src/bot/bot.py index df5303f..dff1582 100644 --- a/hosts/telebot/src/bot/bot.py +++ b/hosts/telebot/src/bot/bot.py @@ -1,5 +1,5 @@ from telegram.ext import Updater -from .handlers import commands as cmd +from .handlers import commands as cmd, message from .handlers.conv import (add_subscription as add, view_subscription as view, feedback as feedback) @@ -16,6 +16,7 @@ def add_handlers(self): self.dispatcher.add_handler(add.conv_handler) self.dispatcher.add_handler(view.conv_handler) self.dispatcher.add_handler(feedback.conv_handler) + self.dispatcher.add_handler(message.message_handler) def start(self): self.updater.start_polling() diff --git a/hosts/telebot/src/bot/config.py b/hosts/telebot/src/bot/config.py index 54488cd..409c098 100644 --- a/hosts/telebot/src/bot/config.py +++ b/hosts/telebot/src/bot/config.py @@ -8,3 +8,5 @@ TELEMSG_API_HOST = os.environ.get('TELEMSG_API_HOST', 'localhost') TELEMSG_API_PORT = os.environ.get('TELEMSG_API_PORT', 5001) + +TELEGRAM_ADMIN_ID = int(os.environ['TELEGRAM_ADMIN_ID']) diff --git a/hosts/telebot/src/bot/handlers/message.py b/hosts/telebot/src/bot/handlers/message.py new file mode 100644 index 0000000..99a68ba --- /dev/null +++ b/hosts/telebot/src/bot/handlers/message.py @@ -0,0 +1,34 @@ +import os +import re + +import requests +from telegram.ext import Filters, MessageHandler + +from ..config import TELEGRAM_ADMIN_ID, TELEMSG_API_HOST, TELEMSG_API_PORT +from .logging import logger + + +def admin_message_handler(update, context): + if update.message.chat_id != TELEGRAM_ADMIN_ID: + return + if update.message.reply_to_message is None: + return + + text = update.message.reply_to_message.text + m = re.match(r'Message from (\d+):', text) + if m is None: + return + target_user = int(m.group(1)) + text = f'Message from admin:\n{update.message.text}' + message_user(target_user, text) + + +def message_user(chat_id: int, text: str) -> None: + url = f'http://{TELEMSG_API_HOST}:{TELEMSG_API_PORT}/message' + requests.post(url, json={ + 'chat_id': chat_id, + 'text': text, + }) + + +message_handler = MessageHandler(Filters.text & ~Filters.command, admin_message_handler)