gramio 0.0.50 → 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.
@@ -0,0 +1,1012 @@
1
+ import { CallbackData } from '@gramio/callback-data';
2
+ export * from '@gramio/callback-data';
3
+ import { Context, UpdateName, MaybeArray, ContextType, Attachment } from '@gramio/contexts';
4
+ export * from '@gramio/contexts';
5
+ import { APIMethods, TelegramResponseParameters, TelegramAPIResponseError, TelegramUser, APIMethodParams, APIMethodReturn, TelegramUpdate, TelegramReactionTypeEmojiEmoji, SetMyCommandsParams, TelegramBotCommand } from '@gramio/types';
6
+ export * from '@gramio/types';
7
+ import * as middleware_io from 'middleware-io';
8
+ import { Composer as Composer$1, Middleware, CaughtMiddlewareHandler, NextMiddleware } from 'middleware-io';
9
+ export * from '@gramio/files';
10
+ export * from '@gramio/keyboards';
11
+ export * from '@gramio/format';
12
+
13
+ /** Symbol to determine which error kind is it */
14
+ declare const ErrorKind: symbol;
15
+ /** Represent {@link TelegramAPIResponseError} and thrown in API calls */
16
+ declare class TelegramError<T extends keyof APIMethods> extends Error {
17
+ /** Name of the API Method */
18
+ method: T;
19
+ /** Params that were sent */
20
+ params: MaybeSuppressedParams<T>;
21
+ /** See {@link TelegramAPIResponseError.error_code}*/
22
+ code: number;
23
+ /** Describes why a request was unsuccessful. */
24
+ payload?: TelegramResponseParameters;
25
+ /** Construct new TelegramError */
26
+ constructor(error: TelegramAPIResponseError, method: T, params: MaybeSuppressedParams<T>);
27
+ }
28
+
29
+ /** Base-composer without chainable type-safety */
30
+ declare class Composer {
31
+ protected composer: Composer$1<Context<AnyBot> & {
32
+ [key: string]: unknown;
33
+ }, Context<AnyBot> & {
34
+ [key: string]: unknown;
35
+ }>;
36
+ length: number;
37
+ composed: Middleware<Context<AnyBot>>;
38
+ protected onError: CaughtMiddlewareHandler<Context<AnyBot>>;
39
+ constructor(onError?: CaughtMiddlewareHandler<Context<any>>);
40
+ /** Register handler to one or many Updates */
41
+ on<T extends UpdateName>(updateName: MaybeArray<T>, handler: Handler<any>): this;
42
+ /** Register handler to any Update */
43
+ use(handler: Handler<any>): this;
44
+ /**
45
+ * Derive some data to handlers
46
+ *
47
+ * @example
48
+ * ```ts
49
+ * new Bot("token").derive((context) => {
50
+ * return {
51
+ * superSend: () => context.send("Derived method")
52
+ * }
53
+ * })
54
+ * ```
55
+ */
56
+ derive<Update extends UpdateName, Handler extends Hooks.Derive<ContextType<AnyBot, Update>>>(updateNameOrHandler: MaybeArray<Update> | Handler, handler?: Handler): this;
57
+ protected recompose(): this;
58
+ compose(context: Context<AnyBot>, next?: middleware_io.NextMiddleware): void;
59
+ }
60
+
61
+ /**
62
+ * `Plugin` is an object from which you can extends in Bot instance and adopt types
63
+ *
64
+ * @example
65
+ * ```ts
66
+ * import { Plugin, Bot } from "gramio";
67
+ *
68
+ * export class PluginError extends Error {
69
+ * wow: "type" | "safe" = "type";
70
+ * }
71
+ *
72
+ * const plugin = new Plugin("gramio-example")
73
+ * .error("PLUGIN", PluginError)
74
+ * .derive(() => {
75
+ * return {
76
+ * some: ["derived", "props"] as const,
77
+ * };
78
+ * });
79
+ *
80
+ * const bot = new Bot(process.env.TOKEN!)
81
+ * .extend(plugin)
82
+ * .onError(({ context, kind, error }) => {
83
+ * if (context.is("message") && kind === "PLUGIN") {
84
+ * console.log(error.wow);
85
+ * }
86
+ * })
87
+ * .use((context) => {
88
+ * console.log(context.some);
89
+ * });
90
+ * ```
91
+ */
92
+ declare class Plugin<Errors extends ErrorDefinitions = {}, Derives extends DeriveDefinitions = DeriveDefinitions> {
93
+ /**
94
+ * @internal
95
+ * Set of Plugin data
96
+ *
97
+ *
98
+ */
99
+ _: {
100
+ /** Name of plugin */
101
+ name: string;
102
+ /** List of plugin dependencies. If user does't extend from listed there dependencies it throw a error */
103
+ dependencies: string[];
104
+ /** remap generic type. {} in runtime */
105
+ Errors: Errors;
106
+ /** remap generic type. {} in runtime */
107
+ Derives: Derives;
108
+ /** Composer */
109
+ composer: Composer;
110
+ /** Store plugin preRequests hooks */
111
+ preRequests: [Hooks.PreRequest<any>, MaybeArray<keyof APIMethods> | undefined][];
112
+ /** Store plugin onResponses hooks */
113
+ onResponses: [Hooks.OnResponse<any>, MaybeArray<keyof APIMethods> | undefined][];
114
+ /** Store plugin onResponseErrors hooks */
115
+ onResponseErrors: [Hooks.OnResponseError<any>, MaybeArray<keyof APIMethods> | undefined][];
116
+ /**
117
+ * Store plugin groups
118
+ *
119
+ * If you use `on` or `use` in group and on plugin-level groups handlers are registered after plugin-level handlers
120
+ * */
121
+ groups: ((bot: AnyBot) => AnyBot)[];
122
+ /** Store plugin onStarts hooks */
123
+ onStarts: Hooks.OnStart[];
124
+ /** Store plugin onStops hooks */
125
+ onStops: Hooks.OnStop[];
126
+ /** Store plugin onErrors hooks */
127
+ onErrors: Hooks.OnError<any, any>[];
128
+ /** Map of plugin errors */
129
+ errorsDefinitions: Record<string, {
130
+ new (...args: any): any;
131
+ prototype: Error;
132
+ }>;
133
+ decorators: Record<string, unknown>;
134
+ };
135
+ /** Create new Plugin. Please provide `name` */
136
+ constructor(name: string, { dependencies }?: {
137
+ dependencies?: string[];
138
+ });
139
+ /** Currently not isolated!!!
140
+ *
141
+ * > [!WARNING]
142
+ * > If you use `on` or `use` in a `group` and at the plugin level, the group handlers are registered **after** the handlers at the plugin level
143
+ */
144
+ group(grouped: (bot: Bot<Errors, Derives>) => AnyBot): this;
145
+ /**
146
+ * Register custom class-error in plugin
147
+ **/
148
+ error<Name extends string, NewError extends {
149
+ new (...args: any): any;
150
+ prototype: Error;
151
+ }>(kind: Name, error: NewError): Plugin<Errors & { [name in Name]: InstanceType<NewError>; }, Derives>;
152
+ /**
153
+ * Derive some data to handlers
154
+ *
155
+ * @example
156
+ * ```ts
157
+ * new Bot("token").derive((context) => {
158
+ * return {
159
+ * superSend: () => context.send("Derived method")
160
+ * }
161
+ * })
162
+ * ```
163
+ */
164
+ derive<Handler extends Hooks.Derive<Context<AnyBot> & Derives["global"]>>(handler: Handler): Plugin<Errors, Derives & {
165
+ global: Awaited<ReturnType<Handler>>;
166
+ }>;
167
+ derive<Update extends UpdateName, Handler extends Hooks.Derive<ContextType<AnyBot, Update> & Derives["global"] & Derives[Update]>>(updateName: MaybeArray<Update>, handler: Handler): Plugin<Errors, Derives & {
168
+ [K in Update]: Awaited<ReturnType<Handler>>;
169
+ }>;
170
+ decorate<Value extends Record<string, any>>(value: Value): Plugin<Errors, Derives & {
171
+ global: {
172
+ [K in keyof Value]: Value[K];
173
+ };
174
+ }>;
175
+ decorate<Name extends string, Value>(name: Name, value: Value): Plugin<Errors, Derives & {
176
+ global: {
177
+ [K in Name]: Value;
178
+ };
179
+ }>;
180
+ /** Register handler to one or many Updates */
181
+ on<T extends UpdateName>(updateName: MaybeArray<T>, handler: Handler<ContextType<AnyBot, T> & Derives["global"] & Derives[T]>): this;
182
+ /** Register handler to any Updates */
183
+ use(handler: Handler<Context<AnyBot> & Derives["global"]>): this;
184
+ /**
185
+ * This hook called before sending a request to Telegram Bot API (allows us to impact the sent parameters).
186
+ *
187
+ * @example
188
+ * ```typescript
189
+ * import { Bot } from "gramio";
190
+ *
191
+ * const bot = new Bot(process.env.TOKEN!).preRequest((context) => {
192
+ * if (context.method === "sendMessage") {
193
+ * context.params.text = "mutate params";
194
+ * }
195
+ *
196
+ * return context;
197
+ * });
198
+ *
199
+ * bot.start();
200
+ * ```
201
+ *
202
+ * [Documentation](https://gramio.dev/hooks/pre-request.html)
203
+ * */
204
+ preRequest<Methods extends keyof APIMethods, Handler extends Hooks.PreRequest<Methods>>(methods: MaybeArray<Methods>, handler: Handler): this;
205
+ preRequest(handler: Hooks.PreRequest): this;
206
+ /**
207
+ * This hook called when API return successful response
208
+ *
209
+ * [Documentation](https://gramio.dev/hooks/on-response.html)
210
+ * */
211
+ onResponse<Methods extends keyof APIMethods, Handler extends Hooks.OnResponse<Methods>>(methods: MaybeArray<Methods>, handler: Handler): this;
212
+ onResponse(handler: Hooks.OnResponse): this;
213
+ /**
214
+ * This hook called when API return an error
215
+ *
216
+ * [Documentation](https://gramio.dev/hooks/on-response-error.html)
217
+ * */
218
+ onResponseError<Methods extends keyof APIMethods, Handler extends Hooks.OnResponseError<Methods>>(methods: MaybeArray<Methods>, handler: Handler): this;
219
+ onResponseError(handler: Hooks.OnResponseError): this;
220
+ /**
221
+ * This hook called when the bot is `started`.
222
+ *
223
+ * @example
224
+ * ```typescript
225
+ * import { Bot } from "gramio";
226
+ *
227
+ * const bot = new Bot(process.env.TOKEN!).onStart(
228
+ * ({ plugins, info, updatesFrom }) => {
229
+ * console.log(`plugin list - ${plugins.join(", ")}`);
230
+ * console.log(`bot username is @${info.username}`);
231
+ * console.log(`updates from ${updatesFrom}`);
232
+ * }
233
+ * );
234
+ *
235
+ * bot.start();
236
+ * ```
237
+ *
238
+ * [Documentation](https://gramio.dev/hooks/on-start.html)
239
+ * */
240
+ onStart(handler: Hooks.OnStart): this;
241
+ /**
242
+ * This hook called when the bot stops.
243
+ *
244
+ * @example
245
+ * ```typescript
246
+ * import { Bot } from "gramio";
247
+ *
248
+ * const bot = new Bot(process.env.TOKEN!).onStop(
249
+ * ({ plugins, info, updatesFrom }) => {
250
+ * console.log(`plugin list - ${plugins.join(", ")}`);
251
+ * console.log(`bot username is @${info.username}`);
252
+ * }
253
+ * );
254
+ *
255
+ * bot.start();
256
+ * bot.stop();
257
+ * ```
258
+ *
259
+ * [Documentation](https://gramio.dev/hooks/on-stop.html)
260
+ * */
261
+ onStop(handler: Hooks.OnStop): this;
262
+ /**
263
+ * Set error handler.
264
+ * @example
265
+ * ```ts
266
+ * bot.onError("message", ({ context, kind, error }) => {
267
+ * return context.send(`${kind}: ${error.message}`);
268
+ * })
269
+ * ```
270
+ */
271
+ onError<T extends UpdateName>(updateName: MaybeArray<T>, handler: Hooks.OnError<Errors, ContextType<Bot, T> & Derives["global"] & Derives[T]>): this;
272
+ onError(handler: Hooks.OnError<Errors, Context<AnyBot> & Derives["global"]>): this;
273
+ }
274
+
275
+ /** Bot options that you can provide to {@link Bot} constructor */
276
+ interface BotOptions {
277
+ /** Bot token */
278
+ token: string;
279
+ /** When the bot begins to listen for updates, `GramIO` retrieves information about the bot to verify if the **bot token is valid**
280
+ * and to utilize some bot metadata. For instance, this metadata can be used to strip bot mentions in commands.
281
+ *
282
+ * If you set it up, `GramIO` will not send a `getMe` request on startup.
283
+ *
284
+ * @important
285
+ * **You should set this up when horizontally scaling your bot or working in serverless environments.**
286
+ * */
287
+ info?: TelegramUser;
288
+ /** List of plugins enabled by default */
289
+ plugins?: {
290
+ /** Pass `false` to disable plugin. @default true */
291
+ format?: boolean;
292
+ };
293
+ /** Options to configure how to send requests to the Telegram Bot API */
294
+ api: {
295
+ /** Configure {@link fetch} parameters */
296
+ fetchOptions?: Parameters<typeof fetch>[1];
297
+ /** URL which will be used to send requests to. @default "https://api.telegram.org/bot" */
298
+ baseURL: string;
299
+ /**
300
+ * Should we send requests to `test` data center?
301
+ * The test environment is completely separate from the main environment, so you will need to create a new user account and a new bot with `@BotFather`.
302
+ *
303
+ * [Documentation](https://core.telegram.org/bots/webapps#using-bots-in-the-test-environment)
304
+ * @default false
305
+ * */
306
+ useTest?: boolean;
307
+ /**
308
+ * Time in milliseconds before calling {@link APIMethods.getUpdates | getUpdates} again
309
+ * @default 1000
310
+ */
311
+ retryGetUpdatesWait?: number;
312
+ };
313
+ }
314
+ /**
315
+ * Handler is a function with context and next function arguments
316
+ *
317
+ * @example
318
+ * ```ts
319
+ * const handler: Handler<ContextType<Bot, "message">> = (context, _next) => context.send("HI!");
320
+ *
321
+ * bot.on("message", handler)
322
+ * ```
323
+ */
324
+ type Handler<T> = (context: T, next: NextMiddleware) => unknown;
325
+ interface ErrorHandlerParams<Ctx extends Context<AnyBot>, Kind extends string, Err> {
326
+ context: Ctx;
327
+ kind: Kind;
328
+ error: Err;
329
+ }
330
+ type AnyTelegramError<Methods extends keyof APIMethods = keyof APIMethods> = {
331
+ [APIMethod in Methods]: TelegramError<APIMethod>;
332
+ }[Methods];
333
+ type AnyTelegramMethod<Methods extends keyof APIMethods> = {
334
+ [APIMethod in Methods]: {
335
+ method: APIMethod;
336
+ params: MaybeSuppressedParams<APIMethod>;
337
+ };
338
+ }[Methods];
339
+ /**
340
+ * Interface for add `suppress` param to params
341
+ */
342
+ interface Suppress<IsSuppressed extends boolean | undefined = undefined> {
343
+ /**
344
+ * Pass `true` if you want to suppress throwing errors of this method.
345
+ *
346
+ * **But this does not undo getting into the `onResponseError` hook**.
347
+ *
348
+ * @example
349
+ * ```ts
350
+ * const response = await bot.api.sendMessage({
351
+ * suppress: true,
352
+ * chat_id: "@not_found",
353
+ * text: "Suppressed method"
354
+ * });
355
+ *
356
+ * if(response instanceof TelegramError) console.error("sendMessage returns an error...")
357
+ * else console.log("Message has been sent successfully");
358
+ * ```
359
+ *
360
+ * */
361
+ suppress?: IsSuppressed;
362
+ }
363
+ /** Type that assign API params with {@link Suppress} */
364
+ type MaybeSuppressedParams<Method extends keyof APIMethods, IsSuppressed extends boolean | undefined = undefined> = APIMethodParams<Method> & Suppress<IsSuppressed>;
365
+ /** Return method params but with {@link Suppress} */
366
+ type SuppressedAPIMethodParams<Method extends keyof APIMethods> = undefined extends APIMethodParams<Method> ? Suppress<true> : MaybeSuppressedParams<Method, true>;
367
+ /** Type that return MaybeSuppressed API method ReturnType */
368
+ type MaybeSuppressedReturn<Method extends keyof APIMethods, IsSuppressed extends boolean | undefined = undefined> = true extends IsSuppressed ? TelegramError<Method> | APIMethodReturn<Method> : APIMethodReturn<Method>;
369
+ /** Type that return {@link Suppress | Suppressed} API method ReturnType */
370
+ type SuppressedAPIMethodReturn<Method extends keyof APIMethods> = MaybeSuppressedReturn<Method, true>;
371
+ /** Map of APIMethods but with {@link Suppress} */
372
+ type SuppressedAPIMethods<Methods extends keyof APIMethods = keyof APIMethods> = {
373
+ [APIMethod in Methods]: APIMethodParams<APIMethod> extends undefined ? <IsSuppressed extends boolean | undefined = undefined>(params?: Suppress<IsSuppressed>) => Promise<MaybeSuppressedReturn<APIMethod, IsSuppressed>> : undefined extends APIMethodParams<APIMethod> ? <IsSuppressed extends boolean | undefined = undefined>(params?: MaybeSuppressedParams<APIMethod, IsSuppressed>) => Promise<MaybeSuppressedReturn<APIMethod, IsSuppressed>> : <IsSuppressed extends boolean | undefined = undefined>(params: MaybeSuppressedParams<APIMethod, IsSuppressed>) => Promise<MaybeSuppressedReturn<APIMethod, IsSuppressed>>;
374
+ };
375
+ type AnyTelegramMethodWithReturn<Methods extends keyof APIMethods> = {
376
+ [APIMethod in Methods]: {
377
+ method: APIMethod;
378
+ params: APIMethodParams<APIMethod>;
379
+ response: APIMethodReturn<APIMethod>;
380
+ };
381
+ }[Methods];
382
+ /** Type for maybe {@link Promise} or may not */
383
+ type MaybePromise<T> = Promise<T> | T;
384
+ /**
385
+ * Namespace with GramIO hooks types
386
+ *
387
+ * [Documentation](https://gramio.dev/hooks/overview.html)
388
+ * */
389
+ declare namespace Hooks {
390
+ /** Derive */
391
+ type Derive<Ctx> = (context: Ctx) => MaybePromise<Record<string, unknown>>;
392
+ /** Argument type for {@link PreRequest} */
393
+ type PreRequestContext<Methods extends keyof APIMethods> = AnyTelegramMethod<Methods>;
394
+ /**
395
+ * Type for `preRequest` hook
396
+ *
397
+ * @example
398
+ * ```typescript
399
+ * import { Bot } from "gramio";
400
+ *
401
+ * const bot = new Bot(process.env.TOKEN!).preRequest((context) => {
402
+ * if (context.method === "sendMessage") {
403
+ * context.params.text = "mutate params";
404
+ * }
405
+ *
406
+ * return context;
407
+ * });
408
+ *
409
+ * bot.start();
410
+ * ```
411
+ *
412
+ * [Documentation](https://gramio.dev/hooks/pre-request.html)
413
+ * */
414
+ type PreRequest<Methods extends keyof APIMethods = keyof APIMethods> = (ctx: PreRequestContext<Methods>) => MaybePromise<PreRequestContext<Methods>>;
415
+ /** Argument type for {@link OnError} */
416
+ type OnErrorContext<Ctx extends Context<AnyBot>, T extends ErrorDefinitions> = ErrorHandlerParams<Ctx, "TELEGRAM", AnyTelegramError> | ErrorHandlerParams<Ctx, "UNKNOWN", Error> | {
417
+ [K in keyof T]: ErrorHandlerParams<Ctx, K & string, T[K & string]>;
418
+ }[keyof T];
419
+ /**
420
+ * Type for `onError` hook
421
+ *
422
+ * @example
423
+ * ```typescript
424
+ * bot.on("message", () => {
425
+ * bot.api.sendMessage({
426
+ * chat_id: "@not_found",
427
+ * text: "Chat not exists....",
428
+ * });
429
+ * });
430
+ *
431
+ * bot.onError(({ context, kind, error }) => {
432
+ * if (context.is("message")) return context.send(`${kind}: ${error.message}`);
433
+ * });
434
+ * ```
435
+ *
436
+ * [Documentation](https://gramio.dev/hooks/on-error.html)
437
+ * */
438
+ type OnError<T extends ErrorDefinitions, Ctx extends Context<any> = Context<AnyBot>> = (options: OnErrorContext<Ctx, T>) => unknown;
439
+ /**
440
+ * Type for `onStart` hook
441
+ *
442
+ * @example
443
+ * ```typescript
444
+ * import { Bot } from "gramio";
445
+ *
446
+ * const bot = new Bot(process.env.TOKEN!).onStart(
447
+ * ({ plugins, info, updatesFrom }) => {
448
+ * console.log(`plugin list - ${plugins.join(", ")}`);
449
+ * console.log(`bot username is @${info.username}`);
450
+ * console.log(`updates from ${updatesFrom}`);
451
+ * }
452
+ * );
453
+ *
454
+ * bot.start();
455
+ * ```
456
+ *
457
+ * [Documentation](https://gramio.dev/hooks/on-start.html)
458
+ * */
459
+ type OnStart = (context: {
460
+ plugins: string[];
461
+ info: TelegramUser;
462
+ updatesFrom: "webhook" | "long-polling";
463
+ }) => unknown;
464
+ /**
465
+ * Type for `onStop` hook
466
+ *
467
+ * @example
468
+ * ```typescript
469
+ * import { Bot } from "gramio";
470
+ *
471
+ * const bot = new Bot(process.env.TOKEN!).onStop(
472
+ * ({ plugins, info, updatesFrom }) => {
473
+ * console.log(`plugin list - ${plugins.join(", ")}`);
474
+ * console.log(`bot username is @${info.username}`);
475
+ * }
476
+ * );
477
+ *
478
+ * bot.start();
479
+ * bot.stop();
480
+ * ```
481
+ *
482
+ * [Documentation](https://gramio.dev/hooks/on-stop.html)
483
+ * */
484
+ type OnStop = (context: {
485
+ plugins: string[];
486
+ info: TelegramUser;
487
+ }) => unknown;
488
+ /**
489
+ * Type for `onResponseError` hook
490
+ *
491
+ * [Documentation](https://gramio.dev/hooks/on-response-error.html)
492
+ * */
493
+ type OnResponseError<Methods extends keyof APIMethods = keyof APIMethods> = (context: AnyTelegramError<Methods>, api: Bot["api"]) => unknown;
494
+ /**
495
+ * Type for `onResponse` hook
496
+ *
497
+ * [Documentation](https://gramio.dev/hooks/on-response.html)
498
+ * */
499
+ type OnResponse<Methods extends keyof APIMethods = keyof APIMethods> = (context: AnyTelegramMethodWithReturn<Methods>) => unknown;
500
+ /** Store hooks */
501
+ interface Store<T extends ErrorDefinitions> {
502
+ preRequest: PreRequest[];
503
+ onResponse: OnResponse[];
504
+ onResponseError: OnResponseError[];
505
+ onError: OnError<T>[];
506
+ onStart: OnStart[];
507
+ onStop: OnStop[];
508
+ }
509
+ }
510
+ /** Error map should be map of string: error */
511
+ type ErrorDefinitions = Record<string, Error>;
512
+ /** Map of derives */
513
+ type DeriveDefinitions = Record<UpdateName | "global", {}>;
514
+ type FilterDefinitions = Record<string, (...args: any[]) => (context: Context<Bot>) => boolean>;
515
+ /** Type of Bot that accepts any generics */
516
+ type AnyBot = Bot<any, any>;
517
+ /** Type of Bot that accepts any generics */
518
+ type AnyPlugin = Plugin<any, any>;
519
+
520
+ declare class Updates {
521
+ private readonly bot;
522
+ isStarted: boolean;
523
+ private offset;
524
+ composer: Composer;
525
+ constructor(bot: AnyBot, onError: CaughtMiddlewareHandler<Context<any>>);
526
+ handleUpdate(data: TelegramUpdate): Promise<void>;
527
+ /** @deprecated use bot.start instead @internal */
528
+ startPolling(params?: APIMethodParams<"getUpdates">): Promise<void>;
529
+ startFetchLoop(params?: APIMethodParams<"getUpdates">): Promise<void>;
530
+ stopPolling(): void;
531
+ }
532
+
533
+ /** Bot instance
534
+ *
535
+ * @example
536
+ * ```ts
537
+ * import { Bot } from "gramio";
538
+ *
539
+ * const bot = new Bot("") // put you token here
540
+ * .command("start", (context) => context.send("Hi!"))
541
+ * .onStart(console.log);
542
+ *
543
+ * bot.start();
544
+ * ```
545
+ */
546
+ declare class Bot<Errors extends ErrorDefinitions = {}, Derives extends DeriveDefinitions = DeriveDefinitions> {
547
+ _: {
548
+ /** @internal. Remap generic */
549
+ derives: Derives;
550
+ };
551
+ /** @internal. Remap generic */
552
+ __Derives: Derives;
553
+ private filters;
554
+ /** Options provided to instance */
555
+ readonly options: BotOptions;
556
+ /** Bot data (filled in when calling bot.init/bot.start) */
557
+ info: TelegramUser | undefined;
558
+ /**
559
+ * Send API Request to Telegram Bot API
560
+ *
561
+ * @example
562
+ * ```ts
563
+ * const response = await bot.api.sendMessage({
564
+ * chat_id: "@gramio_forum",
565
+ * text: "some text",
566
+ * });
567
+ * ```
568
+ *
569
+ * [Documentation](https://gramio.dev/bot-api.html)
570
+ */
571
+ readonly api: SuppressedAPIMethods;
572
+ private lazyloadPlugins;
573
+ private dependencies;
574
+ private errorsDefinitions;
575
+ private errorHandler;
576
+ /** This instance handle updates */
577
+ updates: Updates;
578
+ private hooks;
579
+ constructor(token: string, options?: Omit<BotOptions, "token" | "api"> & {
580
+ api?: Partial<BotOptions["api"]>;
581
+ });
582
+ constructor(options: Omit<BotOptions, "api"> & {
583
+ api?: Partial<BotOptions["api"]>;
584
+ });
585
+ private runHooks;
586
+ private runImmutableHooks;
587
+ private _callApi;
588
+ /**
589
+ * Download file
590
+ *
591
+ * @example
592
+ * ```ts
593
+ * bot.on("message", async (context) => {
594
+ * if (!context.document) return;
595
+ * // download to ./file-name
596
+ * await context.download(context.document.fileName || "file-name");
597
+ * // get ArrayBuffer
598
+ * const buffer = await context.download();
599
+ *
600
+ * return context.send("Thank you!");
601
+ * });
602
+ * ```
603
+ * [Documentation](https://gramio.dev/files/download.html)
604
+ */
605
+ downloadFile(attachment: Attachment | {
606
+ file_id: string;
607
+ } | string): Promise<ArrayBuffer>;
608
+ downloadFile(attachment: Attachment | {
609
+ file_id: string;
610
+ } | string, path: string): Promise<string>;
611
+ /**
612
+ * Register custom class-error for type-safe catch in `onError` hook
613
+ *
614
+ * @example
615
+ * ```ts
616
+ * export class NoRights extends Error {
617
+ * needRole: "admin" | "moderator";
618
+ *
619
+ * constructor(role: "admin" | "moderator") {
620
+ * super();
621
+ * this.needRole = role;
622
+ * }
623
+ * }
624
+ *
625
+ * const bot = new Bot(process.env.TOKEN!)
626
+ * .error("NO_RIGHTS", NoRights)
627
+ * .onError(({ context, kind, error }) => {
628
+ * if (context.is("message") && kind === "NO_RIGHTS")
629
+ * return context.send(
630
+ * format`You don't have enough rights! You need to have an «${bold(
631
+ * error.needRole
632
+ * )}» role.`
633
+ * );
634
+ * });
635
+ *
636
+ * bot.updates.on("message", (context) => {
637
+ * if (context.text === "bun") throw new NoRights("admin");
638
+ * });
639
+ * ```
640
+ */
641
+ error<Name extends string, NewError extends {
642
+ new (...args: any): any;
643
+ prototype: Error;
644
+ }>(kind: Name, error: NewError): Bot<Errors & { [name in Name]: InstanceType<NewError>; }, Derives>;
645
+ /**
646
+ * Set error handler.
647
+ * @example
648
+ * ```ts
649
+ * bot.onError("message", ({ context, kind, error }) => {
650
+ * return context.send(`${kind}: ${error.message}`);
651
+ * })
652
+ * ```
653
+ */
654
+ onError<T extends UpdateName>(updateName: MaybeArray<T>, handler: Hooks.OnError<Errors, ContextType<typeof this, T> & Derives["global"] & Derives[T]>): this;
655
+ onError(handler: Hooks.OnError<Errors, Context<typeof this> & Derives["global"]>): this;
656
+ /**
657
+ * Derive some data to handlers
658
+ *
659
+ * @example
660
+ * ```ts
661
+ * new Bot("token").derive((context) => {
662
+ * return {
663
+ * superSend: () => context.send("Derived method")
664
+ * }
665
+ * })
666
+ * ```
667
+ */
668
+ derive<Handler extends Hooks.Derive<Context<typeof this> & Derives["global"]>>(handler: Handler): Bot<Errors, Derives & {
669
+ global: Awaited<ReturnType<Handler>>;
670
+ }>;
671
+ derive<Update extends UpdateName, Handler extends Hooks.Derive<ContextType<typeof this, Update> & Derives["global"] & Derives[Update]>>(updateName: MaybeArray<Update>, handler: Handler): Bot<Errors, Derives & {
672
+ [K in Update]: Awaited<ReturnType<Handler>>;
673
+ }>;
674
+ decorate<Value extends Record<string, any>>(value: Value): Bot<Errors, Derives & {
675
+ global: {
676
+ [K in keyof Value]: Value[K];
677
+ };
678
+ }>;
679
+ decorate<Name extends string, Value>(name: Name, value: Value): Bot<Errors, Derives & {
680
+ global: {
681
+ [K in Name]: Value;
682
+ };
683
+ }>;
684
+ /**
685
+ * This hook called when the bot is `started`.
686
+ *
687
+ * @example
688
+ * ```typescript
689
+ * import { Bot } from "gramio";
690
+ *
691
+ * const bot = new Bot(process.env.TOKEN!).onStart(
692
+ * ({ plugins, info, updatesFrom }) => {
693
+ * console.log(`plugin list - ${plugins.join(", ")}`);
694
+ * console.log(`bot username is @${info.username}`);
695
+ * console.log(`updates from ${updatesFrom}`);
696
+ * }
697
+ * );
698
+ *
699
+ * bot.start();
700
+ * ```
701
+ *
702
+ * [Documentation](https://gramio.dev/hooks/on-start.html)
703
+ * */
704
+ onStart(handler: Hooks.OnStart): this;
705
+ /**
706
+ * This hook called when the bot stops.
707
+ *
708
+ * @example
709
+ * ```typescript
710
+ * import { Bot } from "gramio";
711
+ *
712
+ * const bot = new Bot(process.env.TOKEN!).onStop(
713
+ * ({ plugins, info, updatesFrom }) => {
714
+ * console.log(`plugin list - ${plugins.join(", ")}`);
715
+ * console.log(`bot username is @${info.username}`);
716
+ * }
717
+ * );
718
+ *
719
+ * bot.start();
720
+ * bot.stop();
721
+ * ```
722
+ *
723
+ * [Documentation](https://gramio.dev/hooks/on-stop.html)
724
+ * */
725
+ onStop(handler: Hooks.OnStop): this;
726
+ /**
727
+ * This hook called before sending a request to Telegram Bot API (allows us to impact the sent parameters).
728
+ *
729
+ * @example
730
+ * ```typescript
731
+ * import { Bot } from "gramio";
732
+ *
733
+ * const bot = new Bot(process.env.TOKEN!).preRequest((context) => {
734
+ * if (context.method === "sendMessage") {
735
+ * context.params.text = "mutate params";
736
+ * }
737
+ *
738
+ * return context;
739
+ * });
740
+ *
741
+ * bot.start();
742
+ * ```
743
+ *
744
+ * [Documentation](https://gramio.dev/hooks/pre-request.html)
745
+ * */
746
+ preRequest<Methods extends keyof APIMethods, Handler extends Hooks.PreRequest<Methods>>(methods: MaybeArray<Methods>, handler: Handler): this;
747
+ preRequest(handler: Hooks.PreRequest): this;
748
+ /**
749
+ * This hook called when API return successful response
750
+ *
751
+ * [Documentation](https://gramio.dev/hooks/on-response.html)
752
+ * */
753
+ onResponse<Methods extends keyof APIMethods, Handler extends Hooks.OnResponse<Methods>>(methods: MaybeArray<Methods>, handler: Handler): this;
754
+ onResponse(handler: Hooks.OnResponse): this;
755
+ /**
756
+ * This hook called when API return an error
757
+ *
758
+ * [Documentation](https://gramio.dev/hooks/on-response-error.html)
759
+ * */
760
+ onResponseError<Methods extends keyof APIMethods, Handler extends Hooks.OnResponseError<Methods>>(methods: MaybeArray<Methods>, handler: Handler): this;
761
+ onResponseError(handler: Hooks.OnResponseError): this;
762
+ /** Register handler to one or many Updates */
763
+ on<T extends UpdateName>(updateName: MaybeArray<T>, handler: Handler<ContextType<typeof this, T> & Derives["global"] & Derives[T]>): this;
764
+ /** Register handler to any Updates */
765
+ use(handler: Handler<Context<typeof this> & Derives["global"]>): this;
766
+ /**
767
+ * Extend {@link Plugin} logic and types
768
+ *
769
+ * @example
770
+ * ```ts
771
+ * import { Plugin, Bot } from "gramio";
772
+ *
773
+ * export class PluginError extends Error {
774
+ * wow: "type" | "safe" = "type";
775
+ * }
776
+ *
777
+ * const plugin = new Plugin("gramio-example")
778
+ * .error("PLUGIN", PluginError)
779
+ * .derive(() => {
780
+ * return {
781
+ * some: ["derived", "props"] as const,
782
+ * };
783
+ * });
784
+ *
785
+ * const bot = new Bot(process.env.TOKEN!)
786
+ * .extend(plugin)
787
+ * .onError(({ context, kind, error }) => {
788
+ * if (context.is("message") && kind === "PLUGIN") {
789
+ * console.log(error.wow);
790
+ * }
791
+ * })
792
+ * .use((context) => {
793
+ * console.log(context.some);
794
+ * });
795
+ * ```
796
+ */
797
+ extend<NewPlugin extends AnyPlugin>(plugin: MaybePromise<NewPlugin>): Bot<Errors & NewPlugin["_"]["Errors"], Derives & NewPlugin["_"]["Derives"]>;
798
+ /**
799
+ * Register handler to reaction (`message_reaction` update)
800
+ *
801
+ * @example
802
+ * ```ts
803
+ * new Bot().reaction("👍", async (context) => {
804
+ * await context.reply(`Thank you!`);
805
+ * });
806
+ * ```
807
+ * */
808
+ reaction(trigger: MaybeArray<TelegramReactionTypeEmojiEmoji>, handler: (context: ContextType<typeof this, "message_reaction"> & Derives["global"] & Derives["message_reaction"]) => unknown): this;
809
+ /**
810
+ * Register handler to `callback_query` event
811
+ *
812
+ * @example
813
+ * ```ts
814
+ * const someData = new CallbackData("example").number("id");
815
+ *
816
+ * new Bot()
817
+ * .command("start", (context) =>
818
+ * context.send("some", {
819
+ * reply_markup: new InlineKeyboard().text(
820
+ * "example",
821
+ * someData.pack({
822
+ * id: 1,
823
+ * })
824
+ * ),
825
+ * })
826
+ * )
827
+ * .callbackQuery(someData, (context) => {
828
+ * context.queryData; // is type-safe
829
+ * });
830
+ * ```
831
+ */
832
+ callbackQuery<Trigger extends CallbackData | string | RegExp>(trigger: Trigger, handler: (context: Omit<ContextType<typeof this, "callback_query">, "data"> & Derives["global"] & Derives["callback_query"] & {
833
+ queryData: Trigger extends CallbackData ? ReturnType<Trigger["unpack"]> : RegExpMatchArray | null;
834
+ }) => unknown): this;
835
+ /** Register handler to `chosen_inline_result` update */
836
+ chosenInlineResult<Ctx = ContextType<typeof this, "chosen_inline_result"> & Derives["global"] & Derives["chosen_inline_result"]>(trigger: RegExp | string | ((context: Ctx) => boolean), handler: (context: Ctx & {
837
+ args: RegExpMatchArray | null;
838
+ }) => unknown): this;
839
+ /**
840
+ * Register handler to `inline_query` update
841
+ *
842
+ * @example
843
+ * ```ts
844
+ * new Bot().inlineQuery(
845
+ * /regular expression with (.*)/i,
846
+ * async (context) => {
847
+ * if (context.args) {
848
+ * await context.answer(
849
+ * [
850
+ * InlineQueryResult.article(
851
+ * "id-1",
852
+ * context.args[1],
853
+ * InputMessageContent.text("some"),
854
+ * {
855
+ * reply_markup: new InlineKeyboard().text(
856
+ * "some",
857
+ * "callback-data"
858
+ * ),
859
+ * }
860
+ * ),
861
+ * ],
862
+ * {
863
+ * cache_time: 0,
864
+ * }
865
+ * );
866
+ * }
867
+ * },
868
+ * {
869
+ * onResult: (context) => context.editText("Message edited!"),
870
+ * }
871
+ * );
872
+ * ```
873
+ * */
874
+ inlineQuery<Ctx = ContextType<typeof this, "inline_query"> & Derives["global"] & Derives["inline_query"]>(trigger: RegExp | string | ((context: Ctx) => boolean), handler: (context: Ctx & {
875
+ args: RegExpMatchArray | null;
876
+ }) => unknown, options?: {
877
+ onResult?: (context: ContextType<Bot, "chosen_inline_result"> & Derives["global"] & Derives["chosen_inline_result"] & {
878
+ args: RegExpMatchArray | null;
879
+ }) => unknown;
880
+ }): this;
881
+ /**
882
+ * Register handler to `message` and `business_message` event
883
+ *
884
+ * new Bot().hears(/regular expression with (.*)/i, async (context) => {
885
+ * if (context.args) await context.send(`Params ${context.args[1]}`);
886
+ * });
887
+ */
888
+ hears<Ctx = ContextType<typeof this, "message"> & Derives["global"] & Derives["message"]>(trigger: RegExp | string | ((context: Ctx) => boolean), handler: (context: Ctx & {
889
+ args: RegExpMatchArray | null;
890
+ }) => unknown): this;
891
+ /**
892
+ * Register handler to `message` and `business_message` event when entities contains a command
893
+ *
894
+ * new Bot().command("start", async (context) => {
895
+ * return context.send(`You message is /start ${context.args}`);
896
+ * });
897
+ */
898
+ command(command: string, handler: (context: ContextType<typeof this, "message"> & Derives["global"] & Derives["message"] & {
899
+ args: string | null;
900
+ }) => unknown, options?: Omit<SetMyCommandsParams, "commands"> & Omit<TelegramBotCommand, "command">): this;
901
+ /** Currently not isolated!!! */
902
+ group(grouped: (bot: typeof this) => AnyBot): typeof this;
903
+ /**
904
+ * Init bot. Call it manually only if you doesn't use {@link Bot.start}
905
+ */
906
+ init(): Promise<void>;
907
+ /**
908
+ * Start receive updates via long-polling or webhook
909
+ *
910
+ * @example
911
+ * ```ts
912
+ * import { Bot } from "gramio";
913
+ *
914
+ * const bot = new Bot("") // put you token here
915
+ * .command("start", (context) => context.send("Hi!"))
916
+ * .onStart(console.log);
917
+ *
918
+ * bot.start();
919
+ * ```
920
+ */
921
+ start({ webhook, dropPendingUpdates, allowedUpdates, }?: {
922
+ webhook?: Omit<APIMethodParams<"setWebhook">, "drop_pending_updates" | "allowed_updates">;
923
+ dropPendingUpdates?: boolean;
924
+ allowedUpdates?: NonNullable<APIMethodParams<"getUpdates">>["allowed_updates"];
925
+ }): Promise<TelegramUser | undefined>;
926
+ /**
927
+ * Stops receiving events via long-polling or webhook
928
+ * Currently does not implement graceful shutdown
929
+ * */
930
+ stop(): Promise<void>;
931
+ }
932
+
933
+ declare const frameworks: {
934
+ elysia: ({ body, headers }: any) => {
935
+ update: any;
936
+ header: any;
937
+ unauthorized: () => Response;
938
+ };
939
+ fastify: (request: any, reply: any) => {
940
+ update: any;
941
+ header: any;
942
+ unauthorized: () => any;
943
+ };
944
+ hono: (c: any) => {
945
+ update: any;
946
+ header: any;
947
+ unauthorized: () => any;
948
+ };
949
+ express: (req: any, res: any) => {
950
+ update: any;
951
+ header: any;
952
+ unauthorized: () => any;
953
+ };
954
+ koa: (ctx: any) => {
955
+ update: any;
956
+ header: any;
957
+ unauthorized: () => void;
958
+ };
959
+ http: (req: any, res: any) => {
960
+ update: Promise<TelegramUpdate>;
961
+ header: any;
962
+ unauthorized: () => any;
963
+ };
964
+ "std/http": (req: any) => {
965
+ update: any;
966
+ header: any;
967
+ response: () => Response;
968
+ unauthorized: () => Response;
969
+ };
970
+ "Bun.serve": (req: any) => {
971
+ update: any;
972
+ header: any;
973
+ response: () => Response;
974
+ unauthorized: () => Response;
975
+ };
976
+ };
977
+
978
+ /** Union type of webhook handlers name */
979
+ type WebhookHandlers = keyof typeof frameworks;
980
+ /**
981
+ * Setup handler with yours web-framework to receive updates via webhook
982
+ *
983
+ * @example
984
+ * ```ts
985
+ * import { Bot } from "gramio";
986
+ * import Fastify from "fastify";
987
+ *
988
+ * const bot = new Bot(process.env.TOKEN as string).on(
989
+ * "message",
990
+ * (context) => {
991
+ * return context.send("Fastify!");
992
+ * },
993
+ * );
994
+ *
995
+ * const fastify = Fastify();
996
+ *
997
+ * fastify.post("/telegram-webhook", webhookHandler(bot, "fastify"));
998
+ *
999
+ * fastify.listen({ port: 3445, host: "::" });
1000
+ *
1001
+ * bot.start({
1002
+ * webhook: {
1003
+ * url: "https://example.com:3445/telegram-webhook",
1004
+ * },
1005
+ * });
1006
+ * ```
1007
+ */
1008
+ declare function webhookHandler<Framework extends keyof typeof frameworks>(bot: Bot, framework: Framework, secretToken?: string): ReturnType<(typeof frameworks)[Framework]> extends {
1009
+ response: () => any;
1010
+ } ? (...args: Parameters<(typeof frameworks)[Framework]>) => ReturnType<ReturnType<(typeof frameworks)[Framework]>["response"]> : (...args: Parameters<(typeof frameworks)[Framework]>) => void;
1011
+
1012
+ export { type AnyBot, type AnyPlugin, Bot, type BotOptions, type DeriveDefinitions, type ErrorDefinitions, ErrorKind, type FilterDefinitions, type Handler, Hooks, type MaybePromise, type MaybeSuppressedParams, Plugin, type Suppress, type SuppressedAPIMethodParams, type SuppressedAPIMethodReturn, type SuppressedAPIMethods, TelegramError, type WebhookHandlers, webhookHandler };