feat: add multiple env options to simplify personal deployments

* ADD_CALENDAR_LINK: bool (defaults to True): do not send "Add to calendar" links
* EDIT_MESSAGE_ID: int (default to None): do not send initial message,
  instead edit the given one.
This commit is contained in:
Arthur K. 2025-05-21 15:41:27 +03:00
parent 07c609de87
commit 331008aa14
Signed by: wzray
GPG key ID: B97F30FDC4636357
2 changed files with 47 additions and 25 deletions

View file

@ -1,2 +1,4 @@
TOKEN= TOKEN=
MAIN_GROUP_ID= MAIN_GROUP_ID=
EDIT_MESSAGE_ID=
ADD_CALENDAR_LINK=

70
main.py
View file

@ -1,13 +1,15 @@
import datetime
import logging
import os
import requests
import asyncio import asyncio
from aiogram import Bot
import datetime as dt import datetime as dt
import locale import locale
import urllib.parse import logging
import os
import re import re
import urllib.parse
import requests
from aiogram import Bot
from aiogram.client.default import DefaultBotProperties
from aiogram.types import LinkPreviewOptions
# Modify the links and data below: # Modify the links and data below:
DEADLINES_URL = "https://m3104.nawinds.dev/DEADLINES.json" DEADLINES_URL = "https://m3104.nawinds.dev/DEADLINES.json"
@ -16,12 +18,17 @@ BOT_NAME = "Дединсайдер M3104"
BOT_USERNAME = "m3104_deadliner_bot" BOT_USERNAME = "m3104_deadliner_bot"
# Environment variables that should be available: # Environment variables that should be available:
TOKEN: str = os.getenv("TOKEN") # type: ignore TOKEN = os.getenv("TOKEN")
MAIN_GROUP_ID = int(os.getenv("MAIN_GROUP_ID")) # type: ignore MAIN_GROUP_ID = int(os.getenv("MAIN_GROUP_ID") or '0')
EDIT_MESSAGE_ID = int(os.getenv("EDIT_MESSAGE_ID") or '0')
ADD_CALENDAR_LINK = os.getenv("ADD_CALENDAR_LINK") != 'false'
assert TOKEN, "Missing token!"
assert MAIN_GROUP_ID, "Missing group ID!"
logging.basicConfig(level=logging.INFO) logging.basicConfig(level=logging.INFO)
bot = Bot(TOKEN) bot = Bot(TOKEN, default=DefaultBotProperties(parse_mode='HTML', link_preview=LinkPreviewOptions(is_disabled=True)))
NUMBER_EMOJIS = ['0.', '1', '2', '3', '4', '5', '6', '7', '8', '9', '🔟'] NUMBER_EMOJIS = ['0.', '1', '2', '3', '4', '5', '6', '7', '8', '9', '🔟']
@ -91,7 +98,7 @@ def get_message_text() -> str:
try: try:
response = requests.get(DEADLINES_URL).json() response = requests.get(DEADLINES_URL).json()
except Exception as e: except Exception as e:
print(f"{datetime.datetime.now()} Failed to fetch deadlines: {e}") print(f"{dt.datetime.now()} Failed to fetch deadlines: {e}")
return "" return ""
all_deadlines = response["deadlines"] all_deadlines = response["deadlines"]
@ -139,45 +146,58 @@ def get_message_text() -> str:
text += "</b> — " text += "</b> — "
text += get_human_timedelta(item["time"]) text += get_human_timedelta(item["time"])
text += f"\n(<a href='{generate_link(name, item['time'])}'>" if ADD_CALENDAR_LINK:
text += get_human_time(item["time"]) + "</a>)\n\n" text += f"\n(<a href='{generate_link(name, item['time'])}'>"
text += get_human_time(item["time"]) + "</a>)\n\n"
else:
text += f'\n({get_human_time(item["time"])})\n\n'
for assignment_type in assignments: for assignment_type in assignments:
add_items(*assignment_type) add_items(*assignment_type)
text += f"\n🆕 <a href='{ADD_DEADLINE_LINK}'>" \ text += (
f"Добавить дедлайн</a>" f"\n🆕 <a href='{ADD_DEADLINE_LINK}'>"
f"Добавить дедлайн</a>"
)
return text return text
async def send_deadlines(chat_id: int) -> None: async def send_deadlines(chat_id: int) -> None:
text = get_message_text() text = get_message_text()
if text == "Дедлайнов нет)\n\n":
return
msg = await bot.send_message(chat_id, text, parse_mode="HTML", disable_web_page_preview=True) if EDIT_MESSAGE_ID:
msg = await bot.edit_message_text(text, chat_id=chat_id, message_id=EDIT_MESSAGE_ID)
assert not isinstance(msg, bool), 'EDIT_MESSAGE_ID is not a message!'
else:
msg = await bot.send_message(chat_id, text, parse_mode="HTML", disable_web_page_preview=True)
started_updating = dt.datetime.now() started_updating = dt.datetime.now()
print(datetime.datetime.now(), "Message sent. Msg id:", msg.message_id) print(dt.datetime.now(), "Message sent. Msg id:", msg.message_id)
while dt.datetime.now() - started_updating < dt.timedelta(days=1): condition = (lambda: True) if EDIT_MESSAGE_ID else (lambda: dt.datetime.now() - started_updating < dt.timedelta(days=1))
while condition():
await asyncio.sleep(60) await asyncio.sleep(60)
try: try:
new_text = get_message_text() new_text = get_message_text()
if text != new_text and new_text != "": if text != new_text and new_text != "":
await msg.edit_text(new_text, parse_mode="HTML", disable_web_page_preview=True) await msg.edit_text(new_text, parse_mode="HTML", disable_web_page_preview=True)
text = new_text text = new_text
print(datetime.datetime.now(), "Message updated. Msg id:", msg.message_id) print(dt.datetime.now(), "Message updated. Msg id:", msg.message_id)
else: else:
print(datetime.datetime.now(), "Message update skipped. Msg id:", msg.message_id) print(dt.datetime.now(), "Message update skipped. Msg id:", msg.message_id)
except Exception as e: except Exception as e:
logging.warning(datetime.datetime.now(),f"{datetime.datetime.now()} Error updating message: {e}") logging.warning(dt.datetime.now(),f"{dt.datetime.now()} Error updating message: {e}")
continue continue
await msg.delete()
if not EDIT_MESSAGE_ID:
await msg.delete()
async def main(): async def main():
await send_deadlines(MAIN_GROUP_ID) try:
await bot.session.close() await send_deadlines(MAIN_GROUP_ID)
finally:
await bot.session.close()
if __name__ == '__main__': if __name__ == '__main__':