# Events & Scheduling

> Internal event system for scheduled tasks, webhooks, and cross-component communication.

## EventDefinition

Declare events in the `UIRouter.events` list. Each definition has:

- `name: str` — event identifier.
- `source_type: EventSourceType` — how the event originates:
  - `INTERNAL` — emitted from code via the `EMIT_EVENT` action.
  - `WEBHOOK` — triggered by an HTTP endpoint.
  - `SCHEDULED` — runs on a cron expression or interval.
  - `MANUAL` — triggered programmatically.
- `schedule_type: ScheduleType | None` — `ONCE`, `CRON`, or `INTERVAL`. Only relevant for `SCHEDULED` source.
- `schedule_value: str | None` — cron expression (e.g. `"0 9 * * *"`) or interval string.
- `webhook_path: str | None` — URL path for `WEBHOOK` source.
- `expected_data: dict[str, str] = {}` — expected payload keys and their types.
- `description: str | None`

## EventHandler

React to events in `UIRouter.event_handlers`. Each handler has:

- `event_name: str` — must match an `EventDefinition.name`.
- `conditions: list[RuleCondition] = []` — optional rule-based filtering.
- `actions: list[ActionInstruction]` — actions to execute when the event fires.
- `priority: int = 0` — higher priority handlers execute first.
- `target_scope: "user" | "bot" | "chat" = "user"` — who receives the resulting actions.

## EMIT_EVENT Action

Emit an event immediately from any handler's action list:

```python
ActionInstruction(
    type=ActionType.EMIT_EVENT,
    event_name="purchase_completed",
    event_data={"amount": 100},
)
```

## SCHEDULE_EVENT Action

Schedule a future event from any handler's action list:

```python
ActionInstruction(
    type=ActionType.SCHEDULE_EVENT,
    event_name="reminder",
    schedule_type="once",
    schedule_value="2024-12-25T09:00:00",
    event_data={"message": "Merry Christmas!"},
)
```

## Event Scheduler Integrations

Three built-in scheduler implementations are available:

- `InMemoryEventScheduler()` — no persistence, development only.
- `APSchedulerEventScheduler(scheduler)` — requires `pip install aiogram-ui-router[apscheduler]`.
- `TaskiqEventScheduler(broker)` — requires `pip install aiogram-ui-router[taskiq]`.

Pass the chosen scheduler to `SharedServices`:

```python
shared = SharedServices(
    event_scheduler=APSchedulerEventScheduler(scheduler),
    ...
)
```

## bot_resolver

Required for scheduled events that need to send messages when there is no active user update. Provide an async callable that resolves a `Bot` instance from a bot ID:

```python
async def resolve_bot(bot_id: int | str) -> Bot:
    return bot_instance

shared = SharedServices(
    bot_resolver=resolve_bot,
    ...
)
```

## Example — Daily Reminder

A complete example combining an `EventDefinition` with its `EventHandler`:

```python
UIRouter(
    events=[
        EventDefinition(
            name="daily_reminder",
            source_type=EventSourceType.SCHEDULED,
            schedule_type=ScheduleType.CRON,
            schedule_value="0 9 * * *",
        ),
    ],
    event_handlers=[
        EventHandler(
            event_name="daily_reminder",
            actions=[
                ActionInstruction(
                    type=ActionType.SEND_MESSAGE,
                    content=MessageContent(text="Good morning! Don't forget your daily tasks."),
                ),
            ],
        ),
    ],
    ...
)
```
