grammy 1.6.2 → 1.7.2
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/README.md +5 -3
- package/out/bot.d.ts +37 -9
- package/out/bot.js +133 -147
- package/out/composer.d.ts +2 -2
- package/out/composer.js +2 -18
- package/out/context.d.ts +5 -5
- package/out/context.js +5 -30
- package/out/convenience/frameworks.node.d.ts +6 -5
- package/out/convenience/keyboard.d.ts +1 -1
- package/out/convenience/keyboard.js +2 -12
- package/out/convenience/session.d.ts +2 -2
- package/out/convenience/session.js +2 -12
- package/out/convenience/webhook.d.ts +11 -7
- package/out/core/api.d.ts +9 -9
- package/out/core/api.js +5 -31
- package/out/core/client.d.ts +21 -2
- package/out/core/client.js +78 -94
- package/out/core/error.d.ts +3 -1
- package/out/core/error.js +26 -46
- package/out/filter.d.ts +36 -19
- package/out/mod.d.ts +4 -7
- package/out/mod.js +5 -1
- package/out/platform.node.d.ts +2 -2
- package/out/platform.node.js +6 -26
- package/out/shim.node.d.ts +1 -1
- package/out/shim.node.js +1 -2
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -10,9 +10,9 @@ _<h2 align="center"> [:mag: Documentation](https://grammy.dev) | [:page_with_cur
|
|
|
10
10
|
|
|
11
11
|
<!-- deno-fmt-ignore-start -->
|
|
12
12
|
|
|
13
|
-
[](https://core.telegram.org/bots/api)
|
|
14
14
|
[](https://www.npmjs.org/package/grammy) <!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
|
|
15
|
-
[](#contributors-)
|
|
16
16
|
<!-- ALL-CONTRIBUTORS-BADGE:END -->
|
|
17
17
|
|
|
18
18
|
<!-- deno-fmt-ignore-end -->
|
|
@@ -176,7 +176,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
|
|
|
176
176
|
<tr>
|
|
177
177
|
<td align="center"><a href="https://github.com/taotie111"><img src="https://avatars.githubusercontent.com/u/44166322?v=4?s=100" width="100px;" alt=""/><br /><sub><b>taotie111</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/commits?author=taotie111" title="Documentation">📖</a> <a href="#translation-taotie111" title="Translation">🌍</a></td>
|
|
178
178
|
<td align="center"><a href="https://www.linkedin.com/in/merlin-brandes-42328717a/"><img src="https://avatars.githubusercontent.com/u/14237330?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Merlin</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/commits?author=FatalMerlin" title="Documentation">📖</a></td>
|
|
179
|
-
<td align="center"><a href="https://darve.sh"><img src="https://avatars.githubusercontent.com/u/22394081?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Darvesh</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/issues?q=author%3Adarvesh" title="Bug reports">🐛</a> <a href="https://github.com/grammyjs/grammY/commits?author=darvesh" title="Code">💻</a></td>
|
|
179
|
+
<td align="center"><a href="https://darve.sh"><img src="https://avatars.githubusercontent.com/u/22394081?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Darvesh</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/issues?q=author%3Adarvesh" title="Bug reports">🐛</a> <a href="https://github.com/grammyjs/grammY/commits?author=darvesh" title="Code">💻</a> <a href="https://github.com/grammyjs/grammY/pulls?q=is%3Apr+reviewed-by%3Adarvesh" title="Reviewed Pull Requests">👀</a></td>
|
|
180
180
|
<td align="center"><a href="http://telegram.me/dcdunkan"><img src="https://avatars.githubusercontent.com/u/70066170?v=4?s=100" width="100px;" alt=""/><br /><sub><b>dcdunkan</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/issues?q=author%3Adcdunkan" title="Bug reports">🐛</a> <a href="https://github.com/grammyjs/grammY/commits?author=dcdunkan" title="Code">💻</a> <a href="#plugin-dcdunkan" title="Plugin/utility libraries">🔌</a> <a href="https://github.com/grammyjs/grammY/pulls?q=is%3Apr+reviewed-by%3Adcdunkan" title="Reviewed Pull Requests">👀</a> <a href="https://github.com/grammyjs/grammY/commits?author=dcdunkan" title="Documentation">📖</a></td>
|
|
181
181
|
<td align="center"><a href="https://xuann.wang/"><img src="https://avatars.githubusercontent.com/u/44045911?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Kid</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/commits?author=kidonng" title="Documentation">📖</a> <a href="#translation-kidonng" title="Translation">🌍</a></td>
|
|
182
182
|
<td align="center"><a href="http://slava.fomin.io/"><img src="https://avatars.githubusercontent.com/u/1702725?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Slava Fomin II</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/issues?q=author%3Aslavafomin" title="Bug reports">🐛</a> <a href="https://github.com/grammyjs/grammY/commits?author=slavafomin" title="Documentation">📖</a></td>
|
|
@@ -193,6 +193,8 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
|
|
|
193
193
|
</tr>
|
|
194
194
|
<tr>
|
|
195
195
|
<td align="center"><a href="https://github.com/abdollahzadehAli"><img src="https://avatars.githubusercontent.com/u/96317431?v=4?s=100" width="100px;" alt=""/><br /><sub><b>abdollahzadehAli</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/commits?author=abdollahzadehAli" title="Documentation">📖</a> <a href="#example-abdollahzadehAli" title="Examples">💡</a></td>
|
|
196
|
+
<td align="center"><a href="https://github.com/MrSaeedNasiri"><img src="https://avatars.githubusercontent.com/u/17780289?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Saeed Nasiri</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/commits?author=MrSaeedNasiri" title="Documentation">📖</a></td>
|
|
197
|
+
<td align="center"><a href="https://github.com/Scrip7"><img src="https://avatars.githubusercontent.com/u/37535505?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Hesoyam</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/commits?author=Scrip7" title="Documentation">📖</a></td>
|
|
196
198
|
</tr>
|
|
197
199
|
</table>
|
|
198
200
|
|
package/out/bot.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { BotError, Composer } from "./composer.js";
|
|
2
2
|
import { Context } from "./context.js";
|
|
3
3
|
import { Api } from "./core/api.js";
|
|
4
|
-
import { ApiClientOptions, WebhookReplyEnvelope } from "./core/client.js";
|
|
5
|
-
import { Update, UserFromGetMe } from "./platform.node.js";
|
|
4
|
+
import { type ApiClientOptions, type WebhookReplyEnvelope } from "./core/client.js";
|
|
5
|
+
import { type Update, type UserFromGetMe } from "./platform.node.js";
|
|
6
6
|
/**
|
|
7
7
|
* Options that can be specified when running the bot via simple long polling.
|
|
8
8
|
*/
|
|
@@ -35,13 +35,14 @@ export interface PollingOptions {
|
|
|
35
35
|
*/
|
|
36
36
|
drop_pending_updates?: boolean;
|
|
37
37
|
/**
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
* function
|
|
38
|
+
* A callback function that is useful for logging (or setting up middleware
|
|
39
|
+
* if you did not do this before). It will be executed after the setup of
|
|
40
|
+
* the bot has completed, and immediately before the first updates are being
|
|
41
|
+
* fetched. The bot information `bot.botInfo` will be available when the
|
|
42
|
+
* function is run. For convenience, the callback function receives the
|
|
43
|
+
* value of `bot.botInfo` as an argument.
|
|
43
44
|
*/
|
|
44
|
-
onStart?: (botInfo: UserFromGetMe) => void
|
|
45
|
+
onStart?: (botInfo: UserFromGetMe) => void | Promise<void>;
|
|
45
46
|
}
|
|
46
47
|
export { BotError };
|
|
47
48
|
/**
|
|
@@ -50,7 +51,7 @@ export { BotError };
|
|
|
50
51
|
*/
|
|
51
52
|
export declare type ErrorHandler<C extends Context = Context> = (error: BotError<C>) => unknown;
|
|
52
53
|
/**
|
|
53
|
-
* Options to pass the bot when creating it.
|
|
54
|
+
* Options to pass to the bot when creating it.
|
|
54
55
|
*/
|
|
55
56
|
export interface BotConfig<C extends Context> {
|
|
56
57
|
/**
|
|
@@ -169,6 +170,14 @@ export declare class Bot<C extends Context = Context, A extends Api = Api> exten
|
|
|
169
170
|
* manually.
|
|
170
171
|
*/
|
|
171
172
|
init(): Promise<void>;
|
|
173
|
+
/**
|
|
174
|
+
* Internal. Do not call. Handles an update batch sequentially by supplying
|
|
175
|
+
* it one-by-one to the middleware. Handles middleware errors and stores the
|
|
176
|
+
* last update identifier that was being tried to handle.
|
|
177
|
+
*
|
|
178
|
+
* @param updates An array of updates to handle
|
|
179
|
+
*/
|
|
180
|
+
private handleUpdates;
|
|
172
181
|
/**
|
|
173
182
|
* This is an internal method that you probably will not ever need to call.
|
|
174
183
|
* It is used whenever a new update arrives from the Telegram servers that
|
|
@@ -249,4 +258,23 @@ export declare class Bot<C extends Context = Context, A extends Api = Api> exten
|
|
|
249
258
|
* @param errorHandler A function that handles potential middleware errors
|
|
250
259
|
*/
|
|
251
260
|
catch(errorHandler: ErrorHandler<C>): void;
|
|
261
|
+
/**
|
|
262
|
+
* Internal. Do not call. Enters a loop that will perform long polling until
|
|
263
|
+
* the bot is stopped.
|
|
264
|
+
*/
|
|
265
|
+
private loop;
|
|
266
|
+
/**
|
|
267
|
+
* Internal. Do not call. Reliably fetches an update batch via `getUpdates`.
|
|
268
|
+
* Handles all known errors. Returns `undefined` if the bot is stopped and
|
|
269
|
+
* the call gets cancelled.
|
|
270
|
+
*
|
|
271
|
+
* @param options Polling options
|
|
272
|
+
* @returns An array of updates, or `undefined` if the bot is stopped.
|
|
273
|
+
*/
|
|
274
|
+
private fetchUpdates;
|
|
275
|
+
/**
|
|
276
|
+
* Internal. Do not call. Handles an error that occurred during long
|
|
277
|
+
* polling.
|
|
278
|
+
*/
|
|
279
|
+
private handlePollingError;
|
|
252
280
|
}
|
package/out/bot.js
CHANGED
|
@@ -50,85 +50,25 @@ class Bot extends composer_js_1.Composer {
|
|
|
50
50
|
constructor(token, config) {
|
|
51
51
|
var _a;
|
|
52
52
|
super();
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
writable: true,
|
|
57
|
-
value: token
|
|
58
|
-
});
|
|
59
|
-
Object.defineProperty(this, "pollingRunning", {
|
|
60
|
-
enumerable: true,
|
|
61
|
-
configurable: true,
|
|
62
|
-
writable: true,
|
|
63
|
-
value: false
|
|
64
|
-
});
|
|
65
|
-
Object.defineProperty(this, "pollingAbortController", {
|
|
66
|
-
enumerable: true,
|
|
67
|
-
configurable: true,
|
|
68
|
-
writable: true,
|
|
69
|
-
value: void 0
|
|
70
|
-
});
|
|
71
|
-
Object.defineProperty(this, "lastTriedUpdateId", {
|
|
72
|
-
enumerable: true,
|
|
73
|
-
configurable: true,
|
|
74
|
-
writable: true,
|
|
75
|
-
value: 0
|
|
76
|
-
});
|
|
77
|
-
/**
|
|
78
|
-
* Gives you full access to the Telegram Bot API.
|
|
79
|
-
* ```ts
|
|
80
|
-
* // This is how to call the Bot API methods:
|
|
81
|
-
* bot.api.sendMessage(chat_id, 'Hello, grammY!')
|
|
82
|
-
* ```
|
|
83
|
-
*
|
|
84
|
-
* Use this only outside of your middleware. If you have access to `ctx`,
|
|
85
|
-
* then using `ctx.api` instead of `bot.api` is preferred.
|
|
86
|
-
*/
|
|
87
|
-
Object.defineProperty(this, "api", {
|
|
88
|
-
enumerable: true,
|
|
89
|
-
configurable: true,
|
|
90
|
-
writable: true,
|
|
91
|
-
value: void 0
|
|
92
|
-
});
|
|
93
|
-
Object.defineProperty(this, "me", {
|
|
94
|
-
enumerable: true,
|
|
95
|
-
configurable: true,
|
|
96
|
-
writable: true,
|
|
97
|
-
value: void 0
|
|
98
|
-
});
|
|
99
|
-
Object.defineProperty(this, "clientConfig", {
|
|
100
|
-
enumerable: true,
|
|
101
|
-
configurable: true,
|
|
102
|
-
writable: true,
|
|
103
|
-
value: void 0
|
|
104
|
-
});
|
|
105
|
-
Object.defineProperty(this, "ContextConstructor", {
|
|
106
|
-
enumerable: true,
|
|
107
|
-
configurable: true,
|
|
108
|
-
writable: true,
|
|
109
|
-
value: void 0
|
|
110
|
-
});
|
|
53
|
+
this.token = token;
|
|
54
|
+
this.pollingRunning = false;
|
|
55
|
+
this.lastTriedUpdateId = 0;
|
|
111
56
|
/**
|
|
112
57
|
* Holds the bot's error handler that is invoked whenever middleware throws
|
|
113
58
|
* (rejects). If you set your own error handler via `bot.catch`, all that
|
|
114
59
|
* happens is that this variable is assigned.
|
|
115
60
|
*/
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
console.error("
|
|
123
|
-
|
|
124
|
-
console.error("Set your own error handler with `bot.catch = ...`");
|
|
125
|
-
if (this.pollingRunning) {
|
|
126
|
-
console.error("Stopping bot");
|
|
127
|
-
await this.stop();
|
|
128
|
-
}
|
|
129
|
-
throw err;
|
|
61
|
+
this.errorHandler = async (err) => {
|
|
62
|
+
var _a, _b;
|
|
63
|
+
console.error("Error in middleware while handling update", (_b = (_a = err.ctx) === null || _a === void 0 ? void 0 : _a.update) === null || _b === void 0 ? void 0 : _b.update_id, err.error);
|
|
64
|
+
console.error("No error handler was set!");
|
|
65
|
+
console.error("Set your own error handler with `bot.catch = ...`");
|
|
66
|
+
if (this.pollingRunning) {
|
|
67
|
+
console.error("Stopping bot");
|
|
68
|
+
await this.stop();
|
|
130
69
|
}
|
|
131
|
-
|
|
70
|
+
throw err;
|
|
71
|
+
};
|
|
132
72
|
if (!token)
|
|
133
73
|
throw new Error("Empty token!");
|
|
134
74
|
this.me = config === null || config === void 0 ? void 0 : config.botInfo;
|
|
@@ -185,6 +125,32 @@ class Bot extends composer_js_1.Composer {
|
|
|
185
125
|
}
|
|
186
126
|
debug(`I am ${this.me.username}!`);
|
|
187
127
|
}
|
|
128
|
+
/**
|
|
129
|
+
* Internal. Do not call. Handles an update batch sequentially by supplying
|
|
130
|
+
* it one-by-one to the middleware. Handles middleware errors and stores the
|
|
131
|
+
* last update identifier that was being tried to handle.
|
|
132
|
+
*
|
|
133
|
+
* @param updates An array of updates to handle
|
|
134
|
+
*/
|
|
135
|
+
async handleUpdates(updates) {
|
|
136
|
+
// handle updates sequentially (!)
|
|
137
|
+
for (const update of updates) {
|
|
138
|
+
this.lastTriedUpdateId = update.update_id;
|
|
139
|
+
try {
|
|
140
|
+
await this.handleUpdate(update);
|
|
141
|
+
}
|
|
142
|
+
catch (err) {
|
|
143
|
+
// should always be true
|
|
144
|
+
if (err instanceof composer_js_1.BotError) {
|
|
145
|
+
await this.errorHandler(err);
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
console.error("FATAL: grammY unable to handle:", err);
|
|
149
|
+
throw err;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
188
154
|
/**
|
|
189
155
|
* This is an internal method that you probably will not ever need to call.
|
|
190
156
|
* It is used whenever a new update arrives from the Telegram servers that
|
|
@@ -256,7 +222,7 @@ a known bot info object.");
|
|
|
256
222
|
* @param options Options to use for simple long polling
|
|
257
223
|
*/
|
|
258
224
|
async start(options) {
|
|
259
|
-
var _a
|
|
225
|
+
var _a;
|
|
260
226
|
// Perform setup
|
|
261
227
|
if (!this.isInited())
|
|
262
228
|
await withRetries(() => this.init());
|
|
@@ -267,6 +233,8 @@ a known bot info object.");
|
|
|
267
233
|
await withRetries(() => this.api.deleteWebhook({
|
|
268
234
|
drop_pending_updates: options === null || options === void 0 ? void 0 : options.drop_pending_updates,
|
|
269
235
|
}));
|
|
236
|
+
// All async ops of setup complete, run callback
|
|
237
|
+
await ((_a = options === null || options === void 0 ? void 0 : options.onStart) === null || _a === void 0 ? void 0 : _a.call(options, this.botInfo));
|
|
270
238
|
// Prevent common misuse that causes memory leak
|
|
271
239
|
this.use = () => {
|
|
272
240
|
throw new Error(`It looks like you are registering more listeners \
|
|
@@ -283,76 +251,7 @@ you can circumvent this protection against memory leaks.`);
|
|
|
283
251
|
};
|
|
284
252
|
// Start polling
|
|
285
253
|
debug("Starting simple long polling");
|
|
286
|
-
this.
|
|
287
|
-
this.pollingAbortController = new shim_node_js_1.AbortController();
|
|
288
|
-
const limit = options === null || options === void 0 ? void 0 : options.limit;
|
|
289
|
-
const timeout = (_a = options === null || options === void 0 ? void 0 : options.timeout) !== null && _a !== void 0 ? _a : 30; // seconds
|
|
290
|
-
let allowed_updates = options === null || options === void 0 ? void 0 : options.allowed_updates;
|
|
291
|
-
try {
|
|
292
|
-
(_b = options === null || options === void 0 ? void 0 : options.onStart) === null || _b === void 0 ? void 0 : _b.call(options, this.botInfo);
|
|
293
|
-
}
|
|
294
|
-
catch (error) {
|
|
295
|
-
this.pollingRunning = false;
|
|
296
|
-
this.pollingAbortController = undefined;
|
|
297
|
-
throw error;
|
|
298
|
-
}
|
|
299
|
-
const handleErr = async (error) => {
|
|
300
|
-
if (!this.pollingRunning)
|
|
301
|
-
throw error;
|
|
302
|
-
else if (error instanceof error_js_1.GrammyError) {
|
|
303
|
-
debugErr(error.message);
|
|
304
|
-
if (error.error_code === 401) {
|
|
305
|
-
debugErr("Make sure you are using the bot token you obtained from @BotFather (https://t.me/BotFather).");
|
|
306
|
-
throw error;
|
|
307
|
-
}
|
|
308
|
-
else if (error.error_code === 409) {
|
|
309
|
-
debugErr("Consider revoking the bot token if you believe that no other instance is running.");
|
|
310
|
-
throw error;
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
else
|
|
314
|
-
debugErr(error);
|
|
315
|
-
debugErr("Call to getUpdates failed, retrying in 3 seconds ...");
|
|
316
|
-
await new Promise((r) => setTimeout(r, 3000));
|
|
317
|
-
};
|
|
318
|
-
while (this.pollingRunning) {
|
|
319
|
-
// fetch updates
|
|
320
|
-
const offset = this.lastTriedUpdateId + 1;
|
|
321
|
-
let updates = undefined;
|
|
322
|
-
do {
|
|
323
|
-
try {
|
|
324
|
-
updates = await this.api.getUpdates({ offset, limit, timeout, allowed_updates }, this.pollingAbortController.signal);
|
|
325
|
-
}
|
|
326
|
-
catch (error) {
|
|
327
|
-
if (this.pollingRunning)
|
|
328
|
-
await handleErr(error);
|
|
329
|
-
else
|
|
330
|
-
debug("Pending getUpdates request cancelled");
|
|
331
|
-
}
|
|
332
|
-
} while (updates === undefined && this.pollingRunning);
|
|
333
|
-
if (updates === undefined)
|
|
334
|
-
break;
|
|
335
|
-
// handle them sequentially (!)
|
|
336
|
-
for (const update of updates) {
|
|
337
|
-
this.lastTriedUpdateId = update.update_id;
|
|
338
|
-
try {
|
|
339
|
-
await this.handleUpdate(update);
|
|
340
|
-
}
|
|
341
|
-
catch (err) {
|
|
342
|
-
// should always be true
|
|
343
|
-
if (err instanceof composer_js_1.BotError) {
|
|
344
|
-
await this.errorHandler(err);
|
|
345
|
-
}
|
|
346
|
-
else {
|
|
347
|
-
console.error("FATAL: grammY unable to handle:", err);
|
|
348
|
-
throw err;
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
// Telegram uses the last setting if `allowed_updates` is omitted so
|
|
353
|
-
// we can save same traffic by only sending it in the first request
|
|
354
|
-
allowed_updates = undefined;
|
|
355
|
-
}
|
|
254
|
+
await this.loop(options);
|
|
356
255
|
debug("Middleware is done running");
|
|
357
256
|
}
|
|
358
257
|
/**
|
|
@@ -402,8 +301,90 @@ you can circumvent this protection against memory leaks.`);
|
|
|
402
301
|
catch(errorHandler) {
|
|
403
302
|
this.errorHandler = errorHandler;
|
|
404
303
|
}
|
|
304
|
+
/**
|
|
305
|
+
* Internal. Do not call. Enters a loop that will perform long polling until
|
|
306
|
+
* the bot is stopped.
|
|
307
|
+
*/
|
|
308
|
+
async loop(options) {
|
|
309
|
+
var _a;
|
|
310
|
+
this.pollingRunning = true;
|
|
311
|
+
this.pollingAbortController = new shim_node_js_1.AbortController();
|
|
312
|
+
const limit = options === null || options === void 0 ? void 0 : options.limit;
|
|
313
|
+
const timeout = (_a = options === null || options === void 0 ? void 0 : options.timeout) !== null && _a !== void 0 ? _a : 30; // seconds
|
|
314
|
+
let allowed_updates = options === null || options === void 0 ? void 0 : options.allowed_updates;
|
|
315
|
+
while (this.pollingRunning) {
|
|
316
|
+
// fetch updates
|
|
317
|
+
const updates = await this.fetchUpdates({ limit, timeout, allowed_updates });
|
|
318
|
+
// check if polling stopped
|
|
319
|
+
if (updates === undefined)
|
|
320
|
+
break;
|
|
321
|
+
// handle updates
|
|
322
|
+
await this.handleUpdates(updates);
|
|
323
|
+
// Telegram uses the last setting if `allowed_updates` is omitted so
|
|
324
|
+
// we can save same traffic by only sending it in the first request
|
|
325
|
+
allowed_updates = undefined;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* Internal. Do not call. Reliably fetches an update batch via `getUpdates`.
|
|
330
|
+
* Handles all known errors. Returns `undefined` if the bot is stopped and
|
|
331
|
+
* the call gets cancelled.
|
|
332
|
+
*
|
|
333
|
+
* @param options Polling options
|
|
334
|
+
* @returns An array of updates, or `undefined` if the bot is stopped.
|
|
335
|
+
*/
|
|
336
|
+
async fetchUpdates({ limit, timeout, allowed_updates }) {
|
|
337
|
+
var _a;
|
|
338
|
+
const offset = this.lastTriedUpdateId + 1;
|
|
339
|
+
let updates = undefined;
|
|
340
|
+
do {
|
|
341
|
+
try {
|
|
342
|
+
updates = await this.api.getUpdates({ offset, limit, timeout, allowed_updates }, (_a = this.pollingAbortController) === null || _a === void 0 ? void 0 : _a.signal);
|
|
343
|
+
}
|
|
344
|
+
catch (error) {
|
|
345
|
+
await this.handlePollingError(error);
|
|
346
|
+
}
|
|
347
|
+
} while (updates === undefined && this.pollingRunning);
|
|
348
|
+
return updates;
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* Internal. Do not call. Handles an error that occurred during long
|
|
352
|
+
* polling.
|
|
353
|
+
*/
|
|
354
|
+
async handlePollingError(error) {
|
|
355
|
+
var _a;
|
|
356
|
+
if (!this.pollingRunning) {
|
|
357
|
+
debug("Pending getUpdates request cancelled");
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
let sleepSeconds = 3;
|
|
361
|
+
if (error instanceof error_js_1.GrammyError) {
|
|
362
|
+
debugErr(error.message);
|
|
363
|
+
if (error.error_code === 401) {
|
|
364
|
+
debugErr("Make sure you are using the bot token you obtained from @BotFather (https://t.me/BotFather).");
|
|
365
|
+
throw error;
|
|
366
|
+
}
|
|
367
|
+
else if (error.error_code === 409) {
|
|
368
|
+
debugErr("Consider revoking the bot token if you believe that no other instance is running.");
|
|
369
|
+
throw error;
|
|
370
|
+
}
|
|
371
|
+
else if (error.error_code === 429) {
|
|
372
|
+
debugErr("Bot API server is closing.");
|
|
373
|
+
sleepSeconds = (_a = error.parameters.retry_after) !== null && _a !== void 0 ? _a : sleepSeconds;
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
else
|
|
377
|
+
debugErr(error);
|
|
378
|
+
debugErr(`Call to getUpdates failed, retrying in ${sleepSeconds} seconds ...`);
|
|
379
|
+
await sleep(sleepSeconds);
|
|
380
|
+
}
|
|
405
381
|
}
|
|
406
382
|
exports.Bot = Bot;
|
|
383
|
+
/**
|
|
384
|
+
* Performs a network call task, retrying upon known errors until success.
|
|
385
|
+
*
|
|
386
|
+
* @param task Async task to perform
|
|
387
|
+
*/
|
|
407
388
|
async function withRetries(task) {
|
|
408
389
|
let success = false;
|
|
409
390
|
while (!success) {
|
|
@@ -420,9 +401,8 @@ async function withRetries(task) {
|
|
|
420
401
|
continue;
|
|
421
402
|
if (error.error_code === 429) {
|
|
422
403
|
const retryAfter = error.parameters.retry_after;
|
|
423
|
-
if (retryAfter !== undefined)
|
|
424
|
-
await
|
|
425
|
-
}
|
|
404
|
+
if (retryAfter !== undefined)
|
|
405
|
+
await sleep(retryAfter);
|
|
426
406
|
continue;
|
|
427
407
|
}
|
|
428
408
|
}
|
|
@@ -430,4 +410,10 @@ async function withRetries(task) {
|
|
|
430
410
|
}
|
|
431
411
|
}
|
|
432
412
|
}
|
|
413
|
+
/**
|
|
414
|
+
* Returns a new promise that resolves after the specified number of seconds.
|
|
415
|
+
*/
|
|
416
|
+
function sleep(seconds) {
|
|
417
|
+
return new Promise((r) => setTimeout(r, 1000 * seconds));
|
|
418
|
+
}
|
|
433
419
|
const shim_node_js_1 = require("./shim.node.js");
|
package/out/composer.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Context } from "./context.js";
|
|
2
|
-
import { Filter, FilterQuery } from "./filter.js";
|
|
1
|
+
import { type Context } from "./context.js";
|
|
2
|
+
import { type Filter, type FilterQuery } from "./filter.js";
|
|
3
3
|
declare type MaybePromise<T> = T | Promise<T>;
|
|
4
4
|
declare type MaybeArray<T> = T | T[];
|
|
5
5
|
declare type StringWithSuggestions<S extends string> = (string & {}) | S;
|
package/out/composer.js
CHANGED
|
@@ -11,18 +11,8 @@ const filter_js_1 = require("./filter.js");
|
|
|
11
11
|
class BotError extends Error {
|
|
12
12
|
constructor(error, ctx) {
|
|
13
13
|
super(generateBotErrorMessage(error));
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
configurable: true,
|
|
17
|
-
writable: true,
|
|
18
|
-
value: error
|
|
19
|
-
});
|
|
20
|
-
Object.defineProperty(this, "ctx", {
|
|
21
|
-
enumerable: true,
|
|
22
|
-
configurable: true,
|
|
23
|
-
writable: true,
|
|
24
|
-
value: ctx
|
|
25
|
-
});
|
|
14
|
+
this.error = error;
|
|
15
|
+
this.ctx = ctx;
|
|
26
16
|
this.name = "BotError";
|
|
27
17
|
if (error instanceof Error)
|
|
28
18
|
this.stack = error.stack;
|
|
@@ -109,12 +99,6 @@ class Composer {
|
|
|
109
99
|
* @param middleware The middleware to compose
|
|
110
100
|
*/
|
|
111
101
|
constructor(...middleware) {
|
|
112
|
-
Object.defineProperty(this, "handler", {
|
|
113
|
-
enumerable: true,
|
|
114
|
-
configurable: true,
|
|
115
|
-
writable: true,
|
|
116
|
-
value: void 0
|
|
117
|
-
});
|
|
118
102
|
this.handler = middleware.length === 0
|
|
119
103
|
? pass
|
|
120
104
|
: middleware.map(flatten).reduce(concat);
|
package/out/context.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Api, Other as OtherApi } from "./core/api.js";
|
|
2
|
-
import { Methods, RawApi } from "./core/client.js";
|
|
3
|
-
import { Chat, ChatPermissions, InlineQueryResult, InputFile, InputMedia, InputMediaAudio, InputMediaDocument, InputMediaPhoto, InputMediaVideo, LabeledPrice, Message, PassportElementError, Update, User, UserFromGetMe } from "./platform.node.js";
|
|
1
|
+
import { type Api, type Other as OtherApi } from "./core/api.js";
|
|
2
|
+
import { type Methods, type RawApi } from "./core/client.js";
|
|
3
|
+
import { type Chat, type ChatPermissions, type InlineQueryResult, type InputFile, type InputMedia, type InputMediaAudio, type InputMediaDocument, type InputMediaPhoto, type InputMediaVideo, type LabeledPrice, type Message, type PassportElementError, type Update, type User, type UserFromGetMe } from "./platform.node.js";
|
|
4
4
|
declare type Other<M extends Methods<RawApi>, X extends string = never> = OtherApi<RawApi, M, X>;
|
|
5
5
|
declare type SnakeToCamelCase<S extends string> = S extends `${infer L}_${infer R}` ? `${L}${Capitalize<SnakeToCamelCase<R>>}` : S;
|
|
6
6
|
export declare type AliasProps<U> = {
|
|
@@ -10,7 +10,7 @@ declare type RenamedUpdate = AliasProps<Omit<Update, "update_id">>;
|
|
|
10
10
|
/**
|
|
11
11
|
* When your bot receives a message, Telegram sends an update object to your
|
|
12
12
|
* bot. The update contains information about the chat, the user, and of course
|
|
13
|
-
* the message itself. There
|
|
13
|
+
* the message itself. There are numerous other updates, too:
|
|
14
14
|
* https://core.telegram.org/bots/api#update
|
|
15
15
|
*
|
|
16
16
|
* When grammY receives an update, it wraps this update into a context object
|
|
@@ -735,7 +735,7 @@ export declare class Context implements RenamedUpdate {
|
|
|
735
735
|
*/
|
|
736
736
|
deleteMessage(signal?: AbortSignal): Promise<true>;
|
|
737
737
|
/**
|
|
738
|
-
* Context-aware alias for `api.sendSticker`. Use this method to send static .WEBP
|
|
738
|
+
* Context-aware alias for `api.sendSticker`. Use this method to send static .WEBP, animated .TGS, or video .WEBM stickers. On success, the sent Message is returned.
|
|
739
739
|
*
|
|
740
740
|
* @param sticker Sticker to send. Pass a file_id as String to send a file that exists on the Telegram servers (recommended), pass an HTTP URL as a String for Telegram to get a .WEBP file from the Internet, or upload a new one using multipart/form-data.
|
|
741
741
|
* @param other Optional remaining parameters, confer the official reference below
|
package/out/context.js
CHANGED
|
@@ -4,7 +4,7 @@ exports.Context = void 0;
|
|
|
4
4
|
/**
|
|
5
5
|
* When your bot receives a message, Telegram sends an update object to your
|
|
6
6
|
* bot. The update contains information about the chat, the user, and of course
|
|
7
|
-
* the message itself. There
|
|
7
|
+
* the message itself. There are numerous other updates, too:
|
|
8
8
|
* https://core.telegram.org/bots/api#update
|
|
9
9
|
*
|
|
10
10
|
* When grammY receives an update, it wraps this update into a context object
|
|
@@ -53,34 +53,9 @@ class Context {
|
|
|
53
53
|
* Information about the bot itself.
|
|
54
54
|
*/
|
|
55
55
|
me) {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
writable: true,
|
|
60
|
-
value: update
|
|
61
|
-
});
|
|
62
|
-
Object.defineProperty(this, "api", {
|
|
63
|
-
enumerable: true,
|
|
64
|
-
configurable: true,
|
|
65
|
-
writable: true,
|
|
66
|
-
value: api
|
|
67
|
-
});
|
|
68
|
-
Object.defineProperty(this, "me", {
|
|
69
|
-
enumerable: true,
|
|
70
|
-
configurable: true,
|
|
71
|
-
writable: true,
|
|
72
|
-
value: me
|
|
73
|
-
});
|
|
74
|
-
/**
|
|
75
|
-
* Used by some middleware to store information about how a certain string
|
|
76
|
-
* or regular expression was matched.
|
|
77
|
-
*/
|
|
78
|
-
Object.defineProperty(this, "match", {
|
|
79
|
-
enumerable: true,
|
|
80
|
-
configurable: true,
|
|
81
|
-
writable: true,
|
|
82
|
-
value: void 0
|
|
83
|
-
});
|
|
56
|
+
this.update = update;
|
|
57
|
+
this.api = api;
|
|
58
|
+
this.me = me;
|
|
84
59
|
}
|
|
85
60
|
// UPDATE SHORTCUTS
|
|
86
61
|
/** Alias for `ctx.update.message` */
|
|
@@ -940,7 +915,7 @@ class Context {
|
|
|
940
915
|
return this.api.deleteMessage(orThrow(this.chat, "deleteMessage").id, orThrow(this.msg, "deleteMessage").message_id, signal);
|
|
941
916
|
}
|
|
942
917
|
/**
|
|
943
|
-
* Context-aware alias for `api.sendSticker`. Use this method to send static .WEBP
|
|
918
|
+
* Context-aware alias for `api.sendSticker`. Use this method to send static .WEBP, animated .TGS, or video .WEBM stickers. On success, the sent Message is returned.
|
|
944
919
|
*
|
|
945
920
|
* @param sticker Sticker to send. Pass a file_id as String to send a file that exists on the Telegram servers (recommended), pass an HTTP URL as a String for Telegram to get a .WEBP file from the Internet, or upload a new one using multipart/form-data.
|
|
946
921
|
* @param other Optional remaining parameters, confer the official reference below
|
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { type IncomingMessage, type ServerResponse } from "http";
|
|
2
3
|
export declare const adapters: {
|
|
3
4
|
http: (req: IncomingMessage, res: ServerResponse) => {
|
|
4
5
|
update: Promise<any>;
|
|
5
|
-
end: () =>
|
|
6
|
-
respond: (json: string) =>
|
|
6
|
+
end: () => ServerResponse;
|
|
7
|
+
respond: (json: string) => ServerResponse;
|
|
7
8
|
};
|
|
8
9
|
https: (req: IncomingMessage, res: ServerResponse) => {
|
|
9
10
|
update: Promise<any>;
|
|
10
|
-
end: () =>
|
|
11
|
-
respond: (json: string) =>
|
|
11
|
+
end: () => ServerResponse;
|
|
12
|
+
respond: (json: string) => ServerResponse;
|
|
12
13
|
};
|
|
13
14
|
express: (req: any, res: any) => {
|
|
14
15
|
update: Promise<any>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { InlineKeyboardButton, KeyboardButton, LoginUrl } from "../platform.node.js";
|
|
1
|
+
import { type InlineKeyboardButton, type KeyboardButton, type LoginUrl } from "../platform.node.js";
|
|
2
2
|
/**
|
|
3
3
|
* Use this class to simplify building a custom keyboard (something like this:
|
|
4
4
|
* https://core.telegram.org/bots#keyboards).
|
|
@@ -34,12 +34,7 @@ class Keyboard {
|
|
|
34
34
|
* The nested array that holds the custom keyboard. It will be extended every time
|
|
35
35
|
* you call one of the provided methods.
|
|
36
36
|
*/
|
|
37
|
-
|
|
38
|
-
enumerable: true,
|
|
39
|
-
configurable: true,
|
|
40
|
-
writable: true,
|
|
41
|
-
value: [[]]
|
|
42
|
-
});
|
|
37
|
+
this.keyboard = [[]];
|
|
43
38
|
}
|
|
44
39
|
/**
|
|
45
40
|
* Allows you to add your own `KeyboardButton` objects if you already have
|
|
@@ -141,12 +136,7 @@ class InlineKeyboard {
|
|
|
141
136
|
* The nested array that holds the inline keyboard. It will be extended
|
|
142
137
|
* every time you call one of the provided methods.
|
|
143
138
|
*/
|
|
144
|
-
|
|
145
|
-
enumerable: true,
|
|
146
|
-
configurable: true,
|
|
147
|
-
writable: true,
|
|
148
|
-
value: [[]]
|
|
149
|
-
});
|
|
139
|
+
this.inline_keyboard = [[]];
|
|
150
140
|
}
|
|
151
141
|
/**
|
|
152
142
|
* Allows you to add your own `InlineKeyboardButton` objects if you already
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Context } from "../context.js";
|
|
2
|
-
import { MiddlewareFn } from "../composer.js";
|
|
1
|
+
import { type Context } from "../context.js";
|
|
2
|
+
import { type MiddlewareFn } from "../composer.js";
|
|
3
3
|
declare type MaybePromise<T> = Promise<T> | T;
|
|
4
4
|
/**
|
|
5
5
|
* A session flavor is a context flavor that holds session data under
|