gramio 0.9.0 → 0.11.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/dist/index.cjs CHANGED
@@ -5,8 +5,6 @@ var contexts = require('@gramio/contexts');
5
5
  var files = require('@gramio/files');
6
6
  var format = require('@gramio/format');
7
7
  var keyboards = require('@gramio/keyboards');
8
- var fs = require('node:fs/promises');
9
- var node_stream = require('node:stream');
10
8
  var debug = require('debug');
11
9
  var utils = require('./utils-BKLnNOBm.cjs');
12
10
  var composer = require('@gramio/composer');
@@ -35,7 +33,8 @@ const ALL_NAMES = [
35
33
  "chat_join_request",
36
34
  "chat_boost",
37
35
  "removed_chat_boost",
38
- "managed_bot"
36
+ "managed_bot",
37
+ "guest_message"
39
38
  ];
40
39
  const MESSAGE_PARENT_TYPES = [
41
40
  "message",
@@ -198,13 +197,23 @@ const methods = composer.defineComposerMethods({
198
197
  return macroHandler ? macroHandler(context, composer.noopNext) : handler(context);
199
198
  });
200
199
  }
200
+ if (typeof trigger === "function") {
201
+ return this.on("chosen_inline_result", (context, next) => {
202
+ if (!trigger(context)) return next();
203
+ context.args = null;
204
+ return macroHandler ? macroHandler(context, composer.noopNext) : handler(context);
205
+ });
206
+ }
201
207
  return this.on("chosen_inline_result", (context, next) => {
202
- if (!trigger(context)) return next();
208
+ if (!context.resultId || !trigger.filter(context.resultId)) return next();
203
209
  context.args = null;
210
+ context.queryData = trigger.unpack(context.resultId);
204
211
  return macroHandler ? macroHandler(context, composer.noopNext) : handler(context);
205
212
  });
206
213
  },
207
- inlineQuery(trigger, handler, options = {}) {
214
+ inlineQuery(triggerOrHandler, maybeHandler, options = {}) {
215
+ const trigger = maybeHandler === void 0 ? (() => true) : triggerOrHandler;
216
+ const handler = maybeHandler ?? triggerOrHandler;
208
217
  if (options.onResult) this.chosenInlineResult(trigger, options.onResult);
209
218
  const { onResult: _, ...macroOptions } = options;
210
219
  const hasMacros = Object.keys(macroOptions).length > 0;
@@ -229,6 +238,32 @@ const methods = composer.defineComposerMethods({
229
238
  return macroHandler ? macroHandler(context, composer.noopNext) : handler(context);
230
239
  });
231
240
  },
241
+ guestQuery(triggerOrHandler, maybeHandler, macroOptions) {
242
+ const trigger = maybeHandler === void 0 ? (() => true) : triggerOrHandler;
243
+ const handler = maybeHandler ?? triggerOrHandler;
244
+ const macroHandler = macroOptions ? composer.buildFromOptions(this["~"].macros, macroOptions, handler) : null;
245
+ if (typeof trigger === "string") {
246
+ return this.on("guest_message", (context, next) => {
247
+ const text = context.text ?? context.caption;
248
+ if (text !== trigger) return next();
249
+ context.args = null;
250
+ return macroHandler ? macroHandler(context, composer.noopNext) : handler(context);
251
+ });
252
+ }
253
+ if (trigger instanceof RegExp) {
254
+ return this.on("guest_message", (context, next) => {
255
+ const text = context.text ?? context.caption;
256
+ if (!text || !trigger.test(text)) return next();
257
+ context.args = text.match(trigger);
258
+ return macroHandler ? macroHandler(context, composer.noopNext) : handler(context);
259
+ });
260
+ }
261
+ return this.on("guest_message", (context, next) => {
262
+ if (!trigger(context)) return next();
263
+ context.args = null;
264
+ return macroHandler ? macroHandler(context, composer.noopNext) : handler(context);
265
+ });
266
+ },
232
267
  hears(trigger, handler, macroOptions) {
233
268
  const macroHandler = macroOptions ? composer.buildFromOptions(this["~"].macros, macroOptions, handler) : null;
234
269
  if (typeof trigger === "string") {
@@ -690,6 +725,7 @@ class Updates {
690
725
  })
691
726
  );
692
727
  this.isRequestActive = false;
728
+ if (!this.isStarted) break;
693
729
  const updateId = updates.at(-1)?.update_id;
694
730
  this.offset = updateId ? updateId + 1 : this.offset;
695
731
  this.queue.addBatch(updates);
@@ -909,28 +945,26 @@ class Bot {
909
945
  }
910
946
  return fn();
911
947
  }
912
- async downloadFile(attachment, path) {
913
- function getFileId(attachment2) {
914
- if (attachment2 instanceof contexts.PhotoAttachment) {
915
- return attachment2.bigSize.fileId;
916
- }
917
- if ("fileId" in attachment2 && typeof attachment2.fileId === "string")
918
- return attachment2.fileId;
919
- if ("file_id" in attachment2) return attachment2.file_id;
920
- throw new Error("Invalid attachment");
921
- }
922
- const fileId = typeof attachment === "string" ? attachment : getFileId(attachment);
923
- const file = await this.api.getFile({ file_id: fileId });
924
- const url = `${this.options.api.baseURL.replace("/bot", "/file/bot")}${this.options.token}/${file.file_path}`;
925
- const res = await fetch(url);
926
- if (path) {
927
- if (!res.body)
928
- throw new Error("Response without body (should be never throw)");
929
- await fs.writeFile(path, node_stream.Readable.fromWeb(res.body));
930
- return path;
931
- }
932
- const buffer = await res.arrayBuffer();
933
- return buffer;
948
+ downloadFile(attachment, path) {
949
+ const input = attachment;
950
+ return path ? files.downloadFile(this, input, path) : files.downloadFile(this, input);
951
+ }
952
+ /**
953
+ * Get a shareable download link for a file.
954
+ *
955
+ * When {@link BotOptions.files | `files.baseURL`} is set (e.g. a local Bot API
956
+ * server with the bundled file server), the link is **token-less and path-based**
957
+ * — safe to hand to users. Otherwise it falls back to the classic
958
+ * `…/file/bot<token>/<path>` URL (which contains the bot token).
959
+ *
960
+ * @example
961
+ * ```ts
962
+ * const link = await bot.getFileLink(ctx.document.fileId);
963
+ * await ctx.reply(`Download: ${link}`);
964
+ * ```
965
+ */
966
+ getFileLink(attachment) {
967
+ return files.downloadFile(this, attachment).link();
934
968
  }
935
969
  /**
936
970
  * Register custom class-error for type-safe catch in `onError` hook
@@ -1274,7 +1308,32 @@ class Bot {
1274
1308
  );
1275
1309
  return this;
1276
1310
  }
1277
- /** Register handler to `chosen_inline_result` update */
1311
+ /**
1312
+ * Register handler to `chosen_inline_result` update
1313
+ *
1314
+ * Accepts a `CallbackData` schema for type-safe filtering on `result_id`:
1315
+ *
1316
+ * @example
1317
+ * ```ts
1318
+ * const trackRef = new CallbackData("track").string("src").string("id");
1319
+ *
1320
+ * new Bot()
1321
+ * .on("inline_query", async (ctx) => {
1322
+ * await ctx.answer(tracks.map((t) => ({
1323
+ * type: "audio",
1324
+ * id: trackRef.pack({ src: t.source, id: t.id }),
1325
+ * audio_url: t.url,
1326
+ * title: t.title,
1327
+ * })));
1328
+ * })
1329
+ * .chosenInlineResult(trackRef, (ctx) => {
1330
+ * ctx.queryData; // { src: string; id: string }
1331
+ * });
1332
+ * ```
1333
+ *
1334
+ * String/RegExp/predicate triggers filter on `context.query` (the user's
1335
+ * typed text); the `CallbackData` schema filters on `context.resultId`.
1336
+ */
1278
1337
  chosenInlineResult(trigger, handler, options) {
1279
1338
  this.updates.composer.chosenInlineResult(
1280
1339
  trigger,
@@ -1283,49 +1342,18 @@ class Bot {
1283
1342
  );
1284
1343
  return this;
1285
1344
  }
1286
- /**
1287
- * Register handler to `inline_query` update
1288
- *
1289
- * @example
1290
- * ```ts
1291
- * new Bot().inlineQuery(
1292
- * /regular expression with (.*)/i,
1293
- * async (context) => {
1294
- * if (context.args) {
1295
- * await context.answer(
1296
- * [
1297
- * InlineQueryResult.article(
1298
- * "id-1",
1299
- * context.args[1],
1300
- * InputMessageContent.text("some"),
1301
- * {
1302
- * reply_markup: new InlineKeyboard().text(
1303
- * "some",
1304
- * "callback-data"
1305
- * ),
1306
- * }
1307
- * ),
1308
- * ],
1309
- * {
1310
- * cache_time: 0,
1311
- * }
1312
- * );
1313
- * }
1314
- * },
1315
- * {
1316
- * onResult: (context) => context.editText("Message edited!"),
1317
- * }
1318
- * );
1319
- * ```
1320
- * */
1321
- inlineQuery(trigger, handler, options) {
1345
+ inlineQuery(triggerOrHandler, handler, options) {
1322
1346
  this.updates.composer.inlineQuery(
1323
- trigger,
1347
+ triggerOrHandler,
1324
1348
  handler,
1325
1349
  options
1326
1350
  );
1327
1351
  return this;
1328
1352
  }
1353
+ guestQuery(triggerOrHandler, handler, options) {
1354
+ this.updates.composer.guestQuery(triggerOrHandler, handler, options);
1355
+ return this;
1356
+ }
1329
1357
  /**
1330
1358
  * Register handler to `message` and `business_message` event
1331
1359
  *
package/dist/index.d.cts CHANGED
@@ -4,6 +4,7 @@ export * from '@gramio/callback-data';
4
4
  import * as _gramio_contexts from '@gramio/contexts';
5
5
  import { UpdateName, MessageEventName, CustomEventName, Context, ContextsMapping, BotLike, ContextType, Attachment, AttachmentsMapping, Dice, MessageOriginUser, MessageOriginChat, MessageOriginChannel, MessageOriginHiddenUser, Message, MessageEntity, TextQuote, User, LinkPreviewOptions, ExternalReplyInfo, Chat, Giveaway, PaidMediaInfo, Game, StoryAttachment, Venue, MessageContext } from '@gramio/contexts';
6
6
  export * from '@gramio/contexts';
7
+ import { FileSource, TelegramFileDownload } from '@gramio/files';
7
8
  export * from '@gramio/files';
8
9
  export * from '@gramio/format';
9
10
  export * from '@gramio/keyboards';
@@ -12,7 +13,7 @@ import { APIMethods, TelegramResponseParameters, TelegramAPIResponseError, Teleg
12
13
  export * from '@gramio/types';
13
14
  import * as _gramio_composer from '@gramio/composer';
14
15
  import { ComposerLike, MacroDefinitions, EventContextOf, EventComposer, MacroDef, Next, EventQueue, HandlerOptions, DeriveFromOptions } from '@gramio/composer';
15
- export { ContextCallback, DeriveFromOptions, EventComposer, EventQueue, HandlerOptions, MacroDef, MacroDefinitions, MacroDeriveType, MacroHooks, MacroOptionType, Middleware, Next, WithCtx, buildFromOptions, compose, noopNext, skip, stop } from '@gramio/composer';
16
+ export { ContextCallback, DeriveFromOptions, DeriveHandler, EventComposer, EventQueue, HandlerOptions, MacroDef, MacroDefinitions, MacroDeriveType, MacroHooks, MacroOptionType, Middleware, Next, WithCtx, WithDecorate, WithDerives, WithEventDerive, WithExtend, buildFromOptions, compose, noopNext, skip, stop } from '@gramio/composer';
16
17
 
17
18
  /**
18
19
  * Telegram Bot API top-level update type name.
@@ -184,16 +185,24 @@ declare const methods: {
184
185
  callbackQuery<TThis extends GramIOLike<TThis>, Trigger extends CallbackData | string | RegExp>(this: TThis, trigger: Trigger, handler: (context: Ctx<"callback_query"> & {
185
186
  queryData: Trigger extends CallbackData ? ReturnType<Trigger["unpack"]> : Trigger extends RegExp ? RegExpMatchArray : never;
186
187
  } & EventContextOf<TThis, "callback_query">) => unknown, macroOptions?: Record<string, unknown>): TThis;
187
- chosenInlineResult<TThis extends GramIOLike<TThis>>(this: TThis, trigger: RegExp | string | ((context: Ctx<"chosen_inline_result">) => boolean), handler: (context: Ctx<"chosen_inline_result"> & {
188
+ chosenInlineResult<TThis extends GramIOLike<TThis>, Trigger extends CallbackData | RegExp | string | ((context: Ctx<"chosen_inline_result">) => boolean)>(this: TThis, trigger: Trigger, handler: (context: Ctx<"chosen_inline_result"> & {
188
189
  args: RegExpMatchArray | null;
190
+ queryData: Trigger extends CallbackData ? ReturnType<Trigger["unpack"]> : never;
189
191
  } & EventContextOf<TThis, "chosen_inline_result">) => unknown, macroOptions?: Record<string, unknown>): TThis;
190
- inlineQuery<TThis extends GramIOLike<TThis>>(this: TThis, trigger: RegExp | string | ((context: Ctx<"inline_query">) => boolean), handler: (context: Ctx<"inline_query"> & {
192
+ inlineQuery<TThis extends GramIOLike<TThis>>(this: TThis, triggerOrHandler: RegExp | string | ((context: Ctx<"inline_query">) => boolean) | ((context: Ctx<"inline_query"> & {
193
+ args: RegExpMatchArray | null;
194
+ } & EventContextOf<TThis, "inline_query">) => unknown), maybeHandler?: (context: Ctx<"inline_query"> & {
191
195
  args: RegExpMatchArray | null;
192
196
  } & EventContextOf<TThis, "inline_query">) => unknown, options?: {
193
197
  onResult?: (context: Ctx<"chosen_inline_result"> & {
194
198
  args: RegExpMatchArray | null;
195
199
  } & EventContextOf<TThis, "chosen_inline_result">) => unknown;
196
200
  } & Record<string, unknown>): TThis;
201
+ guestQuery<TThis extends GramIOLike<TThis>>(this: TThis, triggerOrHandler: RegExp | string | ((context: Ctx<"guest_message">) => boolean) | ((context: Ctx<"guest_message"> & {
202
+ args: RegExpMatchArray | null;
203
+ } & EventContextOf<TThis, "guest_message">) => unknown), maybeHandler?: (context: Ctx<"guest_message"> & {
204
+ args: RegExpMatchArray | null;
205
+ } & EventContextOf<TThis, "guest_message">) => unknown, macroOptions?: Record<string, unknown>): TThis;
197
206
  hears<TThis extends GramIOLike<TThis>>(this: TThis, trigger: RegExp | MaybeArray<string> | ((context: Ctx<"message">) => boolean), handler: (context: Ctx<"message"> & {
198
207
  args: RegExpMatchArray | null;
199
208
  } & EventContextOf<TThis, "message">) => unknown, macroOptions?: Record<string, unknown>): TThis;
@@ -216,6 +225,7 @@ declare module "@gramio/composer" {
216
225
  hears: (typeof methods)["hears"];
217
226
  reaction: (typeof methods)["reaction"];
218
227
  inlineQuery: (typeof methods)["inlineQuery"];
228
+ guestQuery: (typeof methods)["guestQuery"];
219
229
  chosenInlineResult: (typeof methods)["chosenInlineResult"];
220
230
  startParameter: (typeof methods)["startParameter"];
221
231
  }
@@ -225,16 +235,24 @@ declare const Composer: _gramio_composer.EventComposerConstructor<Context<AnyBot
225
235
  callbackQuery<TThis extends GramIOLike<TThis>, Trigger extends CallbackData | string | RegExp>(this: TThis, trigger: Trigger, handler: (context: Ctx<"callback_query"> & {
226
236
  queryData: Trigger extends CallbackData ? ReturnType<Trigger["unpack"]> : Trigger extends RegExp ? RegExpMatchArray : never;
227
237
  } & EventContextOf<TThis, "callback_query">) => unknown, macroOptions?: Record<string, unknown>): TThis;
228
- chosenInlineResult<TThis extends GramIOLike<TThis>>(this: TThis, trigger: RegExp | string | ((context: Ctx<"chosen_inline_result">) => boolean), handler: (context: Ctx<"chosen_inline_result"> & {
238
+ chosenInlineResult<TThis extends GramIOLike<TThis>, Trigger extends CallbackData | RegExp | string | ((context: Ctx<"chosen_inline_result">) => boolean)>(this: TThis, trigger: Trigger, handler: (context: Ctx<"chosen_inline_result"> & {
229
239
  args: RegExpMatchArray | null;
240
+ queryData: Trigger extends CallbackData ? ReturnType<Trigger["unpack"]> : never;
230
241
  } & EventContextOf<TThis, "chosen_inline_result">) => unknown, macroOptions?: Record<string, unknown>): TThis;
231
- inlineQuery<TThis extends GramIOLike<TThis>>(this: TThis, trigger: RegExp | string | ((context: Ctx<"inline_query">) => boolean), handler: (context: Ctx<"inline_query"> & {
242
+ inlineQuery<TThis extends GramIOLike<TThis>>(this: TThis, triggerOrHandler: RegExp | string | ((context: Ctx<"inline_query">) => boolean) | ((context: Ctx<"inline_query"> & {
243
+ args: RegExpMatchArray | null;
244
+ } & EventContextOf<TThis, "inline_query">) => unknown), maybeHandler?: (context: Ctx<"inline_query"> & {
232
245
  args: RegExpMatchArray | null;
233
246
  } & EventContextOf<TThis, "inline_query">) => unknown, options?: {
234
247
  onResult?: (context: Ctx<"chosen_inline_result"> & {
235
248
  args: RegExpMatchArray | null;
236
249
  } & EventContextOf<TThis, "chosen_inline_result">) => unknown;
237
250
  } & Record<string, unknown>): TThis;
251
+ guestQuery<TThis extends GramIOLike<TThis>>(this: TThis, triggerOrHandler: RegExp | string | ((context: Ctx<"guest_message">) => boolean) | ((context: Ctx<"guest_message"> & {
252
+ args: RegExpMatchArray | null;
253
+ } & EventContextOf<TThis, "guest_message">) => unknown), maybeHandler?: (context: Ctx<"guest_message"> & {
254
+ args: RegExpMatchArray | null;
255
+ } & EventContextOf<TThis, "guest_message">) => unknown, macroOptions?: Record<string, unknown>): TThis;
238
256
  hears<TThis extends GramIOLike<TThis>>(this: TThis, trigger: RegExp | MaybeArray<string> | ((context: Ctx<"message">) => boolean), handler: (context: Ctx<"message"> & {
239
257
  args: RegExpMatchArray | null;
240
258
  } & EventContextOf<TThis, "message">) => unknown, macroOptions?: Record<string, unknown>): TThis;
@@ -325,6 +343,7 @@ declare class Plugin<Errors extends ErrorDefinitions = {}, Derives extends Deriv
325
343
  edited_channel_post: _gramio_contexts.MessageContext<AnyBot> & _gramio_contexts.Require<_gramio_contexts.MessageContext<AnyBot>, "from">;
326
344
  business_message: _gramio_contexts.MessageContext<AnyBot> & _gramio_contexts.Require<_gramio_contexts.MessageContext<AnyBot>, "from">;
327
345
  edited_business_message: _gramio_contexts.MessageContext<AnyBot> & _gramio_contexts.Require<_gramio_contexts.MessageContext<AnyBot>, "from">;
346
+ guest_message: _gramio_contexts.MessageContext<AnyBot> & _gramio_contexts.Require<_gramio_contexts.MessageContext<AnyBot>, "from">;
328
347
  deleted_business_messages: _gramio_contexts.BusinessMessagesDeletedContext<AnyBot>;
329
348
  business_connection: _gramio_contexts.BusinessConnectionContext<AnyBot>;
330
349
  migrate_from_chat_id: _gramio_contexts.MigrateFromChatIdContext<AnyBot>;
@@ -408,8 +427,9 @@ declare class Plugin<Errors extends ErrorDefinitions = {}, Derives extends Deriv
408
427
  Derives?: Record<string, object>;
409
428
  };
410
429
  chosenInlineResult(trigger: any, handler: any, macroOptions?: any): TThis;
411
- }>(this: TThis, trigger: RegExp | string | ((context: _gramio_contexts.ChosenInlineResultContext<AnyBot>) => boolean), handler: (context: _gramio_contexts.ChosenInlineResultContext<AnyBot> & {
430
+ }, Trigger extends _gramio_callback_data.CallbackData | RegExp | string | ((context: _gramio_contexts.ChosenInlineResultContext<AnyBot>) => boolean)>(this: TThis, trigger: Trigger, handler: (context: _gramio_contexts.ChosenInlineResultContext<AnyBot> & {
412
431
  args: RegExpMatchArray | null;
432
+ queryData: Trigger extends _gramio_callback_data.CallbackData ? ReturnType<Trigger["unpack"]> : never;
413
433
  } & _gramio_composer.EventContextOf<TThis, "chosen_inline_result">) => unknown, macroOptions?: Record<string, unknown>): TThis;
414
434
  inlineQuery<TThis extends _gramio_composer.ComposerLike<TThis> & {
415
435
  "~": {
@@ -418,13 +438,27 @@ declare class Plugin<Errors extends ErrorDefinitions = {}, Derives extends Deriv
418
438
  Derives?: Record<string, object>;
419
439
  };
420
440
  chosenInlineResult(trigger: any, handler: any, macroOptions?: any): TThis;
421
- }>(this: TThis, trigger: RegExp | string | ((context: _gramio_contexts.InlineQueryContext<AnyBot>) => boolean), handler: (context: _gramio_contexts.InlineQueryContext<AnyBot> & {
441
+ }>(this: TThis, triggerOrHandler: RegExp | string | ((context: _gramio_contexts.InlineQueryContext<AnyBot>) => boolean) | ((context: _gramio_contexts.InlineQueryContext<AnyBot> & {
442
+ args: RegExpMatchArray | null;
443
+ } & _gramio_composer.EventContextOf<TThis, "inline_query">) => unknown), maybeHandler?: (context: _gramio_contexts.InlineQueryContext<AnyBot> & {
422
444
  args: RegExpMatchArray | null;
423
445
  } & _gramio_composer.EventContextOf<TThis, "inline_query">) => unknown, options?: {
424
446
  onResult?: (context: _gramio_contexts.ChosenInlineResultContext<AnyBot> & {
425
447
  args: RegExpMatchArray | null;
426
448
  } & _gramio_composer.EventContextOf<TThis, "chosen_inline_result">) => unknown;
427
449
  } & Record<string, unknown>): TThis;
450
+ guestQuery<TThis extends _gramio_composer.ComposerLike<TThis> & {
451
+ "~": {
452
+ macros: MacroDefinitions;
453
+ commandsMeta?: Map<string, unknown>;
454
+ Derives?: Record<string, object>;
455
+ };
456
+ chosenInlineResult(trigger: any, handler: any, macroOptions?: any): TThis;
457
+ }>(this: TThis, triggerOrHandler: RegExp | string | ((context: _gramio_contexts.MessageContext<AnyBot> & _gramio_contexts.Require<_gramio_contexts.MessageContext<AnyBot>, "from">) => boolean) | ((context: (_gramio_contexts.MessageContext<AnyBot> & _gramio_contexts.Require<_gramio_contexts.MessageContext<AnyBot>, "from">) & {
458
+ args: RegExpMatchArray | null;
459
+ } & _gramio_composer.EventContextOf<TThis, "guest_message">) => unknown), maybeHandler?: (context: (_gramio_contexts.MessageContext<AnyBot> & _gramio_contexts.Require<_gramio_contexts.MessageContext<AnyBot>, "from">) & {
460
+ args: RegExpMatchArray | null;
461
+ } & _gramio_composer.EventContextOf<TThis, "guest_message">) => unknown, macroOptions?: Record<string, unknown>): TThis;
428
462
  hears<TThis extends _gramio_composer.ComposerLike<TThis> & {
429
463
  "~": {
430
464
  macros: MacroDefinitions;
@@ -483,8 +517,9 @@ declare class Plugin<Errors extends ErrorDefinitions = {}, Derives extends Deriv
483
517
  Derives?: Record<string, object>;
484
518
  };
485
519
  chosenInlineResult(trigger: any, handler: any, macroOptions?: any): TThis;
486
- }>(this: TThis, trigger: RegExp | string | ((context: _gramio_contexts.ChosenInlineResultContext<AnyBot>) => boolean), handler: (context: _gramio_contexts.ChosenInlineResultContext<AnyBot> & {
520
+ }, Trigger extends _gramio_callback_data.CallbackData | RegExp | string | ((context: _gramio_contexts.ChosenInlineResultContext<AnyBot>) => boolean)>(this: TThis, trigger: Trigger, handler: (context: _gramio_contexts.ChosenInlineResultContext<AnyBot> & {
487
521
  args: RegExpMatchArray | null;
522
+ queryData: Trigger extends _gramio_callback_data.CallbackData ? ReturnType<Trigger["unpack"]> : never;
488
523
  } & _gramio_composer.EventContextOf<TThis, "chosen_inline_result">) => unknown, macroOptions?: Record<string, unknown>): TThis;
489
524
  inlineQuery<TThis extends _gramio_composer.ComposerLike<TThis> & {
490
525
  "~": {
@@ -493,13 +528,27 @@ declare class Plugin<Errors extends ErrorDefinitions = {}, Derives extends Deriv
493
528
  Derives?: Record<string, object>;
494
529
  };
495
530
  chosenInlineResult(trigger: any, handler: any, macroOptions?: any): TThis;
496
- }>(this: TThis, trigger: RegExp | string | ((context: _gramio_contexts.InlineQueryContext<AnyBot>) => boolean), handler: (context: _gramio_contexts.InlineQueryContext<AnyBot> & {
531
+ }>(this: TThis, triggerOrHandler: RegExp | string | ((context: _gramio_contexts.InlineQueryContext<AnyBot>) => boolean) | ((context: _gramio_contexts.InlineQueryContext<AnyBot> & {
532
+ args: RegExpMatchArray | null;
533
+ } & _gramio_composer.EventContextOf<TThis, "inline_query">) => unknown), maybeHandler?: (context: _gramio_contexts.InlineQueryContext<AnyBot> & {
497
534
  args: RegExpMatchArray | null;
498
535
  } & _gramio_composer.EventContextOf<TThis, "inline_query">) => unknown, options?: {
499
536
  onResult?: (context: _gramio_contexts.ChosenInlineResultContext<AnyBot> & {
500
537
  args: RegExpMatchArray | null;
501
538
  } & _gramio_composer.EventContextOf<TThis, "chosen_inline_result">) => unknown;
502
539
  } & Record<string, unknown>): TThis;
540
+ guestQuery<TThis extends _gramio_composer.ComposerLike<TThis> & {
541
+ "~": {
542
+ macros: MacroDefinitions;
543
+ commandsMeta?: Map<string, unknown>;
544
+ Derives?: Record<string, object>;
545
+ };
546
+ chosenInlineResult(trigger: any, handler: any, macroOptions?: any): TThis;
547
+ }>(this: TThis, triggerOrHandler: RegExp | string | ((context: _gramio_contexts.MessageContext<AnyBot> & _gramio_contexts.Require<_gramio_contexts.MessageContext<AnyBot>, "from">) => boolean) | ((context: (_gramio_contexts.MessageContext<AnyBot> & _gramio_contexts.Require<_gramio_contexts.MessageContext<AnyBot>, "from">) & {
548
+ args: RegExpMatchArray | null;
549
+ } & _gramio_composer.EventContextOf<TThis, "guest_message">) => unknown), maybeHandler?: (context: (_gramio_contexts.MessageContext<AnyBot> & _gramio_contexts.Require<_gramio_contexts.MessageContext<AnyBot>, "from">) & {
550
+ args: RegExpMatchArray | null;
551
+ } & _gramio_composer.EventContextOf<TThis, "guest_message">) => unknown, macroOptions?: Record<string, unknown>): TThis;
503
552
  hears<TThis extends _gramio_composer.ComposerLike<TThis> & {
504
553
  "~": {
505
554
  macros: MacroDefinitions;
@@ -750,6 +799,8 @@ interface Plugin<Errors, Derives, Macros> {
750
799
  reaction: (typeof methods)["reaction"];
751
800
  /** Register inline query handler */
752
801
  inlineQuery: (typeof methods)["inlineQuery"];
802
+ /** Register guest query (`guest_message`) handler */
803
+ guestQuery: (typeof methods)["guestQuery"];
753
804
  /** Register chosen inline result handler */
754
805
  chosenInlineResult: (typeof methods)["chosenInlineResult"];
755
806
  /** Register deep-link parameter handler */
@@ -794,6 +845,30 @@ interface BotOptions {
794
845
  */
795
846
  retryGetUpdatesWait?: number;
796
847
  };
848
+ /**
849
+ * File download/serving options — mainly for a **local Bot API server**.
850
+ *
851
+ * @example
852
+ * ```ts
853
+ * const bot = new Bot(token, {
854
+ * api: { baseURL: "http://telegram-bot-api:8081/bot" },
855
+ * files: {
856
+ * // bot.getFileLink() and ctx.download() resolve to this (token-less) URL
857
+ * baseURL: "http://telegram-bot-api:8080",
858
+ * },
859
+ * });
860
+ * ```
861
+ */
862
+ files?: {
863
+ /** How to fetch file bytes. @default "auto" */
864
+ source?: FileSource;
865
+ /** Working directory of the local Bot API server — the prefix of the absolute `file_path` it returns. @default "/var/lib/telegram-bot-api" */
866
+ localDir?: string;
867
+ /** Where that working dir is mounted on the bot's side (for `source: "disk"` when bot & server share a volume at a different path). Defaults to `localDir`. */
868
+ mountDir?: string;
869
+ /** Public base URL where the working dir is served (e.g. the bundled file server / nginx). Enables token-less {@link Bot.getFileLink} and `source: "rewrite"`. */
870
+ baseURL?: string;
871
+ };
797
872
  }
798
873
  /**
799
874
  * Handler is a function with context and next function arguments
@@ -1202,10 +1277,27 @@ declare class Bot<Errors extends ErrorDefinitions = {}, Derives extends DeriveDe
1202
1277
  */
1203
1278
  downloadFile(attachment: Attachment | {
1204
1279
  file_id: string;
1205
- } | string): Promise<ArrayBuffer>;
1280
+ } | string): TelegramFileDownload;
1206
1281
  downloadFile(attachment: Attachment | {
1207
1282
  file_id: string;
1208
1283
  } | string, path: string): Promise<string>;
1284
+ /**
1285
+ * Get a shareable download link for a file.
1286
+ *
1287
+ * When {@link BotOptions.files | `files.baseURL`} is set (e.g. a local Bot API
1288
+ * server with the bundled file server), the link is **token-less and path-based**
1289
+ * — safe to hand to users. Otherwise it falls back to the classic
1290
+ * `…/file/bot<token>/<path>` URL (which contains the bot token).
1291
+ *
1292
+ * @example
1293
+ * ```ts
1294
+ * const link = await bot.getFileLink(ctx.document.fileId);
1295
+ * await ctx.reply(`Download: ${link}`);
1296
+ * ```
1297
+ */
1298
+ getFileLink(attachment: Attachment | {
1299
+ file_id: string;
1300
+ } | string): Promise<string>;
1209
1301
  /**
1210
1302
  * Register custom class-error for type-safe catch in `onError` hook
1211
1303
  *
@@ -1478,9 +1570,35 @@ declare class Bot<Errors extends ErrorDefinitions = {}, Derives extends DeriveDe
1478
1570
  * ```
1479
1571
  */
1480
1572
  callbackQuery<Trigger extends CallbackData | string | RegExp, TOptions extends HandlerOptions<CallbackQueryShorthandContext<typeof this, Trigger>, Macros> = {}>(trigger: Trigger, handler: (context: CallbackQueryShorthandContext<typeof this, Trigger> & DeriveFromOptions<Macros, TOptions>) => unknown, options?: TOptions): this;
1481
- /** Register handler to `chosen_inline_result` update */
1482
- chosenInlineResult<Ctx = ContextType<typeof this, "chosen_inline_result">, TOptions extends HandlerOptions<Ctx, Macros> = {}>(trigger: RegExp | string | ((context: Ctx) => boolean), handler: (context: Ctx & {
1573
+ /**
1574
+ * Register handler to `chosen_inline_result` update
1575
+ *
1576
+ * Accepts a `CallbackData` schema for type-safe filtering on `result_id`:
1577
+ *
1578
+ * @example
1579
+ * ```ts
1580
+ * const trackRef = new CallbackData("track").string("src").string("id");
1581
+ *
1582
+ * new Bot()
1583
+ * .on("inline_query", async (ctx) => {
1584
+ * await ctx.answer(tracks.map((t) => ({
1585
+ * type: "audio",
1586
+ * id: trackRef.pack({ src: t.source, id: t.id }),
1587
+ * audio_url: t.url,
1588
+ * title: t.title,
1589
+ * })));
1590
+ * })
1591
+ * .chosenInlineResult(trackRef, (ctx) => {
1592
+ * ctx.queryData; // { src: string; id: string }
1593
+ * });
1594
+ * ```
1595
+ *
1596
+ * String/RegExp/predicate triggers filter on `context.query` (the user's
1597
+ * typed text); the `CallbackData` schema filters on `context.resultId`.
1598
+ */
1599
+ chosenInlineResult<Trigger extends CallbackData | RegExp | string | ((context: ContextType<typeof this, "chosen_inline_result">) => boolean), Ctx = ContextType<typeof this, "chosen_inline_result">, TOptions extends HandlerOptions<Ctx, Macros> = {}>(trigger: Trigger, handler: (context: Ctx & {
1483
1600
  args: RegExpMatchArray | null;
1601
+ queryData: Trigger extends CallbackData ? ReturnType<Trigger["unpack"]> : never;
1484
1602
  } & DeriveFromOptions<Macros, TOptions>) => unknown, options?: TOptions): this;
1485
1603
  /**
1486
1604
  * Register handler to `inline_query` update
@@ -1517,6 +1635,9 @@ declare class Bot<Errors extends ErrorDefinitions = {}, Derives extends DeriveDe
1517
1635
  * );
1518
1636
  * ```
1519
1637
  * */
1638
+ inlineQuery<Ctx = ContextType<typeof this, "inline_query">>(handler: (context: Ctx & {
1639
+ args: RegExpMatchArray | null;
1640
+ }) => unknown): this;
1520
1641
  inlineQuery<Ctx = ContextType<typeof this, "inline_query">>(trigger: RegExp | string | ((context: Ctx) => boolean), handler: (context: Ctx & {
1521
1642
  args: RegExpMatchArray | null;
1522
1643
  }) => unknown, options?: HandlerOptions<Ctx, Macros> & {
@@ -1524,6 +1645,34 @@ declare class Bot<Errors extends ErrorDefinitions = {}, Derives extends DeriveDe
1524
1645
  args: RegExpMatchArray | null;
1525
1646
  }) => unknown;
1526
1647
  }): this;
1648
+ /**
1649
+ * Register handler to `guest_message` update — a message sent to the bot
1650
+ * from a chat where the bot is not a member, via a guest query.
1651
+ *
1652
+ * Reply with {@link MessageContext.answerGuestQuery `context.answerGuestQuery()`}
1653
+ * (NOT `context.send`/`context.reply`, which target a chat the bot can't post to).
1654
+ *
1655
+ * @example
1656
+ * ```ts
1657
+ * new Bot().guestQuery(/^find (.*)/i, async (context) => {
1658
+ * await context.answerGuestQuery({
1659
+ * type: "text",
1660
+ * text: `Looking up ${context.args?.[1]}…`,
1661
+ * });
1662
+ * });
1663
+ *
1664
+ * // No-trigger form — match any guest message:
1665
+ * new Bot().guestQuery(async (context) => {
1666
+ * await context.answerGuestQuery({ type: "text", text: "Hi!" });
1667
+ * });
1668
+ * ```
1669
+ * */
1670
+ guestQuery<Ctx = ContextType<typeof this, "guest_message">>(handler: (context: Ctx & {
1671
+ args: RegExpMatchArray | null;
1672
+ }) => unknown): this;
1673
+ guestQuery<Ctx = ContextType<typeof this, "guest_message">>(trigger: RegExp | string | ((context: Ctx) => boolean), handler: (context: Ctx & {
1674
+ args: RegExpMatchArray | null;
1675
+ }) => unknown, options?: HandlerOptions<Ctx, Macros>): this;
1527
1676
  /**
1528
1677
  * Register handler to `message` and `business_message` event
1529
1678
  *
@@ -1996,7 +2145,7 @@ interface WebhookHandlerOptions {
1996
2145
  * });
1997
2146
  * ```
1998
2147
  */
1999
- declare function webhookHandler<Framework extends keyof typeof frameworks>(bot: Bot, framework: Framework, secretTokenOrOptions?: string | WebhookHandlerOptions): ReturnType<(typeof frameworks)[Framework]> extends {
2148
+ declare function webhookHandler<Framework extends keyof typeof frameworks>(bot: AnyBot, framework: Framework, secretTokenOrOptions?: string | WebhookHandlerOptions): ReturnType<(typeof frameworks)[Framework]> extends {
2000
2149
  response: () => any;
2001
2150
  } ? (...args: Parameters<(typeof frameworks)[Framework]>) => ReturnType<ReturnType<(typeof frameworks)[Framework]>["response"]> : (...args: Parameters<(typeof frameworks)[Framework]>) => void;
2002
2151
 
package/dist/index.d.ts CHANGED
@@ -4,6 +4,7 @@ export * from '@gramio/callback-data';
4
4
  import * as _gramio_contexts from '@gramio/contexts';
5
5
  import { UpdateName, MessageEventName, CustomEventName, Context, ContextsMapping, BotLike, ContextType, Attachment, AttachmentsMapping, Dice, MessageOriginUser, MessageOriginChat, MessageOriginChannel, MessageOriginHiddenUser, Message, MessageEntity, TextQuote, User, LinkPreviewOptions, ExternalReplyInfo, Chat, Giveaway, PaidMediaInfo, Game, StoryAttachment, Venue, MessageContext } from '@gramio/contexts';
6
6
  export * from '@gramio/contexts';
7
+ import { FileSource, TelegramFileDownload } from '@gramio/files';
7
8
  export * from '@gramio/files';
8
9
  export * from '@gramio/format';
9
10
  export * from '@gramio/keyboards';
@@ -12,7 +13,7 @@ import { APIMethods, TelegramResponseParameters, TelegramAPIResponseError, Teleg
12
13
  export * from '@gramio/types';
13
14
  import * as _gramio_composer from '@gramio/composer';
14
15
  import { ComposerLike, MacroDefinitions, EventContextOf, EventComposer, MacroDef, Next, EventQueue, HandlerOptions, DeriveFromOptions } from '@gramio/composer';
15
- export { ContextCallback, DeriveFromOptions, EventComposer, EventQueue, HandlerOptions, MacroDef, MacroDefinitions, MacroDeriveType, MacroHooks, MacroOptionType, Middleware, Next, WithCtx, buildFromOptions, compose, noopNext, skip, stop } from '@gramio/composer';
16
+ export { ContextCallback, DeriveFromOptions, DeriveHandler, EventComposer, EventQueue, HandlerOptions, MacroDef, MacroDefinitions, MacroDeriveType, MacroHooks, MacroOptionType, Middleware, Next, WithCtx, WithDecorate, WithDerives, WithEventDerive, WithExtend, buildFromOptions, compose, noopNext, skip, stop } from '@gramio/composer';
16
17
 
17
18
  /**
18
19
  * Telegram Bot API top-level update type name.
@@ -184,16 +185,24 @@ declare const methods: {
184
185
  callbackQuery<TThis extends GramIOLike<TThis>, Trigger extends CallbackData | string | RegExp>(this: TThis, trigger: Trigger, handler: (context: Ctx<"callback_query"> & {
185
186
  queryData: Trigger extends CallbackData ? ReturnType<Trigger["unpack"]> : Trigger extends RegExp ? RegExpMatchArray : never;
186
187
  } & EventContextOf<TThis, "callback_query">) => unknown, macroOptions?: Record<string, unknown>): TThis;
187
- chosenInlineResult<TThis extends GramIOLike<TThis>>(this: TThis, trigger: RegExp | string | ((context: Ctx<"chosen_inline_result">) => boolean), handler: (context: Ctx<"chosen_inline_result"> & {
188
+ chosenInlineResult<TThis extends GramIOLike<TThis>, Trigger extends CallbackData | RegExp | string | ((context: Ctx<"chosen_inline_result">) => boolean)>(this: TThis, trigger: Trigger, handler: (context: Ctx<"chosen_inline_result"> & {
188
189
  args: RegExpMatchArray | null;
190
+ queryData: Trigger extends CallbackData ? ReturnType<Trigger["unpack"]> : never;
189
191
  } & EventContextOf<TThis, "chosen_inline_result">) => unknown, macroOptions?: Record<string, unknown>): TThis;
190
- inlineQuery<TThis extends GramIOLike<TThis>>(this: TThis, trigger: RegExp | string | ((context: Ctx<"inline_query">) => boolean), handler: (context: Ctx<"inline_query"> & {
192
+ inlineQuery<TThis extends GramIOLike<TThis>>(this: TThis, triggerOrHandler: RegExp | string | ((context: Ctx<"inline_query">) => boolean) | ((context: Ctx<"inline_query"> & {
193
+ args: RegExpMatchArray | null;
194
+ } & EventContextOf<TThis, "inline_query">) => unknown), maybeHandler?: (context: Ctx<"inline_query"> & {
191
195
  args: RegExpMatchArray | null;
192
196
  } & EventContextOf<TThis, "inline_query">) => unknown, options?: {
193
197
  onResult?: (context: Ctx<"chosen_inline_result"> & {
194
198
  args: RegExpMatchArray | null;
195
199
  } & EventContextOf<TThis, "chosen_inline_result">) => unknown;
196
200
  } & Record<string, unknown>): TThis;
201
+ guestQuery<TThis extends GramIOLike<TThis>>(this: TThis, triggerOrHandler: RegExp | string | ((context: Ctx<"guest_message">) => boolean) | ((context: Ctx<"guest_message"> & {
202
+ args: RegExpMatchArray | null;
203
+ } & EventContextOf<TThis, "guest_message">) => unknown), maybeHandler?: (context: Ctx<"guest_message"> & {
204
+ args: RegExpMatchArray | null;
205
+ } & EventContextOf<TThis, "guest_message">) => unknown, macroOptions?: Record<string, unknown>): TThis;
197
206
  hears<TThis extends GramIOLike<TThis>>(this: TThis, trigger: RegExp | MaybeArray<string> | ((context: Ctx<"message">) => boolean), handler: (context: Ctx<"message"> & {
198
207
  args: RegExpMatchArray | null;
199
208
  } & EventContextOf<TThis, "message">) => unknown, macroOptions?: Record<string, unknown>): TThis;
@@ -216,6 +225,7 @@ declare module "@gramio/composer" {
216
225
  hears: (typeof methods)["hears"];
217
226
  reaction: (typeof methods)["reaction"];
218
227
  inlineQuery: (typeof methods)["inlineQuery"];
228
+ guestQuery: (typeof methods)["guestQuery"];
219
229
  chosenInlineResult: (typeof methods)["chosenInlineResult"];
220
230
  startParameter: (typeof methods)["startParameter"];
221
231
  }
@@ -225,16 +235,24 @@ declare const Composer: _gramio_composer.EventComposerConstructor<Context<AnyBot
225
235
  callbackQuery<TThis extends GramIOLike<TThis>, Trigger extends CallbackData | string | RegExp>(this: TThis, trigger: Trigger, handler: (context: Ctx<"callback_query"> & {
226
236
  queryData: Trigger extends CallbackData ? ReturnType<Trigger["unpack"]> : Trigger extends RegExp ? RegExpMatchArray : never;
227
237
  } & EventContextOf<TThis, "callback_query">) => unknown, macroOptions?: Record<string, unknown>): TThis;
228
- chosenInlineResult<TThis extends GramIOLike<TThis>>(this: TThis, trigger: RegExp | string | ((context: Ctx<"chosen_inline_result">) => boolean), handler: (context: Ctx<"chosen_inline_result"> & {
238
+ chosenInlineResult<TThis extends GramIOLike<TThis>, Trigger extends CallbackData | RegExp | string | ((context: Ctx<"chosen_inline_result">) => boolean)>(this: TThis, trigger: Trigger, handler: (context: Ctx<"chosen_inline_result"> & {
229
239
  args: RegExpMatchArray | null;
240
+ queryData: Trigger extends CallbackData ? ReturnType<Trigger["unpack"]> : never;
230
241
  } & EventContextOf<TThis, "chosen_inline_result">) => unknown, macroOptions?: Record<string, unknown>): TThis;
231
- inlineQuery<TThis extends GramIOLike<TThis>>(this: TThis, trigger: RegExp | string | ((context: Ctx<"inline_query">) => boolean), handler: (context: Ctx<"inline_query"> & {
242
+ inlineQuery<TThis extends GramIOLike<TThis>>(this: TThis, triggerOrHandler: RegExp | string | ((context: Ctx<"inline_query">) => boolean) | ((context: Ctx<"inline_query"> & {
243
+ args: RegExpMatchArray | null;
244
+ } & EventContextOf<TThis, "inline_query">) => unknown), maybeHandler?: (context: Ctx<"inline_query"> & {
232
245
  args: RegExpMatchArray | null;
233
246
  } & EventContextOf<TThis, "inline_query">) => unknown, options?: {
234
247
  onResult?: (context: Ctx<"chosen_inline_result"> & {
235
248
  args: RegExpMatchArray | null;
236
249
  } & EventContextOf<TThis, "chosen_inline_result">) => unknown;
237
250
  } & Record<string, unknown>): TThis;
251
+ guestQuery<TThis extends GramIOLike<TThis>>(this: TThis, triggerOrHandler: RegExp | string | ((context: Ctx<"guest_message">) => boolean) | ((context: Ctx<"guest_message"> & {
252
+ args: RegExpMatchArray | null;
253
+ } & EventContextOf<TThis, "guest_message">) => unknown), maybeHandler?: (context: Ctx<"guest_message"> & {
254
+ args: RegExpMatchArray | null;
255
+ } & EventContextOf<TThis, "guest_message">) => unknown, macroOptions?: Record<string, unknown>): TThis;
238
256
  hears<TThis extends GramIOLike<TThis>>(this: TThis, trigger: RegExp | MaybeArray<string> | ((context: Ctx<"message">) => boolean), handler: (context: Ctx<"message"> & {
239
257
  args: RegExpMatchArray | null;
240
258
  } & EventContextOf<TThis, "message">) => unknown, macroOptions?: Record<string, unknown>): TThis;
@@ -325,6 +343,7 @@ declare class Plugin<Errors extends ErrorDefinitions = {}, Derives extends Deriv
325
343
  edited_channel_post: _gramio_contexts.MessageContext<AnyBot> & _gramio_contexts.Require<_gramio_contexts.MessageContext<AnyBot>, "from">;
326
344
  business_message: _gramio_contexts.MessageContext<AnyBot> & _gramio_contexts.Require<_gramio_contexts.MessageContext<AnyBot>, "from">;
327
345
  edited_business_message: _gramio_contexts.MessageContext<AnyBot> & _gramio_contexts.Require<_gramio_contexts.MessageContext<AnyBot>, "from">;
346
+ guest_message: _gramio_contexts.MessageContext<AnyBot> & _gramio_contexts.Require<_gramio_contexts.MessageContext<AnyBot>, "from">;
328
347
  deleted_business_messages: _gramio_contexts.BusinessMessagesDeletedContext<AnyBot>;
329
348
  business_connection: _gramio_contexts.BusinessConnectionContext<AnyBot>;
330
349
  migrate_from_chat_id: _gramio_contexts.MigrateFromChatIdContext<AnyBot>;
@@ -408,8 +427,9 @@ declare class Plugin<Errors extends ErrorDefinitions = {}, Derives extends Deriv
408
427
  Derives?: Record<string, object>;
409
428
  };
410
429
  chosenInlineResult(trigger: any, handler: any, macroOptions?: any): TThis;
411
- }>(this: TThis, trigger: RegExp | string | ((context: _gramio_contexts.ChosenInlineResultContext<AnyBot>) => boolean), handler: (context: _gramio_contexts.ChosenInlineResultContext<AnyBot> & {
430
+ }, Trigger extends _gramio_callback_data.CallbackData | RegExp | string | ((context: _gramio_contexts.ChosenInlineResultContext<AnyBot>) => boolean)>(this: TThis, trigger: Trigger, handler: (context: _gramio_contexts.ChosenInlineResultContext<AnyBot> & {
412
431
  args: RegExpMatchArray | null;
432
+ queryData: Trigger extends _gramio_callback_data.CallbackData ? ReturnType<Trigger["unpack"]> : never;
413
433
  } & _gramio_composer.EventContextOf<TThis, "chosen_inline_result">) => unknown, macroOptions?: Record<string, unknown>): TThis;
414
434
  inlineQuery<TThis extends _gramio_composer.ComposerLike<TThis> & {
415
435
  "~": {
@@ -418,13 +438,27 @@ declare class Plugin<Errors extends ErrorDefinitions = {}, Derives extends Deriv
418
438
  Derives?: Record<string, object>;
419
439
  };
420
440
  chosenInlineResult(trigger: any, handler: any, macroOptions?: any): TThis;
421
- }>(this: TThis, trigger: RegExp | string | ((context: _gramio_contexts.InlineQueryContext<AnyBot>) => boolean), handler: (context: _gramio_contexts.InlineQueryContext<AnyBot> & {
441
+ }>(this: TThis, triggerOrHandler: RegExp | string | ((context: _gramio_contexts.InlineQueryContext<AnyBot>) => boolean) | ((context: _gramio_contexts.InlineQueryContext<AnyBot> & {
442
+ args: RegExpMatchArray | null;
443
+ } & _gramio_composer.EventContextOf<TThis, "inline_query">) => unknown), maybeHandler?: (context: _gramio_contexts.InlineQueryContext<AnyBot> & {
422
444
  args: RegExpMatchArray | null;
423
445
  } & _gramio_composer.EventContextOf<TThis, "inline_query">) => unknown, options?: {
424
446
  onResult?: (context: _gramio_contexts.ChosenInlineResultContext<AnyBot> & {
425
447
  args: RegExpMatchArray | null;
426
448
  } & _gramio_composer.EventContextOf<TThis, "chosen_inline_result">) => unknown;
427
449
  } & Record<string, unknown>): TThis;
450
+ guestQuery<TThis extends _gramio_composer.ComposerLike<TThis> & {
451
+ "~": {
452
+ macros: MacroDefinitions;
453
+ commandsMeta?: Map<string, unknown>;
454
+ Derives?: Record<string, object>;
455
+ };
456
+ chosenInlineResult(trigger: any, handler: any, macroOptions?: any): TThis;
457
+ }>(this: TThis, triggerOrHandler: RegExp | string | ((context: _gramio_contexts.MessageContext<AnyBot> & _gramio_contexts.Require<_gramio_contexts.MessageContext<AnyBot>, "from">) => boolean) | ((context: (_gramio_contexts.MessageContext<AnyBot> & _gramio_contexts.Require<_gramio_contexts.MessageContext<AnyBot>, "from">) & {
458
+ args: RegExpMatchArray | null;
459
+ } & _gramio_composer.EventContextOf<TThis, "guest_message">) => unknown), maybeHandler?: (context: (_gramio_contexts.MessageContext<AnyBot> & _gramio_contexts.Require<_gramio_contexts.MessageContext<AnyBot>, "from">) & {
460
+ args: RegExpMatchArray | null;
461
+ } & _gramio_composer.EventContextOf<TThis, "guest_message">) => unknown, macroOptions?: Record<string, unknown>): TThis;
428
462
  hears<TThis extends _gramio_composer.ComposerLike<TThis> & {
429
463
  "~": {
430
464
  macros: MacroDefinitions;
@@ -483,8 +517,9 @@ declare class Plugin<Errors extends ErrorDefinitions = {}, Derives extends Deriv
483
517
  Derives?: Record<string, object>;
484
518
  };
485
519
  chosenInlineResult(trigger: any, handler: any, macroOptions?: any): TThis;
486
- }>(this: TThis, trigger: RegExp | string | ((context: _gramio_contexts.ChosenInlineResultContext<AnyBot>) => boolean), handler: (context: _gramio_contexts.ChosenInlineResultContext<AnyBot> & {
520
+ }, Trigger extends _gramio_callback_data.CallbackData | RegExp | string | ((context: _gramio_contexts.ChosenInlineResultContext<AnyBot>) => boolean)>(this: TThis, trigger: Trigger, handler: (context: _gramio_contexts.ChosenInlineResultContext<AnyBot> & {
487
521
  args: RegExpMatchArray | null;
522
+ queryData: Trigger extends _gramio_callback_data.CallbackData ? ReturnType<Trigger["unpack"]> : never;
488
523
  } & _gramio_composer.EventContextOf<TThis, "chosen_inline_result">) => unknown, macroOptions?: Record<string, unknown>): TThis;
489
524
  inlineQuery<TThis extends _gramio_composer.ComposerLike<TThis> & {
490
525
  "~": {
@@ -493,13 +528,27 @@ declare class Plugin<Errors extends ErrorDefinitions = {}, Derives extends Deriv
493
528
  Derives?: Record<string, object>;
494
529
  };
495
530
  chosenInlineResult(trigger: any, handler: any, macroOptions?: any): TThis;
496
- }>(this: TThis, trigger: RegExp | string | ((context: _gramio_contexts.InlineQueryContext<AnyBot>) => boolean), handler: (context: _gramio_contexts.InlineQueryContext<AnyBot> & {
531
+ }>(this: TThis, triggerOrHandler: RegExp | string | ((context: _gramio_contexts.InlineQueryContext<AnyBot>) => boolean) | ((context: _gramio_contexts.InlineQueryContext<AnyBot> & {
532
+ args: RegExpMatchArray | null;
533
+ } & _gramio_composer.EventContextOf<TThis, "inline_query">) => unknown), maybeHandler?: (context: _gramio_contexts.InlineQueryContext<AnyBot> & {
497
534
  args: RegExpMatchArray | null;
498
535
  } & _gramio_composer.EventContextOf<TThis, "inline_query">) => unknown, options?: {
499
536
  onResult?: (context: _gramio_contexts.ChosenInlineResultContext<AnyBot> & {
500
537
  args: RegExpMatchArray | null;
501
538
  } & _gramio_composer.EventContextOf<TThis, "chosen_inline_result">) => unknown;
502
539
  } & Record<string, unknown>): TThis;
540
+ guestQuery<TThis extends _gramio_composer.ComposerLike<TThis> & {
541
+ "~": {
542
+ macros: MacroDefinitions;
543
+ commandsMeta?: Map<string, unknown>;
544
+ Derives?: Record<string, object>;
545
+ };
546
+ chosenInlineResult(trigger: any, handler: any, macroOptions?: any): TThis;
547
+ }>(this: TThis, triggerOrHandler: RegExp | string | ((context: _gramio_contexts.MessageContext<AnyBot> & _gramio_contexts.Require<_gramio_contexts.MessageContext<AnyBot>, "from">) => boolean) | ((context: (_gramio_contexts.MessageContext<AnyBot> & _gramio_contexts.Require<_gramio_contexts.MessageContext<AnyBot>, "from">) & {
548
+ args: RegExpMatchArray | null;
549
+ } & _gramio_composer.EventContextOf<TThis, "guest_message">) => unknown), maybeHandler?: (context: (_gramio_contexts.MessageContext<AnyBot> & _gramio_contexts.Require<_gramio_contexts.MessageContext<AnyBot>, "from">) & {
550
+ args: RegExpMatchArray | null;
551
+ } & _gramio_composer.EventContextOf<TThis, "guest_message">) => unknown, macroOptions?: Record<string, unknown>): TThis;
503
552
  hears<TThis extends _gramio_composer.ComposerLike<TThis> & {
504
553
  "~": {
505
554
  macros: MacroDefinitions;
@@ -750,6 +799,8 @@ interface Plugin<Errors, Derives, Macros> {
750
799
  reaction: (typeof methods)["reaction"];
751
800
  /** Register inline query handler */
752
801
  inlineQuery: (typeof methods)["inlineQuery"];
802
+ /** Register guest query (`guest_message`) handler */
803
+ guestQuery: (typeof methods)["guestQuery"];
753
804
  /** Register chosen inline result handler */
754
805
  chosenInlineResult: (typeof methods)["chosenInlineResult"];
755
806
  /** Register deep-link parameter handler */
@@ -794,6 +845,30 @@ interface BotOptions {
794
845
  */
795
846
  retryGetUpdatesWait?: number;
796
847
  };
848
+ /**
849
+ * File download/serving options — mainly for a **local Bot API server**.
850
+ *
851
+ * @example
852
+ * ```ts
853
+ * const bot = new Bot(token, {
854
+ * api: { baseURL: "http://telegram-bot-api:8081/bot" },
855
+ * files: {
856
+ * // bot.getFileLink() and ctx.download() resolve to this (token-less) URL
857
+ * baseURL: "http://telegram-bot-api:8080",
858
+ * },
859
+ * });
860
+ * ```
861
+ */
862
+ files?: {
863
+ /** How to fetch file bytes. @default "auto" */
864
+ source?: FileSource;
865
+ /** Working directory of the local Bot API server — the prefix of the absolute `file_path` it returns. @default "/var/lib/telegram-bot-api" */
866
+ localDir?: string;
867
+ /** Where that working dir is mounted on the bot's side (for `source: "disk"` when bot & server share a volume at a different path). Defaults to `localDir`. */
868
+ mountDir?: string;
869
+ /** Public base URL where the working dir is served (e.g. the bundled file server / nginx). Enables token-less {@link Bot.getFileLink} and `source: "rewrite"`. */
870
+ baseURL?: string;
871
+ };
797
872
  }
798
873
  /**
799
874
  * Handler is a function with context and next function arguments
@@ -1202,10 +1277,27 @@ declare class Bot<Errors extends ErrorDefinitions = {}, Derives extends DeriveDe
1202
1277
  */
1203
1278
  downloadFile(attachment: Attachment | {
1204
1279
  file_id: string;
1205
- } | string): Promise<ArrayBuffer>;
1280
+ } | string): TelegramFileDownload;
1206
1281
  downloadFile(attachment: Attachment | {
1207
1282
  file_id: string;
1208
1283
  } | string, path: string): Promise<string>;
1284
+ /**
1285
+ * Get a shareable download link for a file.
1286
+ *
1287
+ * When {@link BotOptions.files | `files.baseURL`} is set (e.g. a local Bot API
1288
+ * server with the bundled file server), the link is **token-less and path-based**
1289
+ * — safe to hand to users. Otherwise it falls back to the classic
1290
+ * `…/file/bot<token>/<path>` URL (which contains the bot token).
1291
+ *
1292
+ * @example
1293
+ * ```ts
1294
+ * const link = await bot.getFileLink(ctx.document.fileId);
1295
+ * await ctx.reply(`Download: ${link}`);
1296
+ * ```
1297
+ */
1298
+ getFileLink(attachment: Attachment | {
1299
+ file_id: string;
1300
+ } | string): Promise<string>;
1209
1301
  /**
1210
1302
  * Register custom class-error for type-safe catch in `onError` hook
1211
1303
  *
@@ -1478,9 +1570,35 @@ declare class Bot<Errors extends ErrorDefinitions = {}, Derives extends DeriveDe
1478
1570
  * ```
1479
1571
  */
1480
1572
  callbackQuery<Trigger extends CallbackData | string | RegExp, TOptions extends HandlerOptions<CallbackQueryShorthandContext<typeof this, Trigger>, Macros> = {}>(trigger: Trigger, handler: (context: CallbackQueryShorthandContext<typeof this, Trigger> & DeriveFromOptions<Macros, TOptions>) => unknown, options?: TOptions): this;
1481
- /** Register handler to `chosen_inline_result` update */
1482
- chosenInlineResult<Ctx = ContextType<typeof this, "chosen_inline_result">, TOptions extends HandlerOptions<Ctx, Macros> = {}>(trigger: RegExp | string | ((context: Ctx) => boolean), handler: (context: Ctx & {
1573
+ /**
1574
+ * Register handler to `chosen_inline_result` update
1575
+ *
1576
+ * Accepts a `CallbackData` schema for type-safe filtering on `result_id`:
1577
+ *
1578
+ * @example
1579
+ * ```ts
1580
+ * const trackRef = new CallbackData("track").string("src").string("id");
1581
+ *
1582
+ * new Bot()
1583
+ * .on("inline_query", async (ctx) => {
1584
+ * await ctx.answer(tracks.map((t) => ({
1585
+ * type: "audio",
1586
+ * id: trackRef.pack({ src: t.source, id: t.id }),
1587
+ * audio_url: t.url,
1588
+ * title: t.title,
1589
+ * })));
1590
+ * })
1591
+ * .chosenInlineResult(trackRef, (ctx) => {
1592
+ * ctx.queryData; // { src: string; id: string }
1593
+ * });
1594
+ * ```
1595
+ *
1596
+ * String/RegExp/predicate triggers filter on `context.query` (the user's
1597
+ * typed text); the `CallbackData` schema filters on `context.resultId`.
1598
+ */
1599
+ chosenInlineResult<Trigger extends CallbackData | RegExp | string | ((context: ContextType<typeof this, "chosen_inline_result">) => boolean), Ctx = ContextType<typeof this, "chosen_inline_result">, TOptions extends HandlerOptions<Ctx, Macros> = {}>(trigger: Trigger, handler: (context: Ctx & {
1483
1600
  args: RegExpMatchArray | null;
1601
+ queryData: Trigger extends CallbackData ? ReturnType<Trigger["unpack"]> : never;
1484
1602
  } & DeriveFromOptions<Macros, TOptions>) => unknown, options?: TOptions): this;
1485
1603
  /**
1486
1604
  * Register handler to `inline_query` update
@@ -1517,6 +1635,9 @@ declare class Bot<Errors extends ErrorDefinitions = {}, Derives extends DeriveDe
1517
1635
  * );
1518
1636
  * ```
1519
1637
  * */
1638
+ inlineQuery<Ctx = ContextType<typeof this, "inline_query">>(handler: (context: Ctx & {
1639
+ args: RegExpMatchArray | null;
1640
+ }) => unknown): this;
1520
1641
  inlineQuery<Ctx = ContextType<typeof this, "inline_query">>(trigger: RegExp | string | ((context: Ctx) => boolean), handler: (context: Ctx & {
1521
1642
  args: RegExpMatchArray | null;
1522
1643
  }) => unknown, options?: HandlerOptions<Ctx, Macros> & {
@@ -1524,6 +1645,34 @@ declare class Bot<Errors extends ErrorDefinitions = {}, Derives extends DeriveDe
1524
1645
  args: RegExpMatchArray | null;
1525
1646
  }) => unknown;
1526
1647
  }): this;
1648
+ /**
1649
+ * Register handler to `guest_message` update — a message sent to the bot
1650
+ * from a chat where the bot is not a member, via a guest query.
1651
+ *
1652
+ * Reply with {@link MessageContext.answerGuestQuery `context.answerGuestQuery()`}
1653
+ * (NOT `context.send`/`context.reply`, which target a chat the bot can't post to).
1654
+ *
1655
+ * @example
1656
+ * ```ts
1657
+ * new Bot().guestQuery(/^find (.*)/i, async (context) => {
1658
+ * await context.answerGuestQuery({
1659
+ * type: "text",
1660
+ * text: `Looking up ${context.args?.[1]}…`,
1661
+ * });
1662
+ * });
1663
+ *
1664
+ * // No-trigger form — match any guest message:
1665
+ * new Bot().guestQuery(async (context) => {
1666
+ * await context.answerGuestQuery({ type: "text", text: "Hi!" });
1667
+ * });
1668
+ * ```
1669
+ * */
1670
+ guestQuery<Ctx = ContextType<typeof this, "guest_message">>(handler: (context: Ctx & {
1671
+ args: RegExpMatchArray | null;
1672
+ }) => unknown): this;
1673
+ guestQuery<Ctx = ContextType<typeof this, "guest_message">>(trigger: RegExp | string | ((context: Ctx) => boolean), handler: (context: Ctx & {
1674
+ args: RegExpMatchArray | null;
1675
+ }) => unknown, options?: HandlerOptions<Ctx, Macros>): this;
1527
1676
  /**
1528
1677
  * Register handler to `message` and `business_message` event
1529
1678
  *
@@ -1996,7 +2145,7 @@ interface WebhookHandlerOptions {
1996
2145
  * });
1997
2146
  * ```
1998
2147
  */
1999
- declare function webhookHandler<Framework extends keyof typeof frameworks>(bot: Bot, framework: Framework, secretTokenOrOptions?: string | WebhookHandlerOptions): ReturnType<(typeof frameworks)[Framework]> extends {
2148
+ declare function webhookHandler<Framework extends keyof typeof frameworks>(bot: AnyBot, framework: Framework, secretTokenOrOptions?: string | WebhookHandlerOptions): ReturnType<(typeof frameworks)[Framework]> extends {
2000
2149
  response: () => any;
2001
2150
  } ? (...args: Parameters<(typeof frameworks)[Framework]>) => ReturnType<ReturnType<(typeof frameworks)[Framework]>["response"]> : (...args: Parameters<(typeof frameworks)[Framework]>) => void;
2002
2151
 
package/dist/index.js CHANGED
@@ -1,13 +1,11 @@
1
1
  export * from '@gramio/callback-data';
2
- import { contextsMappings, PhotoAttachment } from '@gramio/contexts';
2
+ import { contextsMappings } from '@gramio/contexts';
3
3
  export * from '@gramio/contexts';
4
- import { isMediaUpload, convertJsonToFormData, extractFilesToFormData } from '@gramio/files';
4
+ import { downloadFile, isMediaUpload, convertJsonToFormData, extractFilesToFormData } from '@gramio/files';
5
5
  export * from '@gramio/files';
6
6
  import { FormattableMap } from '@gramio/format';
7
7
  export * from '@gramio/format';
8
8
  export * from '@gramio/keyboards';
9
- import fs from 'node:fs/promises';
10
- import { Readable } from 'node:stream';
11
9
  import debug from 'debug';
12
10
  import { E as ErrorKind, w as withRetries, T as TelegramError, s as sleep, d as debug$updates, a as simpleHash, I as IS_BUN, b as simplifyObject, t as timeoutWebhook } from './utils-1ejkKLIB.js';
13
11
  import { defineComposerMethods, buildFromOptions, noopNext, createComposer, eventTypes, EventQueue } from '@gramio/composer';
@@ -37,7 +35,8 @@ const ALL_NAMES = [
37
35
  "chat_join_request",
38
36
  "chat_boost",
39
37
  "removed_chat_boost",
40
- "managed_bot"
38
+ "managed_bot",
39
+ "guest_message"
41
40
  ];
42
41
  const MESSAGE_PARENT_TYPES = [
43
42
  "message",
@@ -200,13 +199,23 @@ const methods = defineComposerMethods({
200
199
  return macroHandler ? macroHandler(context, noopNext) : handler(context);
201
200
  });
202
201
  }
202
+ if (typeof trigger === "function") {
203
+ return this.on("chosen_inline_result", (context, next) => {
204
+ if (!trigger(context)) return next();
205
+ context.args = null;
206
+ return macroHandler ? macroHandler(context, noopNext) : handler(context);
207
+ });
208
+ }
203
209
  return this.on("chosen_inline_result", (context, next) => {
204
- if (!trigger(context)) return next();
210
+ if (!context.resultId || !trigger.filter(context.resultId)) return next();
205
211
  context.args = null;
212
+ context.queryData = trigger.unpack(context.resultId);
206
213
  return macroHandler ? macroHandler(context, noopNext) : handler(context);
207
214
  });
208
215
  },
209
- inlineQuery(trigger, handler, options = {}) {
216
+ inlineQuery(triggerOrHandler, maybeHandler, options = {}) {
217
+ const trigger = maybeHandler === void 0 ? (() => true) : triggerOrHandler;
218
+ const handler = maybeHandler ?? triggerOrHandler;
210
219
  if (options.onResult) this.chosenInlineResult(trigger, options.onResult);
211
220
  const { onResult: _, ...macroOptions } = options;
212
221
  const hasMacros = Object.keys(macroOptions).length > 0;
@@ -231,6 +240,32 @@ const methods = defineComposerMethods({
231
240
  return macroHandler ? macroHandler(context, noopNext) : handler(context);
232
241
  });
233
242
  },
243
+ guestQuery(triggerOrHandler, maybeHandler, macroOptions) {
244
+ const trigger = maybeHandler === void 0 ? (() => true) : triggerOrHandler;
245
+ const handler = maybeHandler ?? triggerOrHandler;
246
+ const macroHandler = macroOptions ? buildFromOptions(this["~"].macros, macroOptions, handler) : null;
247
+ if (typeof trigger === "string") {
248
+ return this.on("guest_message", (context, next) => {
249
+ const text = context.text ?? context.caption;
250
+ if (text !== trigger) return next();
251
+ context.args = null;
252
+ return macroHandler ? macroHandler(context, noopNext) : handler(context);
253
+ });
254
+ }
255
+ if (trigger instanceof RegExp) {
256
+ return this.on("guest_message", (context, next) => {
257
+ const text = context.text ?? context.caption;
258
+ if (!text || !trigger.test(text)) return next();
259
+ context.args = text.match(trigger);
260
+ return macroHandler ? macroHandler(context, noopNext) : handler(context);
261
+ });
262
+ }
263
+ return this.on("guest_message", (context, next) => {
264
+ if (!trigger(context)) return next();
265
+ context.args = null;
266
+ return macroHandler ? macroHandler(context, noopNext) : handler(context);
267
+ });
268
+ },
234
269
  hears(trigger, handler, macroOptions) {
235
270
  const macroHandler = macroOptions ? buildFromOptions(this["~"].macros, macroOptions, handler) : null;
236
271
  if (typeof trigger === "string") {
@@ -692,6 +727,7 @@ class Updates {
692
727
  })
693
728
  );
694
729
  this.isRequestActive = false;
730
+ if (!this.isStarted) break;
695
731
  const updateId = updates.at(-1)?.update_id;
696
732
  this.offset = updateId ? updateId + 1 : this.offset;
697
733
  this.queue.addBatch(updates);
@@ -911,28 +947,26 @@ class Bot {
911
947
  }
912
948
  return fn();
913
949
  }
914
- async downloadFile(attachment, path) {
915
- function getFileId(attachment2) {
916
- if (attachment2 instanceof PhotoAttachment) {
917
- return attachment2.bigSize.fileId;
918
- }
919
- if ("fileId" in attachment2 && typeof attachment2.fileId === "string")
920
- return attachment2.fileId;
921
- if ("file_id" in attachment2) return attachment2.file_id;
922
- throw new Error("Invalid attachment");
923
- }
924
- const fileId = typeof attachment === "string" ? attachment : getFileId(attachment);
925
- const file = await this.api.getFile({ file_id: fileId });
926
- const url = `${this.options.api.baseURL.replace("/bot", "/file/bot")}${this.options.token}/${file.file_path}`;
927
- const res = await fetch(url);
928
- if (path) {
929
- if (!res.body)
930
- throw new Error("Response without body (should be never throw)");
931
- await fs.writeFile(path, Readable.fromWeb(res.body));
932
- return path;
933
- }
934
- const buffer = await res.arrayBuffer();
935
- return buffer;
950
+ downloadFile(attachment, path) {
951
+ const input = attachment;
952
+ return path ? downloadFile(this, input, path) : downloadFile(this, input);
953
+ }
954
+ /**
955
+ * Get a shareable download link for a file.
956
+ *
957
+ * When {@link BotOptions.files | `files.baseURL`} is set (e.g. a local Bot API
958
+ * server with the bundled file server), the link is **token-less and path-based**
959
+ * — safe to hand to users. Otherwise it falls back to the classic
960
+ * `…/file/bot<token>/<path>` URL (which contains the bot token).
961
+ *
962
+ * @example
963
+ * ```ts
964
+ * const link = await bot.getFileLink(ctx.document.fileId);
965
+ * await ctx.reply(`Download: ${link}`);
966
+ * ```
967
+ */
968
+ getFileLink(attachment) {
969
+ return downloadFile(this, attachment).link();
936
970
  }
937
971
  /**
938
972
  * Register custom class-error for type-safe catch in `onError` hook
@@ -1276,7 +1310,32 @@ class Bot {
1276
1310
  );
1277
1311
  return this;
1278
1312
  }
1279
- /** Register handler to `chosen_inline_result` update */
1313
+ /**
1314
+ * Register handler to `chosen_inline_result` update
1315
+ *
1316
+ * Accepts a `CallbackData` schema for type-safe filtering on `result_id`:
1317
+ *
1318
+ * @example
1319
+ * ```ts
1320
+ * const trackRef = new CallbackData("track").string("src").string("id");
1321
+ *
1322
+ * new Bot()
1323
+ * .on("inline_query", async (ctx) => {
1324
+ * await ctx.answer(tracks.map((t) => ({
1325
+ * type: "audio",
1326
+ * id: trackRef.pack({ src: t.source, id: t.id }),
1327
+ * audio_url: t.url,
1328
+ * title: t.title,
1329
+ * })));
1330
+ * })
1331
+ * .chosenInlineResult(trackRef, (ctx) => {
1332
+ * ctx.queryData; // { src: string; id: string }
1333
+ * });
1334
+ * ```
1335
+ *
1336
+ * String/RegExp/predicate triggers filter on `context.query` (the user's
1337
+ * typed text); the `CallbackData` schema filters on `context.resultId`.
1338
+ */
1280
1339
  chosenInlineResult(trigger, handler, options) {
1281
1340
  this.updates.composer.chosenInlineResult(
1282
1341
  trigger,
@@ -1285,49 +1344,18 @@ class Bot {
1285
1344
  );
1286
1345
  return this;
1287
1346
  }
1288
- /**
1289
- * Register handler to `inline_query` update
1290
- *
1291
- * @example
1292
- * ```ts
1293
- * new Bot().inlineQuery(
1294
- * /regular expression with (.*)/i,
1295
- * async (context) => {
1296
- * if (context.args) {
1297
- * await context.answer(
1298
- * [
1299
- * InlineQueryResult.article(
1300
- * "id-1",
1301
- * context.args[1],
1302
- * InputMessageContent.text("some"),
1303
- * {
1304
- * reply_markup: new InlineKeyboard().text(
1305
- * "some",
1306
- * "callback-data"
1307
- * ),
1308
- * }
1309
- * ),
1310
- * ],
1311
- * {
1312
- * cache_time: 0,
1313
- * }
1314
- * );
1315
- * }
1316
- * },
1317
- * {
1318
- * onResult: (context) => context.editText("Message edited!"),
1319
- * }
1320
- * );
1321
- * ```
1322
- * */
1323
- inlineQuery(trigger, handler, options) {
1347
+ inlineQuery(triggerOrHandler, handler, options) {
1324
1348
  this.updates.composer.inlineQuery(
1325
- trigger,
1349
+ triggerOrHandler,
1326
1350
  handler,
1327
1351
  options
1328
1352
  );
1329
1353
  return this;
1330
1354
  }
1355
+ guestQuery(triggerOrHandler, handler, options) {
1356
+ this.updates.composer.guestQuery(triggerOrHandler, handler, options);
1357
+ return this;
1358
+ }
1331
1359
  /**
1332
1360
  * Register handler to `message` and `business_message` event
1333
1361
  *
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "gramio",
3
3
  "type": "module",
4
- "version": "0.9.0",
4
+ "version": "0.11.0",
5
5
  "description": "Powerful, extensible and really type-safe Telegram Bot API framework",
6
6
  "main": "dist/index.cjs",
7
7
  "module": "dist/index.js",
@@ -55,25 +55,28 @@
55
55
  "author": "kravets",
56
56
  "license": "MIT",
57
57
  "devDependencies": {
58
- "@biomejs/biome": "2.4.4",
59
- "@gramio/test": "^0.5.0",
60
- "@types/bun": "^1.3.9",
61
- "@types/debug": "^4.1.12",
58
+ "@biomejs/biome": "2.4.14",
59
+ "@gramio/test": "^0.7.0",
60
+ "@types/bun": "^1.3.13",
61
+ "@types/debug": "^4.1.13",
62
62
  "expect-type": "^1.3.0",
63
63
  "pkgroll": "^2.27.0",
64
64
  "typescript": "^5.9.3"
65
65
  },
66
66
  "dependencies": {
67
67
  "@gramio/callback-data": "^0.1.0",
68
- "@gramio/composer": "^0.4.1",
69
- "@gramio/contexts": "^0.6.1",
70
- "@gramio/files": "^0.4.0",
71
- "@gramio/format": "^0.7.0",
68
+ "@gramio/composer": "^0.5.0",
69
+ "@gramio/contexts": "^0.8.0",
70
+ "@gramio/files": "^0.6.1",
71
+ "@gramio/format": "^0.8.0",
72
72
  "@gramio/keyboards": "^1.4.0",
73
- "@gramio/types": "^9.6.1",
73
+ "@gramio/types": "^10.0.0",
74
74
  "debug": "^4.4.3"
75
75
  },
76
76
  "files": [
77
77
  "dist"
78
- ]
78
+ ],
79
+ "overrides": {
80
+ "@gramio/types": "$@gramio/types"
81
+ }
79
82
  }