gramio 0.4.4 → 0.4.7

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
@@ -7,7 +7,7 @@ var contexts = require('@gramio/contexts');
7
7
  var files = require('@gramio/files');
8
8
  var format = require('@gramio/format');
9
9
  var debug = require('debug');
10
- var utils = require('./utils-CnG66NLH.cjs');
10
+ var utils = require('./utils-CYIya32k.cjs');
11
11
  var middlewareIo = require('middleware-io');
12
12
  var keyboards = require('@gramio/keyboards');
13
13
 
@@ -1002,15 +1002,23 @@ class Bot {
1002
1002
  * return context.send(`You message is /start ${context.args}`);
1003
1003
  * });
1004
1004
  */
1005
- command(command, handler, options) {
1006
- if (command.startsWith("/"))
1007
- throw new Error("Do not use / in command name");
1005
+ command(command, handler) {
1006
+ const normalizedCommands = typeof command === "string" ? [command] : Array.from(command);
1007
+ for (const cmd of normalizedCommands) {
1008
+ if (cmd.startsWith("/"))
1009
+ throw new Error(`Do not use / in command name (${cmd})`);
1010
+ }
1008
1011
  return this.on(["message", "business_message"], (context, next) => {
1009
1012
  if (context.entities?.some((entity) => {
1010
1013
  if (entity.type !== "bot_command" || entity.offset > 0) return false;
1011
- const cmd = context.text?.slice(1, entity.length)?.replace(`@${this.info.username}`, "");
1014
+ const cmd = context.text?.slice(1, entity.length)?.replace(
1015
+ this.info?.username ? `@${this.info.username}` : /@[a-zA-Z0-9_]+/,
1016
+ ""
1017
+ );
1012
1018
  context.args = context.text?.slice(entity.length).trim() || null;
1013
- return cmd === command;
1019
+ return normalizedCommands.some(
1020
+ (normalizedCommand) => cmd === normalizedCommand
1021
+ );
1014
1022
  }))
1015
1023
  return handler(context);
1016
1024
  return next();
@@ -1125,8 +1133,9 @@ class Bot {
1125
1133
 
1126
1134
  const SECRET_TOKEN_HEADER = "X-Telegram-Bot-Api-Secret-Token";
1127
1135
  const WRONG_TOKEN_ERROR = "secret token is invalid";
1128
- const responseOK = new Response("ok!");
1129
- const responseUnauthorized = new Response(WRONG_TOKEN_ERROR, {
1136
+ const RESPONSE_OK = "ok!";
1137
+ const responseOK = () => new Response(RESPONSE_OK);
1138
+ const responseUnauthorized = () => new Response(WRONG_TOKEN_ERROR, {
1130
1139
  status: 401
1131
1140
  // @ts-ignore
1132
1141
  });
@@ -1134,22 +1143,26 @@ const frameworks = {
1134
1143
  elysia: ({ body, headers }) => ({
1135
1144
  update: body,
1136
1145
  header: headers[SECRET_TOKEN_HEADER],
1137
- unauthorized: () => responseUnauthorized
1146
+ unauthorized: responseUnauthorized,
1147
+ response: responseOK
1138
1148
  }),
1139
1149
  fastify: (request, reply) => ({
1140
1150
  update: request.body,
1141
1151
  header: request.headers[SECRET_TOKEN_HEADER],
1142
- unauthorized: () => reply.code(401).send(WRONG_TOKEN_ERROR)
1152
+ unauthorized: () => reply.code(401).send(WRONG_TOKEN_ERROR),
1153
+ response: () => reply.send(RESPONSE_OK)
1143
1154
  }),
1144
1155
  hono: (c) => ({
1145
1156
  update: c.req.json(),
1146
1157
  header: c.req.header(SECRET_TOKEN_HEADER),
1147
- unauthorized: () => c.text(WRONG_TOKEN_ERROR, 401)
1158
+ unauthorized: () => c.text(WRONG_TOKEN_ERROR, 401),
1159
+ response: responseOK
1148
1160
  }),
1149
1161
  express: (req, res) => ({
1150
1162
  update: req.body,
1151
1163
  header: req.header(SECRET_TOKEN_HEADER),
1152
- unauthorized: () => res.status(401).send(WRONG_TOKEN_ERROR)
1164
+ unauthorized: () => res.status(401).send(WRONG_TOKEN_ERROR),
1165
+ response: () => res.send(RESPONSE_OK)
1153
1166
  }),
1154
1167
  koa: (ctx) => ({
1155
1168
  update: ctx.request.body,
@@ -1157,6 +1170,10 @@ const frameworks = {
1157
1170
  unauthorized: () => {
1158
1171
  ctx.status === 401;
1159
1172
  ctx.body = WRONG_TOKEN_ERROR;
1173
+ },
1174
+ response: () => {
1175
+ ctx.status = 200;
1176
+ ctx.body = RESPONSE_OK;
1160
1177
  }
1161
1178
  }),
1162
1179
  http: (req, res) => ({
@@ -1168,38 +1185,59 @@ const frameworks = {
1168
1185
  req.on("end", () => resolve(JSON.parse(body)));
1169
1186
  }),
1170
1187
  header: req.headers[SECRET_TOKEN_HEADER.toLowerCase()],
1171
- unauthorized: () => res.writeHead(401).end(WRONG_TOKEN_ERROR)
1188
+ unauthorized: () => res.writeHead(401).end(WRONG_TOKEN_ERROR),
1189
+ response: () => res.writeHead(200).end(RESPONSE_OK)
1172
1190
  }),
1173
- // TODO: Maybe unify it by 'WebRequest'
1174
1191
  "std/http": (req) => ({
1175
1192
  update: req.json(),
1176
1193
  header: req.headers.get(SECRET_TOKEN_HEADER),
1177
- response: () => responseOK,
1178
- unauthorized: () => responseUnauthorized
1194
+ response: responseOK,
1195
+ unauthorized: responseUnauthorized
1179
1196
  }),
1180
1197
  "Bun.serve": (req) => ({
1181
1198
  update: req.json(),
1182
1199
  header: req.headers.get(SECRET_TOKEN_HEADER),
1183
- response: () => responseOK,
1184
- unauthorized: () => responseUnauthorized
1200
+ response: responseOK,
1201
+ unauthorized: responseUnauthorized
1202
+ }),
1203
+ cloudflare: (req) => ({
1204
+ update: req.json(),
1205
+ header: req.headers.get(SECRET_TOKEN_HEADER),
1206
+ response: responseOK,
1207
+ unauthorized: responseUnauthorized
1185
1208
  }),
1186
1209
  Request: (req) => ({
1187
1210
  update: req.json(),
1188
1211
  header: req.headers.get(SECRET_TOKEN_HEADER),
1189
- response: () => responseOK,
1190
- unauthorized: () => responseUnauthorized
1212
+ response: responseOK,
1213
+ unauthorized: responseUnauthorized
1191
1214
  })
1192
1215
  };
1193
1216
 
1194
- function webhookHandler(bot, framework, secretToken) {
1217
+ function webhookHandler(bot, framework, secretTokenOrOptions) {
1195
1218
  const frameworkAdapter = frameworks[framework];
1219
+ const secretToken = typeof secretTokenOrOptions === "string" ? secretTokenOrOptions : secretTokenOrOptions?.secretToken;
1220
+ const shouldWaitOptions = typeof secretTokenOrOptions === "string" ? false : secretTokenOrOptions?.shouldWait;
1221
+ const isShouldWait = shouldWaitOptions && (typeof shouldWaitOptions === "object" || typeof shouldWaitOptions === "boolean");
1196
1222
  return async (...args) => {
1197
1223
  const { update, response, header, unauthorized } = frameworkAdapter(
1198
1224
  ...args
1199
1225
  );
1200
1226
  if (secretToken && header !== secretToken) return unauthorized();
1201
- bot.updates.queue.add(await update);
1202
- if (response) return response();
1227
+ if (!isShouldWait) {
1228
+ bot.updates.queue.add(await update);
1229
+ if (response) return response();
1230
+ } else {
1231
+ const timeoutOptions = typeof shouldWaitOptions === "object" ? shouldWaitOptions : void 0;
1232
+ const timeout = timeoutOptions?.timeout ?? 3e4;
1233
+ const onTimeout = timeoutOptions?.onTimeout ?? "throw";
1234
+ await utils.timeoutWebhook(
1235
+ bot.updates.handleUpdate(await update, "wait"),
1236
+ timeout,
1237
+ onTimeout
1238
+ );
1239
+ if (response) return response();
1240
+ }
1203
1241
  };
1204
1242
  }
1205
1243
 
package/dist/index.d.cts CHANGED
@@ -2,7 +2,7 @@ import { CallbackData } from '@gramio/callback-data';
2
2
  export * from '@gramio/callback-data';
3
3
  import { Context, UpdateName, ContextType, BotLike, Attachment } from '@gramio/contexts';
4
4
  export * from '@gramio/contexts';
5
- import { APIMethods, TelegramResponseParameters, TelegramAPIResponseError, TelegramUser, APIMethodParams, APIMethodReturn, SetWebhookParams, TelegramUpdate, TelegramReactionTypeEmojiEmoji, SetMyCommandsParams, TelegramBotCommand } from '@gramio/types';
5
+ import { APIMethods, TelegramResponseParameters, TelegramAPIResponseError, TelegramUser, APIMethodParams, APIMethodReturn, SetWebhookParams, TelegramUpdate, TelegramReactionTypeEmojiEmoji } from '@gramio/types';
6
6
  export * from '@gramio/types';
7
7
  import * as middleware_io from 'middleware-io';
8
8
  import { Composer as Composer$1, Middleware, CaughtMiddlewareHandler, NextMiddleware } from 'middleware-io';
@@ -977,9 +977,9 @@ declare class Bot<Errors extends ErrorDefinitions = {}, Derives extends DeriveDe
977
977
  * return context.send(`You message is /start ${context.args}`);
978
978
  * });
979
979
  */
980
- command(command: string, handler: (context: ContextType<typeof this, "message"> & {
980
+ command(command: MaybeArray<string>, handler: (context: ContextType<typeof this, "message"> & {
981
981
  args: string | null;
982
- }) => unknown, options?: Omit<SetMyCommandsParams, "commands"> & Omit<TelegramBotCommand, "command">): this;
982
+ }) => unknown): this;
983
983
  /** Currently not isolated!!! */
984
984
  group(grouped: (bot: typeof this) => AnyBot): typeof this;
985
985
  /**
@@ -1012,31 +1012,37 @@ declare const frameworks: {
1012
1012
  update: any;
1013
1013
  header: any;
1014
1014
  unauthorized: () => Response;
1015
+ response: () => Response;
1015
1016
  };
1016
1017
  fastify: (request: any, reply: any) => {
1017
1018
  update: any;
1018
1019
  header: any;
1019
1020
  unauthorized: () => any;
1021
+ response: () => any;
1020
1022
  };
1021
1023
  hono: (c: any) => {
1022
1024
  update: any;
1023
1025
  header: any;
1024
1026
  unauthorized: () => any;
1027
+ response: () => Response;
1025
1028
  };
1026
1029
  express: (req: any, res: any) => {
1027
1030
  update: any;
1028
1031
  header: any;
1029
1032
  unauthorized: () => any;
1033
+ response: () => any;
1030
1034
  };
1031
1035
  koa: (ctx: any) => {
1032
1036
  update: any;
1033
1037
  header: any;
1034
1038
  unauthorized: () => void;
1039
+ response: () => void;
1035
1040
  };
1036
1041
  http: (req: any, res: any) => {
1037
1042
  update: Promise<TelegramUpdate>;
1038
1043
  header: any;
1039
1044
  unauthorized: () => any;
1045
+ response: () => any;
1040
1046
  };
1041
1047
  "std/http": (req: any) => {
1042
1048
  update: any;
@@ -1050,6 +1056,12 @@ declare const frameworks: {
1050
1056
  response: () => Response;
1051
1057
  unauthorized: () => Response;
1052
1058
  };
1059
+ cloudflare: (req: any) => {
1060
+ update: any;
1061
+ header: any;
1062
+ response: () => Response;
1063
+ unauthorized: () => Response;
1064
+ };
1053
1065
  Request: (req: any) => {
1054
1066
  update: any;
1055
1067
  header: any;
@@ -1060,6 +1072,16 @@ declare const frameworks: {
1060
1072
 
1061
1073
  /** Union type of webhook handlers name */
1062
1074
  type WebhookHandlers = keyof typeof frameworks;
1075
+ interface WebhookHandlerOptionsShouldWait {
1076
+ /** Action to take when timeout occurs. @default "throw" */
1077
+ onTimeout?: "throw" | "return";
1078
+ /** Timeout in milliseconds. @default 10_000 */
1079
+ timeout?: number;
1080
+ }
1081
+ interface WebhookHandlerOptions {
1082
+ secretToken?: string;
1083
+ shouldWait?: boolean | WebhookHandlerOptionsShouldWait;
1084
+ }
1063
1085
  /**
1064
1086
  * Setup handler with yours web-framework to receive updates via webhook
1065
1087
  *
@@ -1088,8 +1110,8 @@ type WebhookHandlers = keyof typeof frameworks;
1088
1110
  * });
1089
1111
  * ```
1090
1112
  */
1091
- declare function webhookHandler<Framework extends keyof typeof frameworks>(bot: Bot, framework: Framework, secretToken?: string): ReturnType<(typeof frameworks)[Framework]> extends {
1113
+ declare function webhookHandler<Framework extends keyof typeof frameworks>(bot: Bot, framework: Framework, secretTokenOrOptions?: string | WebhookHandlerOptions): ReturnType<(typeof frameworks)[Framework]> extends {
1092
1114
  response: () => any;
1093
1115
  } ? (...args: Parameters<(typeof frameworks)[Framework]>) => ReturnType<ReturnType<(typeof frameworks)[Framework]>["response"]> : (...args: Parameters<(typeof frameworks)[Framework]>) => void;
1094
1116
 
1095
- export { type AllowedUpdates, type AnyBot, type AnyPlugin, Bot, type BotOptions, type BotStartOptions, type BotStartOptionsLongPolling, type BotStartOptionsWebhook, type CallbackQueryShorthandContext, Composer, type DeriveDefinitions, type ErrorDefinitions, ErrorKind, type FilterDefinitions, type Handler, Hooks, type MaybePromise, type MaybeSuppressedParams, type MaybeSuppressedReturn, Plugin, type PollingStartOptions, type Suppress, type SuppressedAPIMethodParams, type SuppressedAPIMethodReturn, type SuppressedAPIMethods, TelegramError, Updates, type WebhookHandlers, webhookHandler };
1117
+ export { type AllowedUpdates, type AnyBot, type AnyPlugin, Bot, type BotOptions, type BotStartOptions, type BotStartOptionsLongPolling, type BotStartOptionsWebhook, type CallbackQueryShorthandContext, Composer, type DeriveDefinitions, type ErrorDefinitions, ErrorKind, type FilterDefinitions, type Handler, Hooks, type MaybePromise, type MaybeSuppressedParams, type MaybeSuppressedReturn, Plugin, type PollingStartOptions, type Suppress, type SuppressedAPIMethodParams, type SuppressedAPIMethodReturn, type SuppressedAPIMethods, TelegramError, Updates, type WebhookHandlerOptions, type WebhookHandlerOptionsShouldWait, type WebhookHandlers, webhookHandler };
package/dist/index.d.ts CHANGED
@@ -2,7 +2,7 @@ import { CallbackData } from '@gramio/callback-data';
2
2
  export * from '@gramio/callback-data';
3
3
  import { Context, UpdateName, ContextType, BotLike, Attachment } from '@gramio/contexts';
4
4
  export * from '@gramio/contexts';
5
- import { APIMethods, TelegramResponseParameters, TelegramAPIResponseError, TelegramUser, APIMethodParams, APIMethodReturn, SetWebhookParams, TelegramUpdate, TelegramReactionTypeEmojiEmoji, SetMyCommandsParams, TelegramBotCommand } from '@gramio/types';
5
+ import { APIMethods, TelegramResponseParameters, TelegramAPIResponseError, TelegramUser, APIMethodParams, APIMethodReturn, SetWebhookParams, TelegramUpdate, TelegramReactionTypeEmojiEmoji } from '@gramio/types';
6
6
  export * from '@gramio/types';
7
7
  import * as middleware_io from 'middleware-io';
8
8
  import { Composer as Composer$1, Middleware, CaughtMiddlewareHandler, NextMiddleware } from 'middleware-io';
@@ -977,9 +977,9 @@ declare class Bot<Errors extends ErrorDefinitions = {}, Derives extends DeriveDe
977
977
  * return context.send(`You message is /start ${context.args}`);
978
978
  * });
979
979
  */
980
- command(command: string, handler: (context: ContextType<typeof this, "message"> & {
980
+ command(command: MaybeArray<string>, handler: (context: ContextType<typeof this, "message"> & {
981
981
  args: string | null;
982
- }) => unknown, options?: Omit<SetMyCommandsParams, "commands"> & Omit<TelegramBotCommand, "command">): this;
982
+ }) => unknown): this;
983
983
  /** Currently not isolated!!! */
984
984
  group(grouped: (bot: typeof this) => AnyBot): typeof this;
985
985
  /**
@@ -1012,31 +1012,37 @@ declare const frameworks: {
1012
1012
  update: any;
1013
1013
  header: any;
1014
1014
  unauthorized: () => Response;
1015
+ response: () => Response;
1015
1016
  };
1016
1017
  fastify: (request: any, reply: any) => {
1017
1018
  update: any;
1018
1019
  header: any;
1019
1020
  unauthorized: () => any;
1021
+ response: () => any;
1020
1022
  };
1021
1023
  hono: (c: any) => {
1022
1024
  update: any;
1023
1025
  header: any;
1024
1026
  unauthorized: () => any;
1027
+ response: () => Response;
1025
1028
  };
1026
1029
  express: (req: any, res: any) => {
1027
1030
  update: any;
1028
1031
  header: any;
1029
1032
  unauthorized: () => any;
1033
+ response: () => any;
1030
1034
  };
1031
1035
  koa: (ctx: any) => {
1032
1036
  update: any;
1033
1037
  header: any;
1034
1038
  unauthorized: () => void;
1039
+ response: () => void;
1035
1040
  };
1036
1041
  http: (req: any, res: any) => {
1037
1042
  update: Promise<TelegramUpdate>;
1038
1043
  header: any;
1039
1044
  unauthorized: () => any;
1045
+ response: () => any;
1040
1046
  };
1041
1047
  "std/http": (req: any) => {
1042
1048
  update: any;
@@ -1050,6 +1056,12 @@ declare const frameworks: {
1050
1056
  response: () => Response;
1051
1057
  unauthorized: () => Response;
1052
1058
  };
1059
+ cloudflare: (req: any) => {
1060
+ update: any;
1061
+ header: any;
1062
+ response: () => Response;
1063
+ unauthorized: () => Response;
1064
+ };
1053
1065
  Request: (req: any) => {
1054
1066
  update: any;
1055
1067
  header: any;
@@ -1060,6 +1072,16 @@ declare const frameworks: {
1060
1072
 
1061
1073
  /** Union type of webhook handlers name */
1062
1074
  type WebhookHandlers = keyof typeof frameworks;
1075
+ interface WebhookHandlerOptionsShouldWait {
1076
+ /** Action to take when timeout occurs. @default "throw" */
1077
+ onTimeout?: "throw" | "return";
1078
+ /** Timeout in milliseconds. @default 10_000 */
1079
+ timeout?: number;
1080
+ }
1081
+ interface WebhookHandlerOptions {
1082
+ secretToken?: string;
1083
+ shouldWait?: boolean | WebhookHandlerOptionsShouldWait;
1084
+ }
1063
1085
  /**
1064
1086
  * Setup handler with yours web-framework to receive updates via webhook
1065
1087
  *
@@ -1088,8 +1110,8 @@ type WebhookHandlers = keyof typeof frameworks;
1088
1110
  * });
1089
1111
  * ```
1090
1112
  */
1091
- declare function webhookHandler<Framework extends keyof typeof frameworks>(bot: Bot, framework: Framework, secretToken?: string): ReturnType<(typeof frameworks)[Framework]> extends {
1113
+ declare function webhookHandler<Framework extends keyof typeof frameworks>(bot: Bot, framework: Framework, secretTokenOrOptions?: string | WebhookHandlerOptions): ReturnType<(typeof frameworks)[Framework]> extends {
1092
1114
  response: () => any;
1093
1115
  } ? (...args: Parameters<(typeof frameworks)[Framework]>) => ReturnType<ReturnType<(typeof frameworks)[Framework]>["response"]> : (...args: Parameters<(typeof frameworks)[Framework]>) => void;
1094
1116
 
1095
- export { type AllowedUpdates, type AnyBot, type AnyPlugin, Bot, type BotOptions, type BotStartOptions, type BotStartOptionsLongPolling, type BotStartOptionsWebhook, type CallbackQueryShorthandContext, Composer, type DeriveDefinitions, type ErrorDefinitions, ErrorKind, type FilterDefinitions, type Handler, Hooks, type MaybePromise, type MaybeSuppressedParams, type MaybeSuppressedReturn, Plugin, type PollingStartOptions, type Suppress, type SuppressedAPIMethodParams, type SuppressedAPIMethodReturn, type SuppressedAPIMethods, TelegramError, Updates, type WebhookHandlers, webhookHandler };
1117
+ export { type AllowedUpdates, type AnyBot, type AnyPlugin, Bot, type BotOptions, type BotStartOptions, type BotStartOptionsLongPolling, type BotStartOptionsWebhook, type CallbackQueryShorthandContext, Composer, type DeriveDefinitions, type ErrorDefinitions, ErrorKind, type FilterDefinitions, type Handler, Hooks, type MaybePromise, type MaybeSuppressedParams, type MaybeSuppressedReturn, Plugin, type PollingStartOptions, type Suppress, type SuppressedAPIMethodParams, type SuppressedAPIMethodReturn, type SuppressedAPIMethods, TelegramError, Updates, type WebhookHandlerOptions, type WebhookHandlerOptionsShouldWait, type WebhookHandlers, webhookHandler };
package/dist/index.js CHANGED
@@ -9,7 +9,7 @@ export * from '@gramio/files';
9
9
  import { FormattableMap } from '@gramio/format';
10
10
  export * from '@gramio/format';
11
11
  import debug from 'debug';
12
- import { E as ErrorKind, s as sleep, w as withRetries, T as TelegramError, d as debug$updates, I as IS_BUN, a as simplifyObject } from './utils-CJlBu70R.js';
12
+ import { E as ErrorKind, s as sleep, w as withRetries, T as TelegramError, d as debug$updates, I as IS_BUN, a as simplifyObject, t as timeoutWebhook } from './utils-CJfJNxc_.js';
13
13
  import { Composer as Composer$1, noopNext } from 'middleware-io';
14
14
  export * from '@gramio/keyboards';
15
15
 
@@ -1004,15 +1004,23 @@ class Bot {
1004
1004
  * return context.send(`You message is /start ${context.args}`);
1005
1005
  * });
1006
1006
  */
1007
- command(command, handler, options) {
1008
- if (command.startsWith("/"))
1009
- throw new Error("Do not use / in command name");
1007
+ command(command, handler) {
1008
+ const normalizedCommands = typeof command === "string" ? [command] : Array.from(command);
1009
+ for (const cmd of normalizedCommands) {
1010
+ if (cmd.startsWith("/"))
1011
+ throw new Error(`Do not use / in command name (${cmd})`);
1012
+ }
1010
1013
  return this.on(["message", "business_message"], (context, next) => {
1011
1014
  if (context.entities?.some((entity) => {
1012
1015
  if (entity.type !== "bot_command" || entity.offset > 0) return false;
1013
- const cmd = context.text?.slice(1, entity.length)?.replace(`@${this.info.username}`, "");
1016
+ const cmd = context.text?.slice(1, entity.length)?.replace(
1017
+ this.info?.username ? `@${this.info.username}` : /@[a-zA-Z0-9_]+/,
1018
+ ""
1019
+ );
1014
1020
  context.args = context.text?.slice(entity.length).trim() || null;
1015
- return cmd === command;
1021
+ return normalizedCommands.some(
1022
+ (normalizedCommand) => cmd === normalizedCommand
1023
+ );
1016
1024
  }))
1017
1025
  return handler(context);
1018
1026
  return next();
@@ -1127,8 +1135,9 @@ class Bot {
1127
1135
 
1128
1136
  const SECRET_TOKEN_HEADER = "X-Telegram-Bot-Api-Secret-Token";
1129
1137
  const WRONG_TOKEN_ERROR = "secret token is invalid";
1130
- const responseOK = new Response("ok!");
1131
- const responseUnauthorized = new Response(WRONG_TOKEN_ERROR, {
1138
+ const RESPONSE_OK = "ok!";
1139
+ const responseOK = () => new Response(RESPONSE_OK);
1140
+ const responseUnauthorized = () => new Response(WRONG_TOKEN_ERROR, {
1132
1141
  status: 401
1133
1142
  // @ts-ignore
1134
1143
  });
@@ -1136,22 +1145,26 @@ const frameworks = {
1136
1145
  elysia: ({ body, headers }) => ({
1137
1146
  update: body,
1138
1147
  header: headers[SECRET_TOKEN_HEADER],
1139
- unauthorized: () => responseUnauthorized
1148
+ unauthorized: responseUnauthorized,
1149
+ response: responseOK
1140
1150
  }),
1141
1151
  fastify: (request, reply) => ({
1142
1152
  update: request.body,
1143
1153
  header: request.headers[SECRET_TOKEN_HEADER],
1144
- unauthorized: () => reply.code(401).send(WRONG_TOKEN_ERROR)
1154
+ unauthorized: () => reply.code(401).send(WRONG_TOKEN_ERROR),
1155
+ response: () => reply.send(RESPONSE_OK)
1145
1156
  }),
1146
1157
  hono: (c) => ({
1147
1158
  update: c.req.json(),
1148
1159
  header: c.req.header(SECRET_TOKEN_HEADER),
1149
- unauthorized: () => c.text(WRONG_TOKEN_ERROR, 401)
1160
+ unauthorized: () => c.text(WRONG_TOKEN_ERROR, 401),
1161
+ response: responseOK
1150
1162
  }),
1151
1163
  express: (req, res) => ({
1152
1164
  update: req.body,
1153
1165
  header: req.header(SECRET_TOKEN_HEADER),
1154
- unauthorized: () => res.status(401).send(WRONG_TOKEN_ERROR)
1166
+ unauthorized: () => res.status(401).send(WRONG_TOKEN_ERROR),
1167
+ response: () => res.send(RESPONSE_OK)
1155
1168
  }),
1156
1169
  koa: (ctx) => ({
1157
1170
  update: ctx.request.body,
@@ -1159,6 +1172,10 @@ const frameworks = {
1159
1172
  unauthorized: () => {
1160
1173
  ctx.status === 401;
1161
1174
  ctx.body = WRONG_TOKEN_ERROR;
1175
+ },
1176
+ response: () => {
1177
+ ctx.status = 200;
1178
+ ctx.body = RESPONSE_OK;
1162
1179
  }
1163
1180
  }),
1164
1181
  http: (req, res) => ({
@@ -1170,38 +1187,59 @@ const frameworks = {
1170
1187
  req.on("end", () => resolve(JSON.parse(body)));
1171
1188
  }),
1172
1189
  header: req.headers[SECRET_TOKEN_HEADER.toLowerCase()],
1173
- unauthorized: () => res.writeHead(401).end(WRONG_TOKEN_ERROR)
1190
+ unauthorized: () => res.writeHead(401).end(WRONG_TOKEN_ERROR),
1191
+ response: () => res.writeHead(200).end(RESPONSE_OK)
1174
1192
  }),
1175
- // TODO: Maybe unify it by 'WebRequest'
1176
1193
  "std/http": (req) => ({
1177
1194
  update: req.json(),
1178
1195
  header: req.headers.get(SECRET_TOKEN_HEADER),
1179
- response: () => responseOK,
1180
- unauthorized: () => responseUnauthorized
1196
+ response: responseOK,
1197
+ unauthorized: responseUnauthorized
1181
1198
  }),
1182
1199
  "Bun.serve": (req) => ({
1183
1200
  update: req.json(),
1184
1201
  header: req.headers.get(SECRET_TOKEN_HEADER),
1185
- response: () => responseOK,
1186
- unauthorized: () => responseUnauthorized
1202
+ response: responseOK,
1203
+ unauthorized: responseUnauthorized
1204
+ }),
1205
+ cloudflare: (req) => ({
1206
+ update: req.json(),
1207
+ header: req.headers.get(SECRET_TOKEN_HEADER),
1208
+ response: responseOK,
1209
+ unauthorized: responseUnauthorized
1187
1210
  }),
1188
1211
  Request: (req) => ({
1189
1212
  update: req.json(),
1190
1213
  header: req.headers.get(SECRET_TOKEN_HEADER),
1191
- response: () => responseOK,
1192
- unauthorized: () => responseUnauthorized
1214
+ response: responseOK,
1215
+ unauthorized: responseUnauthorized
1193
1216
  })
1194
1217
  };
1195
1218
 
1196
- function webhookHandler(bot, framework, secretToken) {
1219
+ function webhookHandler(bot, framework, secretTokenOrOptions) {
1197
1220
  const frameworkAdapter = frameworks[framework];
1221
+ const secretToken = typeof secretTokenOrOptions === "string" ? secretTokenOrOptions : secretTokenOrOptions?.secretToken;
1222
+ const shouldWaitOptions = typeof secretTokenOrOptions === "string" ? false : secretTokenOrOptions?.shouldWait;
1223
+ const isShouldWait = shouldWaitOptions && (typeof shouldWaitOptions === "object" || typeof shouldWaitOptions === "boolean");
1198
1224
  return async (...args) => {
1199
1225
  const { update, response, header, unauthorized } = frameworkAdapter(
1200
1226
  ...args
1201
1227
  );
1202
1228
  if (secretToken && header !== secretToken) return unauthorized();
1203
- bot.updates.queue.add(await update);
1204
- if (response) return response();
1229
+ if (!isShouldWait) {
1230
+ bot.updates.queue.add(await update);
1231
+ if (response) return response();
1232
+ } else {
1233
+ const timeoutOptions = typeof shouldWaitOptions === "object" ? shouldWaitOptions : void 0;
1234
+ const timeout = timeoutOptions?.timeout ?? 3e4;
1235
+ const onTimeout = timeoutOptions?.onTimeout ?? "throw";
1236
+ await timeoutWebhook(
1237
+ bot.updates.handleUpdate(await update, "wait"),
1238
+ timeout,
1239
+ onTimeout
1240
+ );
1241
+ if (response) return response();
1242
+ }
1205
1243
  };
1206
1244
  }
1207
1245
 
@@ -42,6 +42,20 @@ function simplifyObject(obj) {
42
42
  const IS_BUN = typeof Bun !== "undefined";
43
43
  debug("gramio:api");
44
44
  const debug$updates = debug("gramio:updates");
45
+ function timeoutWebhook(task, timeout, mode) {
46
+ return new Promise((resolve, reject) => {
47
+ const timeoutTask = setTimeout(() => {
48
+ if (mode === "throw") {
49
+ reject(
50
+ new Error(`Webhook handler execution timed out after ${timeout}ms`)
51
+ );
52
+ } else {
53
+ resolve(void 0);
54
+ }
55
+ }, timeout);
56
+ task.then(resolve).catch(reject).finally(() => clearTimeout(timeoutTask));
57
+ });
58
+ }
45
59
 
46
60
  async function suppressError(fn) {
47
61
  try {
@@ -66,4 +80,4 @@ async function withRetries(resultPromise) {
66
80
  return result;
67
81
  }
68
82
 
69
- export { ErrorKind as E, IS_BUN as I, TelegramError as T, simplifyObject as a, debug$updates as d, sleep as s, withRetries as w };
83
+ export { ErrorKind as E, IS_BUN as I, TelegramError as T, simplifyObject as a, debug$updates as d, sleep as s, timeoutWebhook as t, withRetries as w };
@@ -44,6 +44,20 @@ function simplifyObject(obj) {
44
44
  const IS_BUN = typeof Bun !== "undefined";
45
45
  debug("gramio:api");
46
46
  const debug$updates = debug("gramio:updates");
47
+ function timeoutWebhook(task, timeout, mode) {
48
+ return new Promise((resolve, reject) => {
49
+ const timeoutTask = setTimeout(() => {
50
+ if (mode === "throw") {
51
+ reject(
52
+ new Error(`Webhook handler execution timed out after ${timeout}ms`)
53
+ );
54
+ } else {
55
+ resolve(void 0);
56
+ }
57
+ }, timeout);
58
+ task.then(resolve).catch(reject).finally(() => clearTimeout(timeoutTask));
59
+ });
60
+ }
47
61
 
48
62
  async function suppressError(fn) {
49
63
  try {
@@ -74,4 +88,5 @@ exports.TelegramError = TelegramError;
74
88
  exports.debug$updates = debug$updates;
75
89
  exports.simplifyObject = simplifyObject;
76
90
  exports.sleep = sleep;
91
+ exports.timeoutWebhook = timeoutWebhook;
77
92
  exports.withRetries = withRetries;
package/dist/utils.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var utils = require('./utils-CnG66NLH.cjs');
3
+ var utils = require('./utils-CYIya32k.cjs');
4
4
  require('debug');
5
5
 
6
6
 
package/dist/utils.js CHANGED
@@ -1,2 +1,2 @@
1
- export { w as withRetries } from './utils-CJlBu70R.js';
1
+ export { w as withRetries } from './utils-CJfJNxc_.js';
2
2
  import 'debug';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "gramio",
3
3
  "type": "module",
4
- "version": "0.4.4",
4
+ "version": "0.4.7",
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",
@@ -56,20 +56,20 @@
56
56
  "license": "MIT",
57
57
  "devDependencies": {
58
58
  "@biomejs/biome": "1.9.4",
59
- "@types/bun": "^1.2.10",
59
+ "@types/bun": "^1.2.14",
60
60
  "@types/debug": "^4.1.12",
61
61
  "expect-type": "^1.2.1",
62
- "pkgroll": "^2.12.1",
62
+ "pkgroll": "^2.12.2",
63
63
  "typescript": "^5.8.3"
64
64
  },
65
65
  "dependencies": {
66
66
  "@gramio/callback-data": "^0.0.3",
67
67
  "@gramio/contexts": "^0.2.5",
68
68
  "@gramio/files": "^0.3.0",
69
- "@gramio/format": "^0.2.0",
69
+ "@gramio/format": "^0.2.1",
70
70
  "@gramio/keyboards": "^1.2.1",
71
71
  "@gramio/types": "^9.0.2",
72
- "debug": "^4.4.0",
72
+ "debug": "^4.4.1",
73
73
  "middleware-io": "^2.8.1"
74
74
  },
75
75
  "files": ["dist"]