feat: add team calendar ICS endpoint and related functionality
All checks were successful
CI / lint-and-test (push) Successful in 23s

- Implemented a new API endpoint to generate an ICS calendar for team duty shifts, accessible via a valid token.
- Enhanced the `calendar_link` command to return both personal and team calendar URLs.
- Added a new function to build the team ICS file, ensuring each event includes the duty holder's name in the description.
- Updated tests to cover the new team calendar functionality, including validation for token formats and response content.
- Revised internationalization messages to reflect the new team calendar links.
This commit is contained in:
2026-02-21 23:41:00 +03:00
parent 0c93fe3372
commit 77a94fa91b
8 changed files with 183 additions and 17 deletions

View File

@@ -122,21 +122,30 @@ async def calendar_link(update: Update, context: ContextTypes.DEFAULT_TYPE) -> N
if not can_access_miniapp_for_telegram_user(session, telegram_user_id):
return (None, "denied")
token = create_calendar_token(session, user.id)
base = (config.MINI_APP_BASE_URL or "").rstrip("/")
url = f"{base}/api/calendar/ical/{token}.ics" if base else None
return (url, None)
return (token, None)
result_url, error = await asyncio.get_running_loop().run_in_executor(
result_token, error = await asyncio.get_running_loop().run_in_executor(
None, do_calendar_link
)
if error == "denied":
await update.message.reply_text(t(lang, "calendar_link.access_denied"))
return
if not result_url:
if not result_token:
await update.message.reply_text(t(lang, "calendar_link.error"))
return
base = (config.MINI_APP_BASE_URL or "").rstrip("/")
if not base:
await update.message.reply_text(t(lang, "calendar_link.error"))
return
url_personal = f"{base}/api/calendar/ical/{result_token}.ics"
url_team = f"{base}/api/calendar/ical/team/{result_token}.ics"
await update.message.reply_text(
t(lang, "calendar_link.success", url=result_url)
t(
lang,
"calendar_link.success",
url_personal=url_personal,
url_team=url_team,
)
+ "\n\n"
+ t(lang, "calendar_link.help_hint")
)