tgplus 1.0.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.
Files changed (54) hide show
  1. package/LICENSE +52 -0
  2. package/README.md +1512 -0
  3. package/dist/adapters.d.ts +46 -0
  4. package/dist/adapters.js +83 -0
  5. package/dist/adapters.js.map +1 -0
  6. package/dist/bot.d.ts +50 -0
  7. package/dist/bot.js +180 -0
  8. package/dist/bot.js.map +1 -0
  9. package/dist/client.d.ts +1139 -0
  10. package/dist/client.js +529 -0
  11. package/dist/client.js.map +1 -0
  12. package/dist/composer.d.ts +88 -0
  13. package/dist/composer.js +233 -0
  14. package/dist/composer.js.map +1 -0
  15. package/dist/context.d.ts +72 -0
  16. package/dist/context.js +149 -0
  17. package/dist/context.js.map +1 -0
  18. package/dist/decorators.d.ts +33 -0
  19. package/dist/decorators.js +39 -0
  20. package/dist/decorators.js.map +1 -0
  21. package/dist/filters.d.ts +19 -0
  22. package/dist/filters.js +81 -0
  23. package/dist/filters.js.map +1 -0
  24. package/dist/i18n.d.ts +30 -0
  25. package/dist/i18n.js +41 -0
  26. package/dist/i18n.js.map +1 -0
  27. package/dist/index.d.ts +16 -0
  28. package/dist/index.js +95 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/keyboard.d.ts +62 -0
  31. package/dist/keyboard.js +96 -0
  32. package/dist/keyboard.js.map +1 -0
  33. package/dist/rateLimit.d.ts +19 -0
  34. package/dist/rateLimit.js +32 -0
  35. package/dist/rateLimit.js.map +1 -0
  36. package/dist/richMessage.d.ts +111 -0
  37. package/dist/richMessage.js +221 -0
  38. package/dist/richMessage.js.map +1 -0
  39. package/dist/scenes.d.ts +57 -0
  40. package/dist/scenes.js +105 -0
  41. package/dist/scenes.js.map +1 -0
  42. package/dist/session-redis.d.ts +27 -0
  43. package/dist/session-redis.js +36 -0
  44. package/dist/session-redis.js.map +1 -0
  45. package/dist/session-sqlite.d.ts +29 -0
  46. package/dist/session-sqlite.js +34 -0
  47. package/dist/session-sqlite.js.map +1 -0
  48. package/dist/session.d.ts +30 -0
  49. package/dist/session.js +35 -0
  50. package/dist/session.js.map +1 -0
  51. package/dist/types.d.ts +2485 -0
  52. package/dist/types.js +11 -0
  53. package/dist/types.js.map +1 -0
  54. package/package.json +42 -0
@@ -0,0 +1,46 @@
1
+ import { Bot } from "./bot";
2
+ import { Context } from "./context";
3
+ export interface VercelLikeRequest {
4
+ method?: string;
5
+ headers: Record<string, string | string[] | undefined> | Headers;
6
+ body?: unknown;
7
+ json?: () => Promise<unknown>;
8
+ }
9
+ /**
10
+ * For a Vercel serverless function (pages/api or app router route handler):
11
+ *
12
+ * export default async function handler(req, res) {
13
+ * await vercelWebhookHandler(bot)(req, res);
14
+ * }
15
+ */
16
+ export declare function vercelWebhookHandler<C extends Context>(bot: Bot<C>, opts?: {
17
+ secretToken?: string;
18
+ }): (req: any, res: any) => Promise<void>;
19
+ export interface LambdaProxyEvent {
20
+ httpMethod?: string;
21
+ headers?: Record<string, string | undefined>;
22
+ body: string | null;
23
+ isBase64Encoded?: boolean;
24
+ }
25
+ export interface LambdaProxyResult {
26
+ statusCode: number;
27
+ body: string;
28
+ }
29
+ /**
30
+ * For AWS Lambda behind API Gateway:
31
+ *
32
+ * export const handler = lambdaWebhookHandler(bot);
33
+ */
34
+ export declare function lambdaWebhookHandler<C extends Context>(bot: Bot<C>, opts?: {
35
+ secretToken?: string;
36
+ }): (event: LambdaProxyEvent) => Promise<LambdaProxyResult>;
37
+ /**
38
+ * For a Cloudflare Worker:
39
+ *
40
+ * export default {
41
+ * fetch: cloudflareWebhookHandler(bot),
42
+ * };
43
+ */
44
+ export declare function cloudflareWebhookHandler<C extends Context>(bot: Bot<C>, opts?: {
45
+ secretToken?: string;
46
+ }): (request: Request) => Promise<Response>;
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.vercelWebhookHandler = vercelWebhookHandler;
4
+ exports.lambdaWebhookHandler = lambdaWebhookHandler;
5
+ exports.cloudflareWebhookHandler = cloudflareWebhookHandler;
6
+ /**
7
+ * These adapters exist because `bot.webhookCallback()` speaks Node's raw
8
+ * `http.IncomingMessage`/`ServerResponse`, which Vercel functions, Lambda,
9
+ * and Cloudflare Workers don't use natively. Each helper below adapts
10
+ * `bot.handleUpdate()` to that platform's actual request/response shape.
11
+ */
12
+ function checkSecret(headerValue, expected) {
13
+ if (!expected)
14
+ return true;
15
+ return headerValue === expected;
16
+ }
17
+ /**
18
+ * For a Vercel serverless function (pages/api or app router route handler):
19
+ *
20
+ * export default async function handler(req, res) {
21
+ * await vercelWebhookHandler(bot)(req, res);
22
+ * }
23
+ */
24
+ function vercelWebhookHandler(bot, opts = {}) {
25
+ return async (req, res) => {
26
+ if (req.method !== "POST") {
27
+ res.status?.(404).end?.() ?? res.end();
28
+ return;
29
+ }
30
+ const headerToken = typeof req.headers?.get === "function"
31
+ ? req.headers.get("x-telegram-bot-api-secret-token")
32
+ : req.headers?.["x-telegram-bot-api-secret-token"];
33
+ if (!checkSecret(Array.isArray(headerToken) ? headerToken[0] : headerToken, opts.secretToken)) {
34
+ res.status?.(401).end?.() ?? res.end();
35
+ return;
36
+ }
37
+ const update = req.body ?? (req.json ? await req.json() : undefined);
38
+ res.status?.(200).end?.() ?? res.end();
39
+ await bot.handleUpdate(update);
40
+ };
41
+ }
42
+ /**
43
+ * For AWS Lambda behind API Gateway:
44
+ *
45
+ * export const handler = lambdaWebhookHandler(bot);
46
+ */
47
+ function lambdaWebhookHandler(bot, opts = {}) {
48
+ return async (event) => {
49
+ if (event.httpMethod && event.httpMethod !== "POST") {
50
+ return { statusCode: 404, body: "" };
51
+ }
52
+ const headerToken = event.headers?.["x-telegram-bot-api-secret-token"] ?? event.headers?.["X-Telegram-Bot-Api-Secret-Token"];
53
+ if (!checkSecret(headerToken, opts.secretToken)) {
54
+ return { statusCode: 401, body: "" };
55
+ }
56
+ const raw = event.isBase64Encoded && event.body ? Buffer.from(event.body, "base64").toString("utf-8") : event.body;
57
+ const update = JSON.parse(raw ?? "{}");
58
+ await bot.handleUpdate(update);
59
+ return { statusCode: 200, body: "" };
60
+ };
61
+ }
62
+ // ---------- Cloudflare Workers (fetch-based runtime) ----------
63
+ /**
64
+ * For a Cloudflare Worker:
65
+ *
66
+ * export default {
67
+ * fetch: cloudflareWebhookHandler(bot),
68
+ * };
69
+ */
70
+ function cloudflareWebhookHandler(bot, opts = {}) {
71
+ return async (request) => {
72
+ if (request.method !== "POST")
73
+ return new Response(null, { status: 404 });
74
+ const headerToken = request.headers.get("x-telegram-bot-api-secret-token");
75
+ if (!checkSecret(headerToken, opts.secretToken))
76
+ return new Response(null, { status: 401 });
77
+ const update = (await request.json());
78
+ // Respond immediately, then process — Workers support this via `waitUntil` in the caller if needed.
79
+ await bot.handleUpdate(update);
80
+ return new Response(null, { status: 200 });
81
+ };
82
+ }
83
+ //# sourceMappingURL=adapters.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapters.js","sourceRoot":"","sources":["../src/adapters.ts"],"names":[],"mappings":"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"}
package/dist/bot.d.ts ADDED
@@ -0,0 +1,50 @@
1
+ import { IncomingMessage, ServerResponse } from "http";
2
+ import { Api, ClientOptions } from "./client";
3
+ import { Composer, Middleware } from "./composer";
4
+ import { Context } from "./context";
5
+ import * as T from "./types";
6
+ export interface BotOptions extends ClientOptions {
7
+ /** Provide a custom Context subclass if you want extra helpers/typing on ctx. */
8
+ contextType?: new (update: T.Update, api: Api, botInfo: T.User) => Context;
9
+ }
10
+ /**
11
+ * Bot ties everything together and is a Composer itself, so `bot.command(...)`,
12
+ * `bot.on(...)`, `bot.hears(...)`, `bot.action(...)`, and `bot.use(...)` all work
13
+ * directly on it — no separate "router" object required for small bots.
14
+ */
15
+ export declare class Bot<C extends Context = Context> extends Composer<C> {
16
+ readonly api: Api;
17
+ private transport;
18
+ private polling;
19
+ private botInfo?;
20
+ private ContextClass;
21
+ constructor(token: string, options?: BotOptions);
22
+ /** Register a decorator-based controller instance (see decorators.ts) alongside your functional/fluent handlers. */
23
+ useController(instance: object): this;
24
+ /** Process one Update directly — the entry point serverless adapters (adapters.ts) call after parsing the request body themselves. */
25
+ handleUpdate(update: T.Update): Promise<void>;
26
+ private dispatch;
27
+ private errorHandler?;
28
+ /** Central error handler for anything thrown inside your handlers. */
29
+ catch(fn: (err: Error, ctx: C) => unknown): this;
30
+ /** Start long polling. Resolves once polling has begun (it keeps running in the background). */
31
+ launch(opts?: {
32
+ dropPendingUpdates?: boolean;
33
+ allowedUpdates?: string[];
34
+ }): Promise<void>;
35
+ private lastOffset;
36
+ private pollLoop;
37
+ stop(): void;
38
+ /** Returns an http(s).Server-compatible request handler you can mount in Express/Fastify/raw http. */
39
+ webhookCallback(path?: string, opts?: {
40
+ secretToken?: string;
41
+ }): (req: IncomingMessage, res: ServerResponse) => Promise<void>;
42
+ /** Convenience: spin up a standalone Node http server and set the webhook in one call. */
43
+ launchWebhook(opts: {
44
+ url: string;
45
+ port: number;
46
+ path?: string;
47
+ secretToken?: string;
48
+ }): Promise<void>;
49
+ }
50
+ export { Context, Composer, Middleware, Api, T as Types };
package/dist/bot.js ADDED
@@ -0,0 +1,180 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.Types = exports.Api = exports.Composer = exports.Context = exports.Bot = void 0;
37
+ const http_1 = require("http");
38
+ const client_1 = require("./client");
39
+ Object.defineProperty(exports, "Api", { enumerable: true, get: function () { return client_1.Api; } });
40
+ const composer_1 = require("./composer");
41
+ Object.defineProperty(exports, "Composer", { enumerable: true, get: function () { return composer_1.Composer; } });
42
+ const context_1 = require("./context");
43
+ Object.defineProperty(exports, "Context", { enumerable: true, get: function () { return context_1.Context; } });
44
+ const T = __importStar(require("./types"));
45
+ exports.Types = T;
46
+ const decorators_1 = require("./decorators");
47
+ /**
48
+ * Bot ties everything together and is a Composer itself, so `bot.command(...)`,
49
+ * `bot.on(...)`, `bot.hears(...)`, `bot.action(...)`, and `bot.use(...)` all work
50
+ * directly on it — no separate "router" object required for small bots.
51
+ */
52
+ class Bot extends composer_1.Composer {
53
+ api;
54
+ transport;
55
+ polling = false;
56
+ botInfo;
57
+ ContextClass;
58
+ constructor(token, options = {}) {
59
+ super();
60
+ this.transport = new client_1.Transport(token, options);
61
+ this.api = new client_1.Api(this.transport);
62
+ this.ContextClass = options.contextType ?? context_1.Context;
63
+ }
64
+ /** Register a decorator-based controller instance (see decorators.ts) alongside your functional/fluent handlers. */
65
+ useController(instance) {
66
+ for (const { meta, fn } of (0, decorators_1.getControllerHandlers)(instance)) {
67
+ if (meta.kind === "command")
68
+ this.command(meta.value, fn);
69
+ else if (meta.kind === "hears")
70
+ this.hears(meta.value, fn);
71
+ else if (meta.kind === "action")
72
+ this.action(meta.value, fn);
73
+ else if (meta.kind === "on")
74
+ this.on(meta.value, fn);
75
+ }
76
+ return this;
77
+ }
78
+ /** Process one Update directly — the entry point serverless adapters (adapters.ts) call after parsing the request body themselves. */
79
+ async handleUpdate(update) {
80
+ return this.dispatch(update);
81
+ }
82
+ async dispatch(update) {
83
+ if (!this.botInfo)
84
+ this.botInfo = await this.api.getMe();
85
+ const ctx = new this.ContextClass(update, this.api, this.botInfo);
86
+ try {
87
+ await this.handle(ctx);
88
+ }
89
+ catch (err) {
90
+ if (this.errorHandler)
91
+ await this.errorHandler(err, ctx);
92
+ else
93
+ console.error("[tgplus] Unhandled error in handler:", err);
94
+ }
95
+ }
96
+ errorHandler;
97
+ /** Central error handler for anything thrown inside your handlers. */
98
+ catch(fn) {
99
+ this.errorHandler = fn;
100
+ return this;
101
+ }
102
+ // ----- Long polling -----
103
+ /** Start long polling. Resolves once polling has begun (it keeps running in the background). */
104
+ async launch(opts = {}) {
105
+ this.botInfo = await this.api.getMe();
106
+ await this.api.deleteWebhook({ drop_pending_updates: opts.dropPendingUpdates });
107
+ this.polling = true;
108
+ this.pollLoop(opts.allowedUpdates).catch((err) => console.error("[tgplus] polling loop crashed:", err));
109
+ const stop = () => this.stop();
110
+ process.once("SIGINT", stop);
111
+ process.once("SIGTERM", stop);
112
+ }
113
+ lastOffset = 0;
114
+ async pollLoop(allowedUpdates) {
115
+ while (this.polling) {
116
+ let updates;
117
+ try {
118
+ updates = await this.api.getUpdates({ offset: this.lastOffset, timeout: 30, allowed_updates: allowedUpdates });
119
+ }
120
+ catch (err) {
121
+ if (err instanceof client_1.TelegramApiError && err.parameters?.retry_after) {
122
+ await sleep(err.parameters.retry_after * 1000);
123
+ continue;
124
+ }
125
+ console.error("[tgplus] getUpdates failed, retrying in 3s:", err);
126
+ await sleep(3000);
127
+ continue;
128
+ }
129
+ for (const update of updates) {
130
+ this.lastOffset = update.update_id + 1;
131
+ // Fire-and-continue so one slow handler doesn't delay polling the rest of the batch.
132
+ this.dispatch(update).catch((err) => console.error("[tgplus] dispatch error:", err));
133
+ }
134
+ }
135
+ }
136
+ stop() {
137
+ this.polling = false;
138
+ }
139
+ // ----- Webhook -----
140
+ /** Returns an http(s).Server-compatible request handler you can mount in Express/Fastify/raw http. */
141
+ webhookCallback(path = "/", opts = {}) {
142
+ return async (req, res) => {
143
+ if (req.method !== "POST" || !req.url?.startsWith(path)) {
144
+ res.writeHead(404).end();
145
+ return;
146
+ }
147
+ if (opts.secretToken && req.headers["x-telegram-bot-api-secret-token"] !== opts.secretToken) {
148
+ res.writeHead(401).end();
149
+ return;
150
+ }
151
+ const chunks = [];
152
+ for await (const chunk of req)
153
+ chunks.push(chunk);
154
+ try {
155
+ const update = JSON.parse(Buffer.concat(chunks).toString("utf-8"));
156
+ res.writeHead(200).end();
157
+ await this.dispatch(update);
158
+ }
159
+ catch (err) {
160
+ console.error("[tgplus] webhook handler error:", err);
161
+ if (!res.headersSent)
162
+ res.writeHead(500).end();
163
+ }
164
+ };
165
+ }
166
+ /** Convenience: spin up a standalone Node http server and set the webhook in one call. */
167
+ async launchWebhook(opts) {
168
+ const path = opts.path ?? "/webhook";
169
+ this.botInfo = await this.api.getMe();
170
+ await this.api.setWebhook({ url: opts.url.replace(/\/$/, "") + path, secret_token: opts.secretToken });
171
+ const server = (0, http_1.createServer)(this.webhookCallback(path, { secretToken: opts.secretToken }));
172
+ await new Promise((resolve) => server.listen(opts.port, resolve));
173
+ console.log(`[tgplus] webhook listening on :${opts.port}${path}`);
174
+ }
175
+ }
176
+ exports.Bot = Bot;
177
+ function sleep(ms) {
178
+ return new Promise((r) => setTimeout(r, ms));
179
+ }
180
+ //# sourceMappingURL=bot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bot.js","sourceRoot":"","sources":["../src/bot.ts"],"names":[],"mappings":"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"}