# Telegram Bot Notifications

## Objective

Deliver alerts and summaries to a Telegram user, group, or channel through a bot.

A Telegram delivery channel that sends selected app notifications to a destination each user has proven they control.

## Before You Begin

This feature is being added to an application that already exists and already
works. Do not scaffold a new project, and do not assume a blank slate.

Inspect the codebase first and establish:

- The existing application structure and where code of this kind already lives.
- The framework and version in use.
- The existing design system — colours, spacing, typography, and component conventions.
- Existing UI components you can reuse instead of writing new ones.
- The existing database structure, if this feature needs to persist anything.
- The existing authentication and authorization system, if this feature is user-scoped.
- Dependencies already installed, so you don't add a library that duplicates one.
- The existing test setup and conventions.

Only start writing code once you understand the above. If the application
already implements part of this feature, extend it rather than replacing it.

## Implementation Instructions

1. Add Telegram as a destination on the app's existing notification preferences rather than as a standalone feature, so a user's per-event choices, quiet hours, and unsubscribe controls apply to it unchanged.
2. Establish the destination by having the user start a conversation with the bot and present a short-lived code the app issued, then bind whatever chat that arrives from. Never let a user type a raw chat identifier into a form.
3. Keep the bot credential encrypted at rest and resolved only on the server at send time. It must not appear in configuration exposed to the browser, in logs, or in error reports.
4. Send from the app's background-job system with retries and backoff, and treat the throttling response as a signal to wait rather than to keep hammering.
5. Escape formatting markup in every value interpolated into a message. Content the app renders safely in HTML will break or misformat a Telegram message if it is passed through untouched.

## UI and UX Requirements

Match the application's existing design system exactly. Reuse its components,
spacing, and typography. This feature should look like it was always there.

## Responsive Requirements

Works on mobile, tablet, and desktop. Touch targets are large enough to hit on a
phone, and nothing overflows horizontally at 320px.

## Accessibility Requirements

- Fully keyboard navigable.
- Correct semantic elements and ARIA roles.
- Visible focus states.
- Meets WCAG AA contrast.
- Dynamic changes are announced to screen readers.
- Respects prefers-reduced-motion.

## Edge Cases

- A manually entered chat identifier can point at a stranger's conversation. Bind the destination only from a chat the user demonstrably initiated with a code the app issued and that expires quickly.
- Formatting markup in user-supplied text will either corrupt the message or cause the send to be rejected outright. Escape it for whichever formatting mode the message uses, and be consistent about which mode that is.
- A bot removed from a group, blocked by a user, or stripped of posting permission will fail permanently. Recognise these as terminal, stop retrying, mark the destination inactive, and prompt the user to reconnect.
- A send that times out may have succeeded. Carry a stable identifier per notification and record what was delivered, so a retry does not send the same alert a second time.
- The bot token is a full account credential. It must be encrypted at rest, redacted from every log and stack trace, and rotatable without redeploying.
- Messages have a length ceiling. Truncate long summaries at a readable boundary and link back into the app rather than sending a rejected payload.
- A group destination means everyone in that group sees the notification. Warn the user before binding a group, and never route personal or account-sensitive content to one.
- When Telegram is unreachable, the triggering action must still complete and the user must be able to see in the app that the notification is pending or failed.

## Testing

Exercise the feature end to end in the running application. Cover every edge case
above, then run the existing test suite and confirm nothing regressed.

## Acceptance Criteria

- [ ] A destination can only be bound from a chat the user initiated with a short-lived code.
- [ ] Telegram appears as a destination inside the existing notification preferences, honouring per-event choices.
- [ ] Bot credentials are encrypted at rest and absent from logs and client assets.
- [ ] Interpolated user content cannot break message formatting or cause a rejected send.
- [ ] Blocked bots, removed group memberships, and missing permissions mark the destination inactive without endless retries.
- [ ] Retried jobs never deliver the same notification twice.
- [ ] The feature matches the existing design system.
- [ ] No existing functionality is broken.

## Adaptation Rules

- Match the existing design system. Do not introduce a new colour palette,
  spacing scale, or component library.
- Reuse existing components and utilities wherever they fit.
- Follow the naming, file layout, and code style already present.
- Do not upgrade, replace, or remove existing dependencies to make this
  feature fit. Adapt the feature to the app, not the app to the feature.
- Do not break existing functionality. If a change is genuinely required in
  existing code, make the smallest one that works and say so.
- If something in these instructions conflicts with how the application is
  built, follow the application and explain the deviation.

## Final Verification

Before you report the work as done:

1. Re-read the acceptance criteria above and check each one against what you
   actually built.
2. Run the application and exercise the feature end to end.
3. Run the existing test suite and confirm you have broken nothing.
4. Check the feature on mobile, tablet, and desktop widths.
5. Check keyboard navigation and focus handling.
6. Summarize what changed: files added, files modified, and anything you
   deliberately did differently because of how this application is built.

If any acceptance criterion is unmet, fix it before reporting completion.
