Files
shihaam 1ea2f9f4c2
Build and Push Docker Images / Build and Push Docker Images (push) Failing after 9s
update sign up notifications
2026-08-02 14:54:00 +05:00

96 lines
2.8 KiB
Python

import asyncio
import threading
import logging
import time
from telegram import Bot
from telegram.constants import ParseMode
from decouple import config
import re
logger = logging.getLogger(__name__)
telegram_loop = None
BOT_TOKEN = config("TG_BOT_TOKEN", default="killme", cast=str)
CHAT_ID = config("TG_CHAT_ID", default="drake", cast=str)
# Optional forum topic to post into. If empty, messages go to the group's General topic.
TOPIC_ID = config("TG_TOPIC_ID", default="", cast=str)
if not BOT_TOKEN or not isinstance(BOT_TOKEN, str):
raise ValueError(
"TG_BOT_TOKEN environment variable must be set and must be a string."
)
if not CHAT_ID:
raise ValueError(
"TG_CHAT_ID environment variable must be set and must be a string."
)
bot = Bot(token=BOT_TOKEN)
def telegram_worker():
"""
Run the event loop for Telegram in a separate daemon thread.
"""
global telegram_loop
telegram_loop = asyncio.new_event_loop()
asyncio.set_event_loop(telegram_loop)
try:
logger.info("Telegram loop started.")
telegram_loop.run_forever()
except Exception as e:
logger.exception(f"Telegram worker crashed! {e}", exc_info=True)
finally:
telegram_loop.close()
# Start the Telegram worker thread when the module is loaded
telegram_thread = threading.Thread(target=telegram_worker, daemon=True)
telegram_thread.start()
# Wait until telegram_loop is ready
timeout = 5
for _ in range(timeout * 10): # up to 5 seconds
if telegram_loop is not None:
break
time.sleep(0.1)
else:
logger.error("Telegram loop failed to initialize in time.")
async def send_telegram_alert(markdown_message: str):
logger.info("[TELEGRAM] Preparing to send alert...")
kwargs = {}
if TOPIC_ID:
kwargs["message_thread_id"] = int(TOPIC_ID)
await bot.send_message(
chat_id=str(CHAT_ID),
text=markdown_message,
parse_mode=ParseMode.MARKDOWN_V2,
**kwargs,
)
async def send_telegram_photo(photo, markdown_caption: str):
"""Send a photo. `photo` may be raw bytes / a file-like object (uploaded
directly to Telegram) or a public URL string."""
logger.info("[TELEGRAM] Preparing to send photo...")
kwargs = {}
if TOPIC_ID:
kwargs["message_thread_id"] = int(TOPIC_ID)
await bot.send_photo(
chat_id=str(CHAT_ID),
photo=photo,
caption=markdown_caption,
parse_mode=ParseMode.MARKDOWN_V2,
# Uploading media is slower than a text send; the defaults (5s) time out.
connect_timeout=15,
read_timeout=30,
write_timeout=60,
**kwargs,
)
def escape_markdown_v2(text: str) -> str:
escape_chars = r"_~`>#+-=|{}.!\\"
return re.sub(f"([{re.escape(escape_chars)}])", r"\\\1", text)