Files
2026-matrix-csonac/bot_callbacks.py
2026-08-25 11:47:44 +03:00

176 lines
6.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Callbacks for matrix messages"""
import html
import time
import traceback
from mab import MatrixBot
from nio import MatrixRoom, RoomMessageText
import util
#
# PRIVATE
#
_bot: MatrixBot = None # type: ignore
def _generate_help_message() -> str:
"""Generates help message in HTML markup"""
result = "<b><i>Как использовать</i></b><br><ol>"
result += "<li>Используя <code>!auth</code>, создайте токен</li>"
result += "<li>Добавьте бота в комнату для уведомлений</li>"
result += "<li>Выполните <code>!info</code> в комнате, чтобы узнать код канала уведомений</li>"
result += "<li>Используя полученные токен и код канала, отправьте уведомление через веб-запрос</li>"
result += "</ol>"
result += "<br><br><b><i>Команды</i></b>"
for aliases in _COMMANDS:
result += f"<br><code>!{aliases[0]}</code> - <i>{html.escape(_COMMANDS[aliases][1])}</i>"
return result
#
# GENERIC EVENT HANDLERS
#
async def _on_text(room: MatrixRoom, event: RoomMessageText) -> None:
"""This callback is called when text message is received"""
if event.sender == _bot.get_client().user_id:
return
text = event.body
parts = [p for p in text.split() if p.strip()]
if len(parts) < 1:
return
cmd = parts[0].lower()
if not cmd.startswith("!"):
return
cb = None
for aliases in _COMMANDS:
for alias in aliases:
if alias == cmd.lstrip("!"):
cb = _COMMANDS[aliases][0]
break
if cb:
break
if cb is None:
await _bot.send_text_to_room(room.room_id, "<b>Используйте <code>!help</code></b>")
return
try:
await cb(room, parts[1:])
except:
traceback.print_exc()
#
# COMMAND HANDLERS
#
async def _on_cmd_help(room: MatrixRoom, args: list[str]) -> None:
"""!help"""
await _bot.send_text_to_room(room.room_id, _generate_help_message(), is_html=True)
async def _on_cmd_info(room: MatrixRoom, args: list[str]) -> None:
"""!info"""
response = "<b><i>Сведения о комнате</i></b><br>"
response += f"<b>channel: <b><code>{html.escape(room.room_id)}</code>"
await _bot.send_text_to_room(room.room_id, response, is_html=True)
async def _on_cmd_tokens(room: MatrixRoom, args: list[str]) -> None:
"""!info"""
TEST_LIST = {
"t0K3n": {
"created": time.time() - 60,
"last_use": time.time() - 30,
"total_uses": 534,
"service_name": "Резервное копирование",
},
"T35t_t0KeN": {
"created": time.time() - 12341,
"last_use": time.time() - 123,
"total_uses": 342,
"service_name": None,
},
}
response = "<b><i>Список токенов</i></b>"
for token in TEST_LIST:
data = TEST_LIST[token]
response += f"<br><b><code>{html.escape(token)}</code></b><br><ul>"
if data["service_name"] is not None:
response += f"<li><b>Имя службы:</b> <code>{data["service_name"]}</code></li>"
else:
response += f"<li><b>Имя службы:</b> <i>указывается в запросе</i></li>"
response += f"<li><b>Создан:</b> <i>{util.date_to_text(data["created"])}</i></li>"
response += f"<li><b>Последнее использование:</b> <i>{util.date_to_text(data["last_use"])}</i></li>"
response += f"<li><b>Всего использований:</b> <i>{data["total_uses"]}</i></li>"
response += "</ul>"
await _bot.send_text_to_room(room.room_id, response, is_html=True)
async def _on_cmd_auth(room: MatrixRoom, args: list[str]) -> None:
"""!auth"""
new_token = "inr3i4evfds"
new_token_name = " ".join(args) if args else None
if type(new_token_name) is str and not new_token_name.strip():
new_token_name = None
response = "<b>Создан новый токен</b>"
response += f"<br><b>Код:</b> <code>{new_token}</code>"
response += f"<br><b>Имя сервиса:</b> "
if new_token_name:
response += f"<code>{html.escape(new_token_name)}</code>"
else:
response += "указывается в запросе"
await _bot.send_text_to_room(room.room_id, response, is_html=True)
async def _on_cmd_deauth(room: MatrixRoom, args: list[str]) -> None:
"""!deauth"""
if len(args) != 1:
await _bot.send_text_to_room(room.room_id, "<b>Укажите токен, который надо удалить (должен быть ровно один аргумент)</b>", is_html=True)
return
token = args[0]
# TODO
response = f"<b>Удалён токен <code>{token}</code></b>"
await _bot.send_text_to_room(room.room_id, response, is_html=True)
async def _on_cmd_name(room: MatrixRoom, args: list[str]) -> None:
"""!name"""
if len(args) < 1:
error = "<b>Требуется указать как минимум токен. Если хотите убрать имя, то имя указывать не надо. Если имя нужно назначить или изменить, то после токена укажите новое имя.</b>"
await _bot.send_text_to_room(room.room_id, error, is_html=True)
return
token = args[0]
new_name = " ".join(args[1:])
if not new_name.strip():
new_name = None
# TODO
if new_name:
response = f"<b>Новое имя для токена <code>{token}</code>: <code>{new_name}</code></b>"
else:
response = f"<b>Удалено имя для токена <code>{token}</code></b>"
await _bot.send_text_to_room(room.room_id, response, is_html=True)
async def _on_cmd_leave(room: MatrixRoom, args: list[str]) -> None:
"""!leave"""
await _bot.send_text_to_room(room.room_id, "<b>Команда не реализована</b>", is_html=True)
_COMMANDS = {
("help", "h", "?"): (_on_cmd_help, "Получить справку"),
("info", "room", "i", "r"): (_on_cmd_info, "Получить сведения о комнате"),
("tokens", "t"): (_on_cmd_tokens, "Получить список токенов"),
("auth", "create", "a", "c"): (_on_cmd_auth, "Создать новый токен"),
("deauth", "delete", "d"): (_on_cmd_deauth, "Удалить существующий токен"),
("name", "n"): (_on_cmd_name, "Задать (или удалить) имя для токена"),
("leave", "l"): (_on_cmd_leave, "Покинуть комнату, в которой получена эта команда"),
}
#
# PUBLIC
#
def setup(bot: MatrixBot) -> None:
"""Setup the callbacks"""
global _bot
_bot = bot
_bot.add_event_callback(_on_text, RoomMessageText) # type: ignore