Source code for law.contrib.telegram.notification

# coding: utf-8

"""
Telegram notifications.
"""

from __future__ import annotations

__all__ = ["notify_telegram"]

import os
import threading
import traceback
import pathlib

from law.config import Config
from law.util import escape_markdown
from law.logger import get_logger
from law._types import Any


logger = get_logger(__name__)


[docs] def notify_telegram( title: str, content: str | dict[str, Any], token: str | pathlib.Path | None = None, chat: str | None = None, mention_user: str | None = None, **kwargs, ) -> bool: """ Sends a telegram notification and returns *True* on success. The communication with the telegram API might have some delays and is therefore handled by a thread. """ # test import import telegram # type: ignore[import-untyped, import-not-found] # noqa: F401 cfg = Config.instance() # get default token and chat if not token: token = cfg.get_expanded("notifications", "telegram_token") if not chat: chat = cfg.get_expanded("notifications", "telegram_chat") if not token or not chat: logger.warning(f"cannot send telegram notification, token ({token}) or chat ({chat}) empty") return False # append the user to mention to the title # unless explicitly set to empty string mention_text = "" if mention_user is None: mention_user = cfg.get_expanded("notifications", "telegram_mention_user") if mention_user: mention_text = f" (@{escape_markdown(mention_user)})" # request data for the API call request = {"parse_mode": "MarkdownV2"} # standard or attachment content? if isinstance(content, dict): # content is a dict, add some formatting request["text"] = f"{title}{mention_text}\n\n" for key, value in content.items(): request["text"] += f"_{key}_: {value}\n" else: request["text"] = f"{title}{mention_text}\n\n{content}" # extend by arbitrary kwargs request.update(kwargs) # threaded, non-blocking API communication thread = threading.Thread(target=_notify_telegram, args=(token, chat, request)) thread.start() return True
def _notify_telegram(token: str | pathlib.Path, chat: str, request: dict[str, Any]) -> bool: import telegram # type: ignore[import-untyped, import-not-found] # noqa: F401 try: # token might be a file token_file = os.path.expanduser(os.path.expandvars(token)) if os.path.isfile(token_file): with open(token_file, "r") as f: token = f.read().strip() bot = telegram.Bot(token=token) return bot.send_message(chat, **request) except Exception as e: t = traceback.format_exc() logger.warning(f"could not send telegram notification: {e}\n{t}") return False