@prajwalshete/telegram-plugin 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +87 -0
- package/LICENSE +21 -0
- package/README.md +109 -2
- package/dist/adapters/clock.d.ts +3 -0
- package/dist/adapters/clock.js +4 -0
- package/dist/adapters/console-log.d.ts +13 -0
- package/dist/adapters/console-log.js +41 -0
- package/dist/adapters/d1-db.d.ts +5 -0
- package/dist/adapters/d1-db.js +37 -0
- package/dist/adapters/ids.d.ts +5 -0
- package/dist/adapters/ids.js +25 -0
- package/dist/adapters/index.d.ts +7 -0
- package/dist/adapters/keyring.d.ts +50 -0
- package/dist/adapters/keyring.js +174 -0
- package/dist/adapters/metrics.d.ts +28 -0
- package/dist/adapters/metrics.js +48 -0
- package/dist/adapters/r2-files.d.ts +20 -0
- package/dist/adapters/r2-files.js +53 -0
- package/dist/bin/cli.d.ts +1 -0
- package/dist/bin/cli.js +45 -0
- package/dist/client/broadcasts.d.ts +35 -0
- package/dist/client/commands.d.ts +23 -0
- package/dist/client/endpoint.d.ts +34 -0
- package/dist/client/events.d.ts +33 -0
- package/dist/client/index.d.ts +11 -0
- package/dist/client/index.js +3 -0
- package/dist/client/schedules.d.ts +42 -0
- package/dist/client/schema.d.ts +181 -0
- package/dist/client/send.d.ts +15 -0
- package/dist/client/templates.d.ts +47 -0
- package/dist/contracts/bots.d.ts +129 -0
- package/dist/contracts/bots.js +70 -0
- package/dist/contracts/broadcasts.d.ts +116 -0
- package/dist/contracts/broadcasts.js +63 -0
- package/dist/contracts/chats.d.ts +97 -0
- package/dist/contracts/chats.js +66 -0
- package/dist/contracts/commands.d.ts +52 -0
- package/dist/contracts/commands.js +53 -0
- package/dist/contracts/common.d.ts +38 -0
- package/dist/contracts/common.js +41 -0
- package/dist/contracts/deliveries.d.ts +103 -0
- package/dist/contracts/deliveries.js +74 -0
- package/dist/contracts/destinations.d.ts +24 -0
- package/dist/contracts/destinations.js +28 -0
- package/dist/contracts/events.d.ts +165 -0
- package/dist/contracts/events.js +98 -0
- package/dist/contracts/features.d.ts +20 -0
- package/dist/contracts/features.js +21 -0
- package/dist/contracts/health.d.ts +55 -0
- package/dist/contracts/health.js +58 -0
- package/dist/contracts/index.d.ts +22 -0
- package/dist/contracts/index.js +22 -0
- package/dist/contracts/labels.d.ts +38 -0
- package/dist/contracts/labels.js +52 -0
- package/dist/contracts/links.d.ts +51 -0
- package/dist/contracts/links.js +50 -0
- package/dist/contracts/meta.d.ts +132 -0
- package/dist/contracts/meta.js +85 -0
- package/dist/contracts/permissions.d.ts +24 -0
- package/dist/contracts/permissions.js +27 -0
- package/dist/contracts/problems.d.ts +106 -0
- package/dist/contracts/problems.js +101 -0
- package/dist/contracts/recipients.d.ts +36 -0
- package/dist/contracts/recipients.js +22 -0
- package/dist/contracts/schedules.d.ts +276 -0
- package/dist/contracts/schedules.js +143 -0
- package/dist/contracts/send.d.ts +126 -0
- package/dist/contracts/send.js +69 -0
- package/dist/contracts/subscriptions.d.ts +38 -0
- package/dist/contracts/subscriptions.js +31 -0
- package/dist/contracts/templates.d.ts +358 -0
- package/dist/contracts/templates.js +174 -0
- package/dist/contracts/users.d.ts +15 -0
- package/dist/contracts/users.js +19 -0
- package/dist/core/guards.d.ts +22 -0
- package/dist/core/guards.js +47 -0
- package/dist/core/html/escape.d.ts +2 -0
- package/dist/core/html/escape.js +36 -0
- package/dist/core/html/tokenize.js +65 -0
- package/dist/core/index.d.ts +18 -0
- package/dist/core/pacing.d.ts +1 -0
- package/dist/core/pacing.js +86 -0
- package/dist/core/random.d.ts +2 -0
- package/dist/core/random.js +38 -0
- package/dist/core/recipients.d.ts +1 -0
- package/dist/core/recipients.js +86 -0
- package/dist/core/schedule/describe.d.ts +3 -0
- package/dist/core/schedule/describe.js +74 -0
- package/dist/core/schedule/index.d.ts +4 -0
- package/dist/core/schedule/policy.d.ts +1 -0
- package/dist/core/schedule/policy.js +37 -0
- package/dist/core/schedule/rule.d.ts +25 -0
- package/dist/core/schedule/rule.js +142 -0
- package/dist/core/schedule/tz.d.ts +2 -0
- package/dist/core/schedule/tz.js +59 -0
- package/dist/core/split/plain.d.ts +2 -0
- package/dist/core/split/plain.js +23 -0
- package/dist/core/split/split.d.ts +15 -0
- package/dist/core/split/split.js +158 -0
- package/dist/core/template/ast.d.ts +58 -0
- package/dist/core/template/ast.js +5 -0
- package/dist/core/template/expr.js +108 -0
- package/dist/core/template/filters.d.ts +20 -0
- package/dist/core/template/filters.js +127 -0
- package/dist/core/template/format.d.ts +17 -0
- package/dist/core/template/format.js +88 -0
- package/dist/core/template/index.d.ts +20 -0
- package/dist/core/template/index.js +29 -0
- package/dist/core/template/parse.d.ts +8 -0
- package/dist/core/template/parse.js +369 -0
- package/dist/core/template/render.d.ts +17 -0
- package/dist/core/template/render.js +118 -0
- package/dist/core/template/shape.d.ts +28 -0
- package/dist/core/template/shape.js +151 -0
- package/dist/core/template/tags.js +105 -0
- package/dist/core/template/validate.d.ts +10 -0
- package/dist/core/template/validate.js +144 -0
- package/dist/core/template/variables.d.ts +15 -0
- package/dist/core/template/variables.js +41 -0
- package/dist/do/index.d.ts +3 -0
- package/dist/do/index.js +3 -0
- package/dist/do/telegram-bot-do.d.ts +45 -0
- package/dist/do/telegram-bot-do.js +219 -0
- package/dist/engine/actions/callback.js +256 -0
- package/dist/engine/actions/tokens.d.ts +2 -0
- package/dist/engine/actions/tokens.js +51 -0
- package/dist/engine/bot-api.js +20 -0
- package/dist/engine/bot-features.js +39 -0
- package/dist/engine/chat-state.js +66 -0
- package/dist/engine/content/audience.js +54 -0
- package/dist/engine/content/buttons.d.ts +1 -0
- package/dist/engine/content/buttons.js +113 -0
- package/dist/engine/content/fanout.js +284 -0
- package/dist/engine/content/intersect.d.ts +6 -0
- package/dist/engine/content/intersect.js +26 -0
- package/dist/engine/content/providers.d.ts +6 -0
- package/dist/engine/content/providers.js +142 -0
- package/dist/engine/content/recipients.js +128 -0
- package/dist/engine/content/render.js +138 -0
- package/dist/engine/content/reply.js +156 -0
- package/dist/engine/content/report-files.js +78 -0
- package/dist/engine/content/template-rows.js +74 -0
- package/dist/engine/dialogs/dialog.d.ts +2 -0
- package/dist/engine/dialogs/dialog.js +375 -0
- package/dist/engine/dispatch/builtins.js +198 -0
- package/dist/engine/dispatch/commands.js +194 -0
- package/dist/engine/dispatch/context.d.ts +2 -0
- package/dist/engine/dispatch/context.js +194 -0
- package/dist/engine/dispatch/dispatcher.js +66 -0
- package/dist/engine/dispatch/handlers.d.ts +1 -0
- package/dist/engine/dispatch/handlers.js +103 -0
- package/dist/engine/dispatch/lifecycle.js +85 -0
- package/dist/engine/dispatch/link-chat.js +31 -0
- package/dist/engine/dispatch/linking.js +273 -0
- package/dist/engine/errors.d.ts +60 -0
- package/dist/engine/errors.js +72 -0
- package/dist/engine/events/filters.d.ts +5 -0
- package/dist/engine/events/filters.js +82 -0
- package/dist/engine/events/kick.js +30 -0
- package/dist/engine/events/payload.d.ts +3 -0
- package/dist/engine/events/payload.js +16 -0
- package/dist/engine/events/tick.js +208 -0
- package/dist/engine/i18n.d.ts +12 -0
- package/dist/engine/i18n.js +55 -0
- package/dist/engine/inbound/files.js +121 -0
- package/dist/engine/inbound/handler.js +46 -0
- package/dist/engine/jobs.d.ts +32 -0
- package/dist/engine/jobs.js +85 -0
- package/dist/engine/link-codes.js +46 -0
- package/dist/engine/metrics.js +12 -0
- package/dist/engine/options.d.ts +369 -0
- package/dist/engine/options.js +81 -0
- package/dist/engine/outbox/dead-letter.js +78 -0
- package/dist/engine/outbox/do-registry.d.ts +10 -0
- package/dist/engine/outbox/do-registry.js +10 -0
- package/dist/engine/outbox/do-transport.d.ts +33 -0
- package/dist/engine/outbox/do-transport.js +73 -0
- package/dist/engine/outbox/drain.d.ts +13 -0
- package/dist/engine/outbox/drain.js +381 -0
- package/dist/engine/outbox/enqueue.d.ts +1 -0
- package/dist/engine/outbox/enqueue.js +63 -0
- package/dist/engine/outbox/select.js +24 -0
- package/dist/engine/outbox/send.js +362 -0
- package/dist/engine/outbox/transport.d.ts +35 -0
- package/dist/engine/outbox/transport.js +175 -0
- package/dist/engine/outbox/wake.js +28 -0
- package/dist/engine/registry.d.ts +502 -0
- package/dist/engine/registry.js +258 -0
- package/dist/engine/rows.d.ts +25 -0
- package/dist/engine/rows.js +131 -0
- package/dist/engine/runtime.d.ts +95 -0
- package/dist/engine/runtime.js +149 -0
- package/dist/engine/schedules/fire.js +208 -0
- package/dist/engine/schedules/resume.js +75 -0
- package/dist/engine/schedules/rows.js +69 -0
- package/dist/engine/schedules/tick.js +30 -0
- package/dist/engine/schedules/wake.js +50 -0
- package/dist/engine/state.d.ts +11 -0
- package/dist/engine/state.js +78 -0
- package/dist/locales/en.js +339 -0
- package/dist/locales/en.json +341 -0
- package/dist/locales/mr.js +339 -0
- package/dist/locales/mr.json +341 -0
- package/dist/ports/db.d.ts +22 -0
- package/dist/ports/index.d.ts +4 -0
- package/dist/ports/ports.d.ts +257 -0
- package/dist/ports/sql.d.ts +39 -0
- package/dist/ports/sql.js +76 -0
- package/dist/renderers/csv.d.ts +14 -0
- package/dist/renderers/csv.js +51 -0
- package/dist/renderers/html.d.ts +44 -0
- package/dist/renderers/html.js +81 -0
- package/dist/renderers/index.d.ts +5 -0
- package/dist/renderers/index.js +4 -0
- package/dist/renderers/table.d.ts +30 -0
- package/dist/renderers/table.js +114 -0
- package/dist/routes/admin.js +146 -0
- package/dist/routes/app.d.ts +3111 -0
- package/dist/routes/app.js +9 -0
- package/dist/routes/broadcasts.js +37 -0
- package/dist/routes/commands.js +35 -0
- package/dist/routes/content.js +12 -0
- package/dist/routes/events.js +36 -0
- package/dist/routes/http.d.ts +30 -0
- package/dist/routes/http.js +223 -0
- package/dist/routes/me.js +59 -0
- package/dist/routes/schedules.js +62 -0
- package/dist/routes/send.js +24 -0
- package/dist/routes/templates.js +70 -0
- package/dist/routes/webhook.js +147 -0
- package/dist/schema/columns.js +307 -0
- package/dist/schema/ddl.d.ts +7 -0
- package/dist/schema/ddl.js +45 -0
- package/dist/schema/index.d.ts +4255 -0
- package/dist/schema/index.js +44 -0
- package/dist/schema/reference.sql +359 -0
- package/dist/schema/tables.d.ts +4243 -0
- package/dist/schema/tables.js +327 -0
- package/dist/schema/version.d.ts +5 -0
- package/dist/schema/version.js +7 -0
- package/dist/server/index.d.ts +55 -0
- package/dist/server/index.js +46 -0
- package/dist/server/plugin.d.ts +81 -0
- package/dist/server/plugin.js +247 -0
- package/dist/server/version.d.ts +2 -0
- package/dist/server/version.js +4 -0
- package/dist/services/ai-tool.d.ts +26 -0
- package/dist/services/ai-tool.js +148 -0
- package/dist/services/bots.js +300 -0
- package/dist/services/broadcasts.js +390 -0
- package/dist/services/chats.js +83 -0
- package/dist/services/cleanup.js +83 -0
- package/dist/services/commands.js +140 -0
- package/dist/services/deliveries.js +53 -0
- package/dist/services/destinations.js +91 -0
- package/dist/services/event-rules.js +229 -0
- package/dist/services/events.js +20 -0
- package/dist/services/idempotency.js +64 -0
- package/dist/services/links.js +200 -0
- package/dist/services/menu.js +95 -0
- package/dist/services/ops.js +90 -0
- package/dist/services/rekey.js +63 -0
- package/dist/services/reports.js +87 -0
- package/dist/services/schedules.js +214 -0
- package/dist/services/send.d.ts +14 -0
- package/dist/services/send.js +421 -0
- package/dist/services/subscriptions.js +28 -0
- package/dist/services/templates.js +259 -0
- package/dist/telegram/classify.d.ts +30 -0
- package/dist/telegram/classify.js +164 -0
- package/dist/telegram/client.d.ts +73 -0
- package/dist/telegram/client.js +135 -0
- package/dist/telegram/errors.d.ts +37 -0
- package/dist/telegram/errors.js +62 -0
- package/dist/telegram/inbound.d.ts +40 -0
- package/dist/telegram/inbound.js +72 -0
- package/dist/telegram/index.d.ts +8 -0
- package/dist/telegram/multipart.d.ts +5 -0
- package/dist/telegram/multipart.js +47 -0
- package/dist/telegram/types.d.ts +271 -0
- package/dist/telegram/update.d.ts +833 -0
- package/dist/telegram/update.js +129 -0
- package/dist/testing/fake-html.d.ts +9 -0
- package/dist/testing/fake-html.js +83 -0
- package/dist/testing/fake-telegram.d.ts +206 -0
- package/dist/testing/fake-telegram.js +856 -0
- package/dist/testing/index.d.ts +7 -0
- package/dist/testing/index.js +7 -0
- package/dist/testing/reference-sql.d.ts +4 -0
- package/dist/testing/reference-sql.js +8 -0
- package/dist/testing/test-plugin.d.ts +126 -0
- package/dist/testing/test-plugin.js +182 -0
- package/dist/testing/updates.d.ts +100 -0
- package/dist/testing/updates.js +212 -0
- package/package.json +113 -3
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/** How a bot receives updates: Telegram webhook, or `getUpdates` polling. */
|
|
3
|
+
export declare const BOT_MODES: readonly ["webhook", "polling"];
|
|
4
|
+
/** Zod enum of {@link BOT_MODES}. */
|
|
5
|
+
export declare const BotMode: z.ZodEnum<{
|
|
6
|
+
webhook: "webhook";
|
|
7
|
+
polling: "polling";
|
|
8
|
+
}>;
|
|
9
|
+
export type BotMode = z.infer<typeof BotMode>;
|
|
10
|
+
/** Bot health: `invalid_token` after a 401 from Telegram, `webhook_error` when the webhook could not be set. */
|
|
11
|
+
export declare const BOT_STATUSES: readonly ["active", "disabled", "invalid_token", "webhook_error"];
|
|
12
|
+
/** Zod enum of {@link BOT_STATUSES}. */
|
|
13
|
+
export declare const BotStatus: z.ZodEnum<{
|
|
14
|
+
active: "active";
|
|
15
|
+
disabled: "disabled";
|
|
16
|
+
invalid_token: "invalid_token";
|
|
17
|
+
webhook_error: "webhook_error";
|
|
18
|
+
}>;
|
|
19
|
+
export type BotStatus = z.infer<typeof BotStatus>;
|
|
20
|
+
/** BotFather token shape. Never returned by the API. */
|
|
21
|
+
export declare const BotToken: z.ZodString;
|
|
22
|
+
/** Per-bot feature overrides (for example commands off on a broadcast-only bot). */
|
|
23
|
+
export declare const BotFeatures: z.ZodRecord<z.ZodEnum<{
|
|
24
|
+
core: "core";
|
|
25
|
+
commands: "commands";
|
|
26
|
+
templates: "templates";
|
|
27
|
+
schedules: "schedules";
|
|
28
|
+
reports: "reports";
|
|
29
|
+
events: "events";
|
|
30
|
+
broadcasts: "broadcasts";
|
|
31
|
+
actions: "actions";
|
|
32
|
+
dialogs: "dialogs";
|
|
33
|
+
inbound: "inbound";
|
|
34
|
+
subscriptions: "subscriptions";
|
|
35
|
+
ai: "ai";
|
|
36
|
+
ops: "ops";
|
|
37
|
+
}> & z.core.$partial, z.ZodBoolean>;
|
|
38
|
+
export type BotFeatures = z.infer<typeof BotFeatures>;
|
|
39
|
+
/** A bot as the admin UI sees it. No token, no webhook secret. */
|
|
40
|
+
export declare const BotDto: z.ZodObject<{
|
|
41
|
+
id: z.ZodString;
|
|
42
|
+
name: z.ZodString;
|
|
43
|
+
username: z.ZodString;
|
|
44
|
+
tgBotId: z.ZodString;
|
|
45
|
+
mode: z.ZodEnum<{
|
|
46
|
+
webhook: "webhook";
|
|
47
|
+
polling: "polling";
|
|
48
|
+
}>;
|
|
49
|
+
status: z.ZodEnum<{
|
|
50
|
+
active: "active";
|
|
51
|
+
disabled: "disabled";
|
|
52
|
+
invalid_token: "invalid_token";
|
|
53
|
+
webhook_error: "webhook_error";
|
|
54
|
+
}>;
|
|
55
|
+
statusDetail: z.ZodNullable<z.ZodString>;
|
|
56
|
+
checkedAt: z.ZodNullable<z.ZodNumber>;
|
|
57
|
+
defaultLocale: z.ZodString;
|
|
58
|
+
features: z.ZodRecord<z.ZodEnum<{
|
|
59
|
+
core: "core";
|
|
60
|
+
commands: "commands";
|
|
61
|
+
templates: "templates";
|
|
62
|
+
schedules: "schedules";
|
|
63
|
+
reports: "reports";
|
|
64
|
+
events: "events";
|
|
65
|
+
broadcasts: "broadcasts";
|
|
66
|
+
actions: "actions";
|
|
67
|
+
dialogs: "dialogs";
|
|
68
|
+
inbound: "inbound";
|
|
69
|
+
subscriptions: "subscriptions";
|
|
70
|
+
ai: "ai";
|
|
71
|
+
ops: "ops";
|
|
72
|
+
}> & z.core.$partial, z.ZodBoolean>;
|
|
73
|
+
ratePerSec: z.ZodNumber;
|
|
74
|
+
pausedUntil: z.ZodNullable<z.ZodNumber>;
|
|
75
|
+
createdAt: z.ZodNumber;
|
|
76
|
+
updatedAt: z.ZodNumber;
|
|
77
|
+
}, z.core.$strip>;
|
|
78
|
+
export type BotDto = z.infer<typeof BotDto>;
|
|
79
|
+
/** `POST /admin/bots` body. The token is verified with `getMe` and stored encrypted. */
|
|
80
|
+
export declare const BotCreate: z.ZodObject<{
|
|
81
|
+
name: z.ZodString;
|
|
82
|
+
token: z.ZodString;
|
|
83
|
+
defaultLocale: z.ZodOptional<z.ZodString>;
|
|
84
|
+
}, z.core.$strip>;
|
|
85
|
+
export type BotCreate = z.infer<typeof BotCreate>;
|
|
86
|
+
/** `PATCH /admin/bots/:id` body; every field optional. `ratePerSec` is 1–30, `enabled: false` disables the bot. */
|
|
87
|
+
export declare const BotPatch: z.ZodObject<{
|
|
88
|
+
name: z.ZodOptional<z.ZodString>;
|
|
89
|
+
defaultLocale: z.ZodOptional<z.ZodString>;
|
|
90
|
+
features: z.ZodOptional<z.ZodRecord<z.ZodEnum<{
|
|
91
|
+
core: "core";
|
|
92
|
+
commands: "commands";
|
|
93
|
+
templates: "templates";
|
|
94
|
+
schedules: "schedules";
|
|
95
|
+
reports: "reports";
|
|
96
|
+
events: "events";
|
|
97
|
+
broadcasts: "broadcasts";
|
|
98
|
+
actions: "actions";
|
|
99
|
+
dialogs: "dialogs";
|
|
100
|
+
inbound: "inbound";
|
|
101
|
+
subscriptions: "subscriptions";
|
|
102
|
+
ai: "ai";
|
|
103
|
+
ops: "ops";
|
|
104
|
+
}> & z.core.$partial, z.ZodBoolean>>;
|
|
105
|
+
ratePerSec: z.ZodOptional<z.ZodNumber>;
|
|
106
|
+
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
107
|
+
}, z.core.$strip>;
|
|
108
|
+
export type BotPatch = z.infer<typeof BotPatch>;
|
|
109
|
+
/** `POST /admin/bots/:id/rotate-token` body. The new token must belong to the same Telegram bot (`bot_token_mismatch`). */
|
|
110
|
+
export declare const BotRotateToken: z.ZodObject<{
|
|
111
|
+
token: z.ZodString;
|
|
112
|
+
}, z.core.$strip>;
|
|
113
|
+
export type BotRotateToken = z.infer<typeof BotRotateToken>;
|
|
114
|
+
/** `POST /admin/bots/:id/test` result (`getMe` + `getWebhookInfo`, no secrets). */
|
|
115
|
+
export declare const BotTestResult: z.ZodObject<{
|
|
116
|
+
ok: z.ZodBoolean;
|
|
117
|
+
status: z.ZodEnum<{
|
|
118
|
+
active: "active";
|
|
119
|
+
disabled: "disabled";
|
|
120
|
+
invalid_token: "invalid_token";
|
|
121
|
+
webhook_error: "webhook_error";
|
|
122
|
+
}>;
|
|
123
|
+
username: z.ZodNullable<z.ZodString>;
|
|
124
|
+
webhookUrlSet: z.ZodBoolean;
|
|
125
|
+
pendingUpdateCount: z.ZodNullable<z.ZodNumber>;
|
|
126
|
+
lastErrorAt: z.ZodNullable<z.ZodNumber>;
|
|
127
|
+
lastErrorMessage: z.ZodNullable<z.ZodString>;
|
|
128
|
+
}, z.core.$strip>;
|
|
129
|
+
export type BotTestResult = z.infer<typeof BotTestResult>;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { EpochMs, Id, Locale } from "./common.js";
|
|
2
|
+
import { FeatureKey } from "./features.js";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
// src/contracts/bots.ts
|
|
5
|
+
/** How a bot receives updates: Telegram webhook, or `getUpdates` polling. */
|
|
6
|
+
const BOT_MODES = ["webhook", "polling"];
|
|
7
|
+
/** Zod enum of {@link BOT_MODES}. */
|
|
8
|
+
const BotMode = z.enum(BOT_MODES);
|
|
9
|
+
/** Bot health: `invalid_token` after a 401 from Telegram, `webhook_error` when the webhook could not be set. */
|
|
10
|
+
const BOT_STATUSES = [
|
|
11
|
+
"active",
|
|
12
|
+
"disabled",
|
|
13
|
+
"invalid_token",
|
|
14
|
+
"webhook_error"
|
|
15
|
+
];
|
|
16
|
+
/** Zod enum of {@link BOT_STATUSES}. */
|
|
17
|
+
const BotStatus = z.enum(BOT_STATUSES);
|
|
18
|
+
/** BotFather token shape. Never returned by the API. */
|
|
19
|
+
const BotToken = z.string().regex(/^\d{1,20}:[A-Za-z0-9_-]{30,}$/, "bot_token_invalid");
|
|
20
|
+
/** Per-bot feature overrides (for example commands off on a broadcast-only bot). */
|
|
21
|
+
const BotFeatures = z.partialRecord(FeatureKey, z.boolean());
|
|
22
|
+
/** A bot as the admin UI sees it. No token, no webhook secret. */
|
|
23
|
+
const BotDto = z.object({
|
|
24
|
+
id: Id,
|
|
25
|
+
name: z.string(),
|
|
26
|
+
username: z.string(),
|
|
27
|
+
/** Telegram's numeric bot id, as text. */
|
|
28
|
+
tgBotId: z.string(),
|
|
29
|
+
mode: BotMode,
|
|
30
|
+
status: BotStatus,
|
|
31
|
+
/** Human-readable reason for a non-`active` status, or null. */
|
|
32
|
+
statusDetail: z.string().nullable(),
|
|
33
|
+
/** Last `getMe` / webhook check (epoch ms UTC), or null if never checked. */
|
|
34
|
+
checkedAt: EpochMs.nullable(),
|
|
35
|
+
defaultLocale: Locale,
|
|
36
|
+
features: BotFeatures,
|
|
37
|
+
/** Per-bot send rate limit (messages per second). */
|
|
38
|
+
ratePerSec: z.number().int(),
|
|
39
|
+
/** Sending is paused until this time after a Telegram 429 (epoch ms UTC), or null. */
|
|
40
|
+
pausedUntil: EpochMs.nullable(),
|
|
41
|
+
createdAt: EpochMs,
|
|
42
|
+
updatedAt: EpochMs
|
|
43
|
+
});
|
|
44
|
+
/** `POST /admin/bots` body. The token is verified with `getMe` and stored encrypted. */
|
|
45
|
+
const BotCreate = z.object({
|
|
46
|
+
name: z.string().trim().min(1).max(80),
|
|
47
|
+
token: BotToken,
|
|
48
|
+
defaultLocale: Locale.optional()
|
|
49
|
+
});
|
|
50
|
+
/** `PATCH /admin/bots/:id` body; every field optional. `ratePerSec` is 1–30, `enabled: false` disables the bot. */
|
|
51
|
+
const BotPatch = z.object({
|
|
52
|
+
name: z.string().trim().min(1).max(80),
|
|
53
|
+
defaultLocale: Locale,
|
|
54
|
+
features: BotFeatures,
|
|
55
|
+
ratePerSec: z.number().int().min(1).max(30),
|
|
56
|
+
enabled: z.boolean()
|
|
57
|
+
}).partial();
|
|
58
|
+
/** `POST /admin/bots/:id/rotate-token` body. The new token must belong to the same Telegram bot (`bot_token_mismatch`). */
|
|
59
|
+
const BotRotateToken = z.object({ token: BotToken });
|
|
60
|
+
/** `POST /admin/bots/:id/test` result (`getMe` + `getWebhookInfo`, no secrets). */
|
|
61
|
+
const BotTestResult = z.object({
|
|
62
|
+
ok: z.boolean(),
|
|
63
|
+
status: BotStatus,
|
|
64
|
+
username: z.string().nullable(),
|
|
65
|
+
webhookUrlSet: z.boolean(),
|
|
66
|
+
pendingUpdateCount: z.number().int().nonnegative().nullable(),
|
|
67
|
+
lastErrorAt: EpochMs.nullable(),
|
|
68
|
+
lastErrorMessage: z.string().nullable()
|
|
69
|
+
});
|
|
70
|
+
export { BOT_MODES, BOT_STATUSES, BotCreate, BotDto, BotFeatures, BotMode, BotPatch, BotRotateToken, BotStatus, BotTestResult, BotToken };
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/** Broadcast lifecycle: `draft` → `queued` (fan-out pending) → `sending` → `done`. */
|
|
3
|
+
export declare const BROADCAST_STATUSES: readonly ["draft", "queued", "sending", "done"];
|
|
4
|
+
/** Zod enum of {@link BROADCAST_STATUSES}. */
|
|
5
|
+
export declare const BroadcastStatus: z.ZodEnum<{
|
|
6
|
+
draft: "draft";
|
|
7
|
+
queued: "queued";
|
|
8
|
+
sending: "sending";
|
|
9
|
+
done: "done";
|
|
10
|
+
}>;
|
|
11
|
+
export type BroadcastStatus = z.infer<typeof BroadcastStatus>;
|
|
12
|
+
/** Delivery counters for one broadcast (null on the DTO until it is sent). */
|
|
13
|
+
export declare const BroadcastStats: z.ZodObject<{
|
|
14
|
+
total: z.ZodNumber;
|
|
15
|
+
queued: z.ZodNumber;
|
|
16
|
+
sent: z.ZodNumber;
|
|
17
|
+
failed: z.ZodNumber;
|
|
18
|
+
dropped: z.ZodNumber;
|
|
19
|
+
}, z.core.$strip>;
|
|
20
|
+
export type BroadcastStats = z.infer<typeof BroadcastStats>;
|
|
21
|
+
/** A file to attach: a host file-source reference. */
|
|
22
|
+
export declare const FileRef: z.ZodObject<{
|
|
23
|
+
source: z.ZodString;
|
|
24
|
+
ref: z.ZodString;
|
|
25
|
+
}, z.core.$strip>;
|
|
26
|
+
export type FileRef = z.infer<typeof FileRef>;
|
|
27
|
+
/** A broadcast as the admin UI sees it (`/admin/broadcasts`, permission `telegram.broadcasts.send`). */
|
|
28
|
+
export declare const BroadcastDto: z.ZodObject<{
|
|
29
|
+
id: z.ZodString;
|
|
30
|
+
title: z.ZodString;
|
|
31
|
+
templateId: z.ZodNullable<z.ZodString>;
|
|
32
|
+
body: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
33
|
+
params: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
34
|
+
file: z.ZodNullable<z.ZodObject<{
|
|
35
|
+
source: z.ZodString;
|
|
36
|
+
ref: z.ZodString;
|
|
37
|
+
}, z.core.$strip>>;
|
|
38
|
+
recipients: z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
|
|
39
|
+
destination: z.ZodString;
|
|
40
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
41
|
+
chat: z.ZodString;
|
|
42
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
43
|
+
user: z.ZodString;
|
|
44
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
45
|
+
role: z.ZodString;
|
|
46
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
47
|
+
allLinked: z.ZodLiteral<true>;
|
|
48
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
49
|
+
audience: z.ZodString;
|
|
50
|
+
ref: z.ZodString;
|
|
51
|
+
}, z.core.$strict>]>>;
|
|
52
|
+
status: z.ZodEnum<{
|
|
53
|
+
draft: "draft";
|
|
54
|
+
queued: "queued";
|
|
55
|
+
sending: "sending";
|
|
56
|
+
done: "done";
|
|
57
|
+
}>;
|
|
58
|
+
stats: z.ZodNullable<z.ZodObject<{
|
|
59
|
+
total: z.ZodNumber;
|
|
60
|
+
queued: z.ZodNumber;
|
|
61
|
+
sent: z.ZodNumber;
|
|
62
|
+
failed: z.ZodNumber;
|
|
63
|
+
dropped: z.ZodNumber;
|
|
64
|
+
}, z.core.$strip>>;
|
|
65
|
+
createdBy: z.ZodNullable<z.ZodString>;
|
|
66
|
+
createdAt: z.ZodNumber;
|
|
67
|
+
sentAt: z.ZodNullable<z.ZodNumber>;
|
|
68
|
+
}, z.core.$strip>;
|
|
69
|
+
export type BroadcastDto = z.infer<typeof BroadcastDto>;
|
|
70
|
+
/** Either a template or an inline body (or only a file). */
|
|
71
|
+
export declare const BroadcastSave: z.ZodObject<{
|
|
72
|
+
title: z.ZodString;
|
|
73
|
+
templateId: z.ZodDefault<z.ZodNullable<z.ZodString>>;
|
|
74
|
+
body: z.ZodDefault<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodString>>>;
|
|
75
|
+
params: z.ZodDefault<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
|
|
76
|
+
file: z.ZodDefault<z.ZodNullable<z.ZodObject<{
|
|
77
|
+
source: z.ZodString;
|
|
78
|
+
ref: z.ZodString;
|
|
79
|
+
}, z.core.$strip>>>;
|
|
80
|
+
recipients: z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
|
|
81
|
+
destination: z.ZodString;
|
|
82
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
83
|
+
chat: z.ZodString;
|
|
84
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
85
|
+
user: z.ZodString;
|
|
86
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
87
|
+
role: z.ZodString;
|
|
88
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
89
|
+
allLinked: z.ZodLiteral<true>;
|
|
90
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
91
|
+
audience: z.ZodString;
|
|
92
|
+
ref: z.ZodString;
|
|
93
|
+
}, z.core.$strict>]>>;
|
|
94
|
+
}, z.core.$strip>;
|
|
95
|
+
export type BroadcastSave = z.infer<typeof BroadcastSave>;
|
|
96
|
+
/** `GET /admin/broadcasts?status=`. */
|
|
97
|
+
export declare const BroadcastQuery: z.ZodObject<{
|
|
98
|
+
status: z.ZodOptional<z.ZodEnum<{
|
|
99
|
+
draft: "draft";
|
|
100
|
+
queued: "queued";
|
|
101
|
+
sending: "sending";
|
|
102
|
+
done: "done";
|
|
103
|
+
}>>;
|
|
104
|
+
}, z.core.$strip>;
|
|
105
|
+
export type BroadcastQuery = z.infer<typeof BroadcastQuery>;
|
|
106
|
+
/** `POST /admin/broadcasts/:id/preview`: render as a role or a user (like the template preview). */
|
|
107
|
+
export declare const BroadcastPreviewRequest: z.ZodObject<{
|
|
108
|
+
as: z.ZodUnion<readonly [z.ZodObject<{
|
|
109
|
+
role: z.ZodString;
|
|
110
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
111
|
+
userId: z.ZodString;
|
|
112
|
+
}, z.core.$strict>]>;
|
|
113
|
+
locale: z.ZodString;
|
|
114
|
+
sample: z.ZodOptional<z.ZodBoolean>;
|
|
115
|
+
}, z.core.$strip>;
|
|
116
|
+
export type BroadcastPreviewRequest = z.infer<typeof BroadcastPreviewRequest>;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { EpochMs, Id, JsonObject, Locale, LocalizedText } from "./common.js";
|
|
2
|
+
import { Recipients } from "./recipients.js";
|
|
3
|
+
import { PreviewAs } from "./templates.js";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
// src/contracts/broadcasts.ts
|
|
6
|
+
/** Broadcast lifecycle: `draft` → `queued` (fan-out pending) → `sending` → `done`. */
|
|
7
|
+
const BROADCAST_STATUSES = [
|
|
8
|
+
"draft",
|
|
9
|
+
"queued",
|
|
10
|
+
"sending",
|
|
11
|
+
"done"
|
|
12
|
+
];
|
|
13
|
+
/** Zod enum of {@link BROADCAST_STATUSES}. */
|
|
14
|
+
const BroadcastStatus = z.enum(BROADCAST_STATUSES);
|
|
15
|
+
/** Delivery counters for one broadcast (null on the DTO until it is sent). */
|
|
16
|
+
const BroadcastStats = z.object({
|
|
17
|
+
total: z.number().int().nonnegative(),
|
|
18
|
+
queued: z.number().int().nonnegative(),
|
|
19
|
+
sent: z.number().int().nonnegative(),
|
|
20
|
+
failed: z.number().int().nonnegative(),
|
|
21
|
+
dropped: z.number().int().nonnegative()
|
|
22
|
+
});
|
|
23
|
+
/** A file to attach: a host file-source reference. */
|
|
24
|
+
const FileRef = z.object({
|
|
25
|
+
source: z.string().min(1).max(64),
|
|
26
|
+
ref: z.string().min(1).max(512)
|
|
27
|
+
});
|
|
28
|
+
/** A broadcast as the admin UI sees it (`/admin/broadcasts`, permission `telegram.broadcasts.send`). */
|
|
29
|
+
const BroadcastDto = z.object({
|
|
30
|
+
id: Id,
|
|
31
|
+
title: z.string(),
|
|
32
|
+
templateId: Id.nullable(),
|
|
33
|
+
body: LocalizedText.nullable(),
|
|
34
|
+
params: JsonObject.nullable(),
|
|
35
|
+
file: FileRef.nullable(),
|
|
36
|
+
recipients: Recipients,
|
|
37
|
+
status: BroadcastStatus,
|
|
38
|
+
stats: BroadcastStats.nullable(),
|
|
39
|
+
/** Host user id of the creator, or null. */
|
|
40
|
+
createdBy: z.string().nullable(),
|
|
41
|
+
createdAt: EpochMs,
|
|
42
|
+
/** When `send` was requested (epoch ms UTC), or null for drafts. */
|
|
43
|
+
sentAt: EpochMs.nullable()
|
|
44
|
+
});
|
|
45
|
+
/** Either a template or an inline body (or only a file). */
|
|
46
|
+
const BroadcastSave = z.object({
|
|
47
|
+
title: z.string().trim().min(1).max(120),
|
|
48
|
+
templateId: Id.nullable().default(null),
|
|
49
|
+
body: LocalizedText.nullable().default(null),
|
|
50
|
+
params: JsonObject.nullable().default(null),
|
|
51
|
+
file: FileRef.nullable().default(null),
|
|
52
|
+
recipients: Recipients
|
|
53
|
+
}).refine((b) => b.templateId !== null || b.body !== null || b.file !== null, "template, body or file required").refine((b) => b.templateId === null || b.body === null, "template or body, not both");
|
|
54
|
+
/** `GET /admin/broadcasts?status=`. */
|
|
55
|
+
const BroadcastQuery = z.object({ status: BroadcastStatus.optional() });
|
|
56
|
+
/** `POST /admin/broadcasts/:id/preview`: render as a role or a user (like the template preview). */
|
|
57
|
+
const BroadcastPreviewRequest = z.object({
|
|
58
|
+
as: PreviewAs,
|
|
59
|
+
locale: Locale,
|
|
60
|
+
/** Use the provider's `sample()` instead of live data (template broadcasts). */
|
|
61
|
+
sample: z.boolean().optional()
|
|
62
|
+
});
|
|
63
|
+
export { BROADCAST_STATUSES, BroadcastDto, BroadcastPreviewRequest, BroadcastQuery, BroadcastSave, BroadcastStats, BroadcastStatus, FileRef };
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/** Telegram chat types. */
|
|
3
|
+
export declare const CHAT_KINDS: readonly ["private", "group", "supergroup", "channel"];
|
|
4
|
+
/** Zod enum of {@link CHAT_KINDS}. */
|
|
5
|
+
export declare const ChatKind: z.ZodEnum<{
|
|
6
|
+
private: "private";
|
|
7
|
+
group: "group";
|
|
8
|
+
supergroup: "supergroup";
|
|
9
|
+
channel: "channel";
|
|
10
|
+
}>;
|
|
11
|
+
export type ChatKind = z.infer<typeof ChatKind>;
|
|
12
|
+
/** Chat lifecycle: `pending` until linked, `blocked`/`left` when the bot can no longer post, `migrated` after a group → supergroup upgrade. */
|
|
13
|
+
export declare const CHAT_STATUSES: readonly ["pending", "active", "blocked", "left", "migrated"];
|
|
14
|
+
/** Zod enum of {@link CHAT_STATUSES}. */
|
|
15
|
+
export declare const ChatStatus: z.ZodEnum<{
|
|
16
|
+
active: "active";
|
|
17
|
+
pending: "pending";
|
|
18
|
+
blocked: "blocked";
|
|
19
|
+
left: "left";
|
|
20
|
+
migrated: "migrated";
|
|
21
|
+
}>;
|
|
22
|
+
export type ChatStatus = z.infer<typeof ChatStatus>;
|
|
23
|
+
/** Whose permissions apply to what a group sees: a host role, or a fixed list of users. */
|
|
24
|
+
export declare const Audience: z.ZodUnion<readonly [z.ZodObject<{
|
|
25
|
+
role: z.ZodString;
|
|
26
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
27
|
+
users: z.ZodArray<z.ZodString>;
|
|
28
|
+
}, z.core.$strict>]>;
|
|
29
|
+
export type Audience = z.infer<typeof Audience>;
|
|
30
|
+
/** Forum topics known for a chat: name → `message_thread_id`. */
|
|
31
|
+
export declare const ChatTopics: z.ZodRecord<z.ZodString, z.ZodNumber>;
|
|
32
|
+
export type ChatTopics = z.infer<typeof ChatTopics>;
|
|
33
|
+
/** A chat the bot knows (`/admin/chats`, permission `telegram.chats.manage`). */
|
|
34
|
+
export declare const ChatDto: z.ZodObject<{
|
|
35
|
+
id: z.ZodString;
|
|
36
|
+
botId: z.ZodString;
|
|
37
|
+
chatId: z.ZodString;
|
|
38
|
+
kind: z.ZodEnum<{
|
|
39
|
+
private: "private";
|
|
40
|
+
group: "group";
|
|
41
|
+
supergroup: "supergroup";
|
|
42
|
+
channel: "channel";
|
|
43
|
+
}>;
|
|
44
|
+
title: z.ZodNullable<z.ZodString>;
|
|
45
|
+
username: z.ZodNullable<z.ZodString>;
|
|
46
|
+
userId: z.ZodNullable<z.ZodString>;
|
|
47
|
+
audience: z.ZodNullable<z.ZodUnion<readonly [z.ZodObject<{
|
|
48
|
+
role: z.ZodString;
|
|
49
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
50
|
+
users: z.ZodArray<z.ZodString>;
|
|
51
|
+
}, z.core.$strict>]>>;
|
|
52
|
+
status: z.ZodEnum<{
|
|
53
|
+
active: "active";
|
|
54
|
+
pending: "pending";
|
|
55
|
+
blocked: "blocked";
|
|
56
|
+
left: "left";
|
|
57
|
+
migrated: "migrated";
|
|
58
|
+
}>;
|
|
59
|
+
locale: z.ZodNullable<z.ZodString>;
|
|
60
|
+
timezone: z.ZodNullable<z.ZodString>;
|
|
61
|
+
topics: z.ZodRecord<z.ZodString, z.ZodNumber>;
|
|
62
|
+
linkedBy: z.ZodNullable<z.ZodString>;
|
|
63
|
+
linkedAt: z.ZodNullable<z.ZodNumber>;
|
|
64
|
+
updatedAt: z.ZodNumber;
|
|
65
|
+
}, z.core.$strip>;
|
|
66
|
+
export type ChatDto = z.infer<typeof ChatDto>;
|
|
67
|
+
/** `PATCH /admin/chats/:id` body; every field optional, `null` clears an override. */
|
|
68
|
+
export declare const ChatPatch: z.ZodObject<{
|
|
69
|
+
audience: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodObject<{
|
|
70
|
+
role: z.ZodString;
|
|
71
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
72
|
+
users: z.ZodArray<z.ZodString>;
|
|
73
|
+
}, z.core.$strict>]>>>;
|
|
74
|
+
locale: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
75
|
+
timezone: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
76
|
+
topics: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodNumber>>;
|
|
77
|
+
}, z.core.$strip>;
|
|
78
|
+
export type ChatPatch = z.infer<typeof ChatPatch>;
|
|
79
|
+
/** Filters for `GET /admin/chats` (`user` = host user id). */
|
|
80
|
+
export declare const ChatQuery: z.ZodObject<{
|
|
81
|
+
bot: z.ZodOptional<z.ZodString>;
|
|
82
|
+
kind: z.ZodOptional<z.ZodEnum<{
|
|
83
|
+
private: "private";
|
|
84
|
+
group: "group";
|
|
85
|
+
supergroup: "supergroup";
|
|
86
|
+
channel: "channel";
|
|
87
|
+
}>>;
|
|
88
|
+
status: z.ZodOptional<z.ZodEnum<{
|
|
89
|
+
active: "active";
|
|
90
|
+
pending: "pending";
|
|
91
|
+
blocked: "blocked";
|
|
92
|
+
left: "left";
|
|
93
|
+
migrated: "migrated";
|
|
94
|
+
}>>;
|
|
95
|
+
user: z.ZodOptional<z.ZodString>;
|
|
96
|
+
}, z.core.$strip>;
|
|
97
|
+
export type ChatQuery = z.infer<typeof ChatQuery>;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { EpochMs, Id, Locale, TelegramChatId, TimeZone } from "./common.js";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
// src/contracts/chats.ts
|
|
4
|
+
/** Telegram chat types. */
|
|
5
|
+
const CHAT_KINDS = [
|
|
6
|
+
"private",
|
|
7
|
+
"group",
|
|
8
|
+
"supergroup",
|
|
9
|
+
"channel"
|
|
10
|
+
];
|
|
11
|
+
/** Zod enum of {@link CHAT_KINDS}. */
|
|
12
|
+
const ChatKind = z.enum(CHAT_KINDS);
|
|
13
|
+
/** Chat lifecycle: `pending` until linked, `blocked`/`left` when the bot can no longer post, `migrated` after a group → supergroup upgrade. */
|
|
14
|
+
const CHAT_STATUSES = [
|
|
15
|
+
"pending",
|
|
16
|
+
"active",
|
|
17
|
+
"blocked",
|
|
18
|
+
"left",
|
|
19
|
+
"migrated"
|
|
20
|
+
];
|
|
21
|
+
/** Zod enum of {@link CHAT_STATUSES}. */
|
|
22
|
+
const ChatStatus = z.enum(CHAT_STATUSES);
|
|
23
|
+
/** Whose permissions apply to what a group sees: a host role, or a fixed list of users. */
|
|
24
|
+
const Audience = z.union([z.strictObject({ role: z.string().min(1).max(64) }), z.strictObject({ users: z.array(z.string().min(1)).min(1).max(100) })]);
|
|
25
|
+
/** Forum topics known for a chat: name → `message_thread_id`. */
|
|
26
|
+
const ChatTopics = z.record(z.string().min(1).max(128), z.number().int().positive());
|
|
27
|
+
/** A chat the bot knows (`/admin/chats`, permission `telegram.chats.manage`). */
|
|
28
|
+
const ChatDto = z.object({
|
|
29
|
+
id: Id,
|
|
30
|
+
botId: Id,
|
|
31
|
+
/** Telegram chat id (text). */
|
|
32
|
+
chatId: TelegramChatId,
|
|
33
|
+
kind: ChatKind,
|
|
34
|
+
title: z.string().nullable(),
|
|
35
|
+
username: z.string().nullable(),
|
|
36
|
+
/** Host user linked to a private chat, or null. */
|
|
37
|
+
userId: z.string().nullable(),
|
|
38
|
+
/** Whose permissions a group or channel sees; null for private chats or unset groups. */
|
|
39
|
+
audience: Audience.nullable(),
|
|
40
|
+
status: ChatStatus,
|
|
41
|
+
/** Locale override, or null for the bot default. */
|
|
42
|
+
locale: Locale.nullable(),
|
|
43
|
+
/** IANA zone override for this chat, or null for the bot/host default. */
|
|
44
|
+
timezone: z.string().nullable(),
|
|
45
|
+
topics: ChatTopics,
|
|
46
|
+
/** Host user id who linked the chat, or null. */
|
|
47
|
+
linkedBy: z.string().nullable(),
|
|
48
|
+
/** When the chat was linked (epoch ms UTC), or null. */
|
|
49
|
+
linkedAt: EpochMs.nullable(),
|
|
50
|
+
updatedAt: EpochMs
|
|
51
|
+
});
|
|
52
|
+
/** `PATCH /admin/chats/:id` body; every field optional, `null` clears an override. */
|
|
53
|
+
const ChatPatch = z.object({
|
|
54
|
+
audience: Audience.nullable(),
|
|
55
|
+
locale: Locale.nullable(),
|
|
56
|
+
timezone: TimeZone.nullable(),
|
|
57
|
+
topics: ChatTopics
|
|
58
|
+
}).partial();
|
|
59
|
+
/** Filters for `GET /admin/chats` (`user` = host user id). */
|
|
60
|
+
const ChatQuery = z.object({
|
|
61
|
+
bot: Id.optional(),
|
|
62
|
+
kind: ChatKind.optional(),
|
|
63
|
+
status: ChatStatus.optional(),
|
|
64
|
+
user: z.string().optional()
|
|
65
|
+
});
|
|
66
|
+
export { Audience, CHAT_KINDS, CHAT_STATUSES, ChatDto, ChatKind, ChatPatch, ChatQuery, ChatStatus, ChatTopics };
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/** Telegram command name: lowercase, ≤ 32 chars, `[a-z0-9_]`. */
|
|
3
|
+
export declare const CommandName: z.ZodString;
|
|
4
|
+
/** Commands the plugin implements itself. */
|
|
5
|
+
export declare const BUILTIN_COMMANDS: readonly ["start", "help", "stop", "settings", "whoami", "language"];
|
|
6
|
+
/** Zod enum of {@link BUILTIN_COMMANDS}. */
|
|
7
|
+
export declare const BuiltinCommand: z.ZodEnum<{
|
|
8
|
+
start: "start";
|
|
9
|
+
help: "help";
|
|
10
|
+
stop: "stop";
|
|
11
|
+
settings: "settings";
|
|
12
|
+
whoami: "whoami";
|
|
13
|
+
language: "language";
|
|
14
|
+
}>;
|
|
15
|
+
export type BuiltinCommand = z.infer<typeof BuiltinCommand>;
|
|
16
|
+
/** A registered command and its per-bot configuration (`tg_command`). */
|
|
17
|
+
export declare const CommandConfigDto: z.ZodObject<{
|
|
18
|
+
command: z.ZodString;
|
|
19
|
+
builtin: z.ZodBoolean;
|
|
20
|
+
enabled: z.ZodBoolean;
|
|
21
|
+
roles: z.ZodNullable<z.ZodArray<z.ZodString>>;
|
|
22
|
+
defaultRoles: z.ZodArray<z.ZodString>;
|
|
23
|
+
aliases: z.ZodArray<z.ZodString>;
|
|
24
|
+
description: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
25
|
+
showInMenu: z.ZodBoolean;
|
|
26
|
+
sort: z.ZodNumber;
|
|
27
|
+
scope: z.ZodArray<z.ZodEnum<{
|
|
28
|
+
private: "private";
|
|
29
|
+
group: "group";
|
|
30
|
+
supergroup: "supergroup";
|
|
31
|
+
channel: "channel";
|
|
32
|
+
}>>;
|
|
33
|
+
permission: z.ZodNullable<z.ZodString>;
|
|
34
|
+
}, z.core.$strip>;
|
|
35
|
+
export type CommandConfigDto = z.infer<typeof CommandConfigDto>;
|
|
36
|
+
/** `PUT /admin/bots/:id/commands/:command` body (permission `telegram.commands.manage`); every field optional. */
|
|
37
|
+
export declare const CommandConfigSave: z.ZodObject<{
|
|
38
|
+
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
39
|
+
roles: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodString>>>;
|
|
40
|
+
aliases: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
41
|
+
description: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodString>>>;
|
|
42
|
+
showInMenu: z.ZodOptional<z.ZodBoolean>;
|
|
43
|
+
sort: z.ZodOptional<z.ZodNumber>;
|
|
44
|
+
}, z.core.$strip>;
|
|
45
|
+
export type CommandConfigSave = z.infer<typeof CommandConfigSave>;
|
|
46
|
+
/** `POST /admin/bots/:id/commands/sync`. */
|
|
47
|
+
export declare const CommandSyncResult: z.ZodObject<{
|
|
48
|
+
synced: z.ZodBoolean;
|
|
49
|
+
calls: z.ZodNumber;
|
|
50
|
+
failed: z.ZodNumber;
|
|
51
|
+
}, z.core.$strip>;
|
|
52
|
+
export type CommandSyncResult = z.infer<typeof CommandSyncResult>;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { LocalizedText } from "./common.js";
|
|
2
|
+
import { ChatKind } from "./chats.js";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
// src/contracts/commands.ts
|
|
5
|
+
/** Telegram command name: lowercase, ≤ 32 chars, `[a-z0-9_]`. */
|
|
6
|
+
const CommandName = z.string().regex(/^[a-z0-9_]{1,32}$/, "command");
|
|
7
|
+
/** Commands the plugin implements itself. */
|
|
8
|
+
const BUILTIN_COMMANDS = [
|
|
9
|
+
"start",
|
|
10
|
+
"help",
|
|
11
|
+
"stop",
|
|
12
|
+
"settings",
|
|
13
|
+
"whoami",
|
|
14
|
+
"language"
|
|
15
|
+
];
|
|
16
|
+
/** Zod enum of {@link BUILTIN_COMMANDS}. */
|
|
17
|
+
const BuiltinCommand = z.enum(BUILTIN_COMMANDS);
|
|
18
|
+
/** A registered command and its per-bot configuration (`tg_command`). */
|
|
19
|
+
const CommandConfigDto = z.object({
|
|
20
|
+
command: CommandName,
|
|
21
|
+
builtin: z.boolean(),
|
|
22
|
+
enabled: z.boolean(),
|
|
23
|
+
/** Per-bot roles: `["*"]` = any role, `[]` = no role, null = the code's `defaultRoles`. */
|
|
24
|
+
roles: z.array(z.string()).nullable(),
|
|
25
|
+
/** Roles from the command's code definition (`["*"]` = any role, `[]` = no role). */
|
|
26
|
+
defaultRoles: z.array(z.string()),
|
|
27
|
+
aliases: z.array(CommandName),
|
|
28
|
+
description: LocalizedText,
|
|
29
|
+
showInMenu: z.boolean(),
|
|
30
|
+
/** Menu order (ascending). */
|
|
31
|
+
sort: z.number().int(),
|
|
32
|
+
/** Chat kinds where the command is available. */
|
|
33
|
+
scope: z.array(ChatKind),
|
|
34
|
+
/** Host permission required to run it, or null. */
|
|
35
|
+
permission: z.string().nullable()
|
|
36
|
+
});
|
|
37
|
+
/** `PUT /admin/bots/:id/commands/:command` body (permission `telegram.commands.manage`); every field optional. */
|
|
38
|
+
const CommandConfigSave = z.object({
|
|
39
|
+
enabled: z.boolean(),
|
|
40
|
+
/** `["*"]` = any role, `[]` = nobody, null = back to the code's `defaultRoles`. */
|
|
41
|
+
roles: z.array(z.string().min(1)).nullable(),
|
|
42
|
+
aliases: z.array(CommandName).max(10),
|
|
43
|
+
description: LocalizedText.nullable(),
|
|
44
|
+
showInMenu: z.boolean(),
|
|
45
|
+
sort: z.number().int().min(0).max(1e3)
|
|
46
|
+
}).partial();
|
|
47
|
+
/** `POST /admin/bots/:id/commands/sync`. */
|
|
48
|
+
const CommandSyncResult = z.object({
|
|
49
|
+
synced: z.boolean(),
|
|
50
|
+
calls: z.number().int().nonnegative(),
|
|
51
|
+
failed: z.number().int().nonnegative()
|
|
52
|
+
});
|
|
53
|
+
export { BUILTIN_COMMANDS, BuiltinCommand, CommandConfigDto, CommandConfigSave, CommandName, CommandSyncResult };
|