feat(telegram): scheduler delivery, hosted service, /jobs and /cancel

Spec: /jobs and /cancel explain when scheduling is off; Scheduler options validation.
This commit is contained in:
EugeneTes
2026-09-27 10:33:38 +02:00
parent 5b780fac36
commit 8dd874a83f
10 changed files with 381 additions and 10 deletions

View File

@@ -274,7 +274,8 @@ schedule(action: create|list|cancel, id?, name?, kind?: reminder|prompt|watcher,
- **Options**: a new `Scheduler` section bound to `SchedulerOptions`: `Enabled` (true),
`StorePath` (`<AgentDir>/scheduler/jobs.json`), `DefaultScriptTimeout` (300 s), `MaxJobsPerTarget` (50) and
`Shell`. There's no time zone and no scrub list here: zones are per chat (§7), the environment comes from
the process environment hook.
the process environment hook. An empty `StorePath` means `<AgentDir>/scheduler/jobs.json`; `Validate` rejects a
`DefaultScriptTimeout` outside 1 s–1 h, `MaxJobsPerTarget` < 1 and empty `Shell` entries (exit 2).
- **`Program.cs`** registers `SchedulerOptions`, `IScriptRunner` → `ScriptRunner`, `TimeProvider.System` (one
`TryAddSingleton`, shared with the message-context and attachments specs), `JobScheduler`,
`TelegramJobDelivery`, `ChatSettingsStore`, `ChatTimeZoneService` (§7; registered even when the scheduler is
@@ -309,6 +310,8 @@ schedule(action: create|list|cancel, id?, name?, kind?: reminder|prompt|watcher,
- `/cancel <id>` → `Cancelled k7m2q (Call the dentist).` `No job k7m2q in this chat.` also covers another chat's id.
With no id: `Usage: /cancel <id> (see /jobs).`
- `/status` gains `**Jobs:** <n>`.
- With the scheduler disabled, `/jobs` and `/cancel` stay in the menu and reply
`Scheduling is turned off on this bot (Scheduler:Enabled).`; `/status` has no Jobs line.
- **Security**: scheduled scripts run unattended as the bot's OS user, with the same trust as the `bash` tool that
every allow-listed user already has, and the same filtered environment. The existing Security section in
`docs/telegram-bot.md` gains that sentence.