grammy 1.6.1 β 1.7.1
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/LICENSE +1 -1
- package/README.md +7 -3
- package/out/bot.d.ts +41 -3
- package/out/bot.js +149 -153
- 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 +2 -2
package/LICENSE
CHANGED
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>
|
|
@@ -189,6 +189,10 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
|
|
|
189
189
|
<td align="center"><a href="http://glukki.ru"><img src="https://avatars.githubusercontent.com/u/140462?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Vitaliy Meshchaninov</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/issues?q=author%3Aglukki" title="Bug reports">π</a> <a href="https://github.com/grammyjs/grammY/commits?author=glukki" title="Code">π»</a></td>
|
|
190
190
|
<td align="center"><a href="https://github.com/dilyanpalauzov"><img src="https://avatars.githubusercontent.com/u/4992947?v=4?s=100" width="100px;" alt=""/><br /><sub><b>ΠΠΈΠ»ΡΠ½ ΠΠ°Π»Π°ΡΠ·ΠΎΠ²</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/issues?q=author%3Adilyanpalauzov" title="Bug reports">π</a> <a href="https://github.com/grammyjs/grammY/commits?author=dilyanpalauzov" title="Code">π»</a></td>
|
|
191
191
|
<td align="center"><a href="https://github.com/lmx-Hexagram"><img src="https://avatars.githubusercontent.com/u/52130356?v=4?s=100" width="100px;" alt=""/><br /><sub><b>lmx-Hexagram</b></sub></a><br /><a href="https://github.com/grammyjs/grammY/commits?author=lmx-Hexagram" title="Documentation">π</a></td>
|
|
192
|
+
<td align="center"><a href="https://github.com/IlyaSemenov"><img src="https://avatars.githubusercontent.com/u/128121?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Ilya Semenov</b></sub></a><br /><a href="#ideas-IlyaSemenov" title="Ideas, Planning, & Feedback">π€</a> <a href="https://github.com/grammyjs/grammY/pulls?q=is%3Apr+reviewed-by%3AIlyaSemenov" title="Reviewed Pull Requests">π</a></td>
|
|
193
|
+
</tr>
|
|
194
|
+
<tr>
|
|
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>
|
|
192
196
|
</tr>
|
|
193
197
|
</table>
|
|
194
198
|
|
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
|
*/
|
|
@@ -153,11 +153,30 @@ export declare class Bot<C extends Context = Context, A extends Api = Api> exten
|
|
|
153
153
|
*/
|
|
154
154
|
set botInfo(botInfo: UserFromGetMe);
|
|
155
155
|
get botInfo(): UserFromGetMe;
|
|
156
|
+
/**
|
|
157
|
+
* Checks if the bot has been initialized. A bot is initialized if the bot
|
|
158
|
+
* information is set. The bot information can either be set automatically
|
|
159
|
+
* by calling `bot.init`, or manually through the bot constructor. Note that
|
|
160
|
+
* usually, initialization is done automatically and you do not have to care
|
|
161
|
+
* about this method.
|
|
162
|
+
*
|
|
163
|
+
* @returns true if the bot is initialized, and false otherwise
|
|
164
|
+
*/
|
|
165
|
+
isInited(): boolean;
|
|
156
166
|
/**
|
|
157
167
|
* Initializes the bot, i.e. fetches information about the bot itself. This
|
|
158
|
-
* method is called automatically, you don't have to call it
|
|
168
|
+
* method is called automatically, you usually don't have to call it
|
|
169
|
+
* manually.
|
|
159
170
|
*/
|
|
160
171
|
init(): Promise<void>;
|
|
172
|
+
/**
|
|
173
|
+
* Internal. Do not call. Handles an update batch sequentially by supplying
|
|
174
|
+
* it one-by-one to the middleware. Handles middleware errors and stores the
|
|
175
|
+
* last update identifier that was being tried to handle.
|
|
176
|
+
*
|
|
177
|
+
* @param updates An array of updates to handle
|
|
178
|
+
*/
|
|
179
|
+
private handleUpdates;
|
|
161
180
|
/**
|
|
162
181
|
* This is an internal method that you probably will not ever need to call.
|
|
163
182
|
* It is used whenever a new update arrives from the Telegram servers that
|
|
@@ -238,4 +257,23 @@ export declare class Bot<C extends Context = Context, A extends Api = Api> exten
|
|
|
238
257
|
* @param errorHandler A function that handles potential middleware errors
|
|
239
258
|
*/
|
|
240
259
|
catch(errorHandler: ErrorHandler<C>): void;
|
|
260
|
+
/**
|
|
261
|
+
* Internal. Do not call. Enters a loop that will perform long polling until
|
|
262
|
+
* the bot is stopped.
|
|
263
|
+
*/
|
|
264
|
+
private loop;
|
|
265
|
+
/**
|
|
266
|
+
* Internal. Do not call. Reliably fetches an update batch via `getUpdates`.
|
|
267
|
+
* Handles all known errors. Returns `undefined` if the bot is stopped and
|
|
268
|
+
* the call gets cancelled.
|
|
269
|
+
*
|
|
270
|
+
* @param options Polling options
|
|
271
|
+
* @returns An array of updates, or `undefined` if the bot is stopped.
|
|
272
|
+
*/
|
|
273
|
+
private fetchUpdates;
|
|
274
|
+
/**
|
|
275
|
+
* Internal. Do not call. Handles an error that occurred during long
|
|
276
|
+
* polling.
|
|
277
|
+
*/
|
|
278
|
+
private handlePollingError;
|
|
241
279
|
}
|
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;
|
|
@@ -157,12 +97,25 @@ class Bot extends composer_js_1.Composer {
|
|
|
157
97
|
}
|
|
158
98
|
return this.me;
|
|
159
99
|
}
|
|
100
|
+
/**
|
|
101
|
+
* Checks if the bot has been initialized. A bot is initialized if the bot
|
|
102
|
+
* information is set. The bot information can either be set automatically
|
|
103
|
+
* by calling `bot.init`, or manually through the bot constructor. Note that
|
|
104
|
+
* usually, initialization is done automatically and you do not have to care
|
|
105
|
+
* about this method.
|
|
106
|
+
*
|
|
107
|
+
* @returns true if the bot is initialized, and false otherwise
|
|
108
|
+
*/
|
|
109
|
+
isInited() {
|
|
110
|
+
return this.me !== undefined;
|
|
111
|
+
}
|
|
160
112
|
/**
|
|
161
113
|
* Initializes the bot, i.e. fetches information about the bot itself. This
|
|
162
|
-
* method is called automatically, you don't have to call it
|
|
114
|
+
* method is called automatically, you usually don't have to call it
|
|
115
|
+
* manually.
|
|
163
116
|
*/
|
|
164
117
|
async init() {
|
|
165
|
-
if (this.
|
|
118
|
+
if (!this.isInited()) {
|
|
166
119
|
debug("Initializing bot");
|
|
167
120
|
const me = await this.api.getMe();
|
|
168
121
|
if (this.me === undefined)
|
|
@@ -170,11 +123,34 @@ class Bot extends composer_js_1.Composer {
|
|
|
170
123
|
else
|
|
171
124
|
debug("Bot info was set manually by now, will not overwrite");
|
|
172
125
|
}
|
|
173
|
-
else {
|
|
174
|
-
debug("Bot already initialized!");
|
|
175
|
-
}
|
|
176
126
|
debug(`I am ${this.me.username}!`);
|
|
177
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
|
+
}
|
|
178
154
|
/**
|
|
179
155
|
* This is an internal method that you probably will not ever need to call.
|
|
180
156
|
* It is used whenever a new update arrives from the Telegram servers that
|
|
@@ -246,9 +222,10 @@ a known bot info object.");
|
|
|
246
222
|
* @param options Options to use for simple long polling
|
|
247
223
|
*/
|
|
248
224
|
async start(options) {
|
|
249
|
-
var _a
|
|
225
|
+
var _a;
|
|
250
226
|
// Perform setup
|
|
251
|
-
|
|
227
|
+
if (!this.isInited())
|
|
228
|
+
await withRetries(() => this.init());
|
|
252
229
|
if (this.pollingRunning) {
|
|
253
230
|
debug("Simple long polling already running!");
|
|
254
231
|
return;
|
|
@@ -272,76 +249,8 @@ you can circumvent this protection against memory leaks.`);
|
|
|
272
249
|
};
|
|
273
250
|
// Start polling
|
|
274
251
|
debug("Starting simple long polling");
|
|
275
|
-
|
|
276
|
-
this.
|
|
277
|
-
const limit = options === null || options === void 0 ? void 0 : options.limit;
|
|
278
|
-
const timeout = (_a = options === null || options === void 0 ? void 0 : options.timeout) !== null && _a !== void 0 ? _a : 30; // seconds
|
|
279
|
-
let allowed_updates = options === null || options === void 0 ? void 0 : options.allowed_updates;
|
|
280
|
-
try {
|
|
281
|
-
(_b = options === null || options === void 0 ? void 0 : options.onStart) === null || _b === void 0 ? void 0 : _b.call(options, this.botInfo);
|
|
282
|
-
}
|
|
283
|
-
catch (error) {
|
|
284
|
-
this.pollingRunning = false;
|
|
285
|
-
this.pollingAbortController = undefined;
|
|
286
|
-
throw error;
|
|
287
|
-
}
|
|
288
|
-
const handleErr = async (error) => {
|
|
289
|
-
if (!this.pollingRunning)
|
|
290
|
-
throw error;
|
|
291
|
-
else if (error instanceof error_js_1.GrammyError) {
|
|
292
|
-
debugErr(error.message);
|
|
293
|
-
if (error.error_code === 401) {
|
|
294
|
-
debugErr("Make sure you are using the bot token you obtained from @BotFather (https://t.me/BotFather).");
|
|
295
|
-
throw error;
|
|
296
|
-
}
|
|
297
|
-
else if (error.error_code === 409) {
|
|
298
|
-
debugErr("Consider revoking the bot token if you believe that no other instance is running.");
|
|
299
|
-
throw error;
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
else
|
|
303
|
-
debugErr(error);
|
|
304
|
-
debugErr("Call to getUpdates failed, retrying in 3 seconds ...");
|
|
305
|
-
await new Promise((r) => setTimeout(r, 3000));
|
|
306
|
-
};
|
|
307
|
-
while (this.pollingRunning) {
|
|
308
|
-
// fetch updates
|
|
309
|
-
const offset = this.lastTriedUpdateId + 1;
|
|
310
|
-
let updates = undefined;
|
|
311
|
-
do {
|
|
312
|
-
try {
|
|
313
|
-
updates = await this.api.getUpdates({ offset, limit, timeout, allowed_updates }, this.pollingAbortController.signal);
|
|
314
|
-
}
|
|
315
|
-
catch (error) {
|
|
316
|
-
if (this.pollingRunning)
|
|
317
|
-
await handleErr(error);
|
|
318
|
-
else
|
|
319
|
-
debug("Pending getUpdates request cancelled");
|
|
320
|
-
}
|
|
321
|
-
} while (updates === undefined && this.pollingRunning);
|
|
322
|
-
if (updates === undefined)
|
|
323
|
-
break;
|
|
324
|
-
// handle them sequentially (!)
|
|
325
|
-
for (const update of updates) {
|
|
326
|
-
this.lastTriedUpdateId = update.update_id;
|
|
327
|
-
try {
|
|
328
|
-
await this.handleUpdate(update);
|
|
329
|
-
}
|
|
330
|
-
catch (err) {
|
|
331
|
-
// should always be true
|
|
332
|
-
if (err instanceof composer_js_1.BotError) {
|
|
333
|
-
await this.errorHandler(err);
|
|
334
|
-
}
|
|
335
|
-
else {
|
|
336
|
-
console.error("FATAL: grammY unable to handle:", err);
|
|
337
|
-
throw err;
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
// Telegram uses the last setting if `allowed_updates` is omitted so
|
|
342
|
-
// we can save same traffic by only sending it in the first request
|
|
343
|
-
allowed_updates = undefined;
|
|
344
|
-
}
|
|
252
|
+
(_a = options === null || options === void 0 ? void 0 : options.onStart) === null || _a === void 0 ? void 0 : _a.call(options, this.botInfo);
|
|
253
|
+
await this.loop(options);
|
|
345
254
|
debug("Middleware is done running");
|
|
346
255
|
}
|
|
347
256
|
/**
|
|
@@ -391,8 +300,90 @@ you can circumvent this protection against memory leaks.`);
|
|
|
391
300
|
catch(errorHandler) {
|
|
392
301
|
this.errorHandler = errorHandler;
|
|
393
302
|
}
|
|
303
|
+
/**
|
|
304
|
+
* Internal. Do not call. Enters a loop that will perform long polling until
|
|
305
|
+
* the bot is stopped.
|
|
306
|
+
*/
|
|
307
|
+
async loop(options) {
|
|
308
|
+
var _a;
|
|
309
|
+
this.pollingRunning = true;
|
|
310
|
+
this.pollingAbortController = new shim_node_js_1.AbortController();
|
|
311
|
+
const limit = options === null || options === void 0 ? void 0 : options.limit;
|
|
312
|
+
const timeout = (_a = options === null || options === void 0 ? void 0 : options.timeout) !== null && _a !== void 0 ? _a : 30; // seconds
|
|
313
|
+
let allowed_updates = options === null || options === void 0 ? void 0 : options.allowed_updates;
|
|
314
|
+
while (this.pollingRunning) {
|
|
315
|
+
// fetch updates
|
|
316
|
+
const updates = await this.fetchUpdates({ limit, timeout, allowed_updates });
|
|
317
|
+
// check if polling stopped
|
|
318
|
+
if (updates === undefined)
|
|
319
|
+
break;
|
|
320
|
+
// handle updates
|
|
321
|
+
await this.handleUpdates(updates);
|
|
322
|
+
// Telegram uses the last setting if `allowed_updates` is omitted so
|
|
323
|
+
// we can save same traffic by only sending it in the first request
|
|
324
|
+
allowed_updates = undefined;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Internal. Do not call. Reliably fetches an update batch via `getUpdates`.
|
|
329
|
+
* Handles all known errors. Returns `undefined` if the bot is stopped and
|
|
330
|
+
* the call gets cancelled.
|
|
331
|
+
*
|
|
332
|
+
* @param options Polling options
|
|
333
|
+
* @returns An array of updates, or `undefined` if the bot is stopped.
|
|
334
|
+
*/
|
|
335
|
+
async fetchUpdates({ limit, timeout, allowed_updates }) {
|
|
336
|
+
var _a;
|
|
337
|
+
const offset = this.lastTriedUpdateId + 1;
|
|
338
|
+
let updates = undefined;
|
|
339
|
+
do {
|
|
340
|
+
try {
|
|
341
|
+
updates = await this.api.getUpdates({ offset, limit, timeout, allowed_updates }, (_a = this.pollingAbortController) === null || _a === void 0 ? void 0 : _a.signal);
|
|
342
|
+
}
|
|
343
|
+
catch (error) {
|
|
344
|
+
await this.handlePollingError(error);
|
|
345
|
+
}
|
|
346
|
+
} while (updates === undefined && this.pollingRunning);
|
|
347
|
+
return updates;
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* Internal. Do not call. Handles an error that occurred during long
|
|
351
|
+
* polling.
|
|
352
|
+
*/
|
|
353
|
+
async handlePollingError(error) {
|
|
354
|
+
var _a;
|
|
355
|
+
if (!this.pollingRunning) {
|
|
356
|
+
debug("Pending getUpdates request cancelled");
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
359
|
+
let sleepSeconds = 3;
|
|
360
|
+
if (error instanceof error_js_1.GrammyError) {
|
|
361
|
+
debugErr(error.message);
|
|
362
|
+
if (error.error_code === 401) {
|
|
363
|
+
debugErr("Make sure you are using the bot token you obtained from @BotFather (https://t.me/BotFather).");
|
|
364
|
+
throw error;
|
|
365
|
+
}
|
|
366
|
+
else if (error.error_code === 409) {
|
|
367
|
+
debugErr("Consider revoking the bot token if you believe that no other instance is running.");
|
|
368
|
+
throw error;
|
|
369
|
+
}
|
|
370
|
+
else if (error.error_code === 429) {
|
|
371
|
+
debugErr("Bot API server is closing.");
|
|
372
|
+
sleepSeconds = (_a = error.parameters.retry_after) !== null && _a !== void 0 ? _a : sleepSeconds;
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
else
|
|
376
|
+
debugErr(error);
|
|
377
|
+
debugErr(`Call to getUpdates failed, retrying in ${sleepSeconds} seconds ...`);
|
|
378
|
+
await sleep(sleepSeconds);
|
|
379
|
+
}
|
|
394
380
|
}
|
|
395
381
|
exports.Bot = Bot;
|
|
382
|
+
/**
|
|
383
|
+
* Performs a network call task, retrying upon known errors until success.
|
|
384
|
+
*
|
|
385
|
+
* @param task Async task to perform
|
|
386
|
+
*/
|
|
396
387
|
async function withRetries(task) {
|
|
397
388
|
let success = false;
|
|
398
389
|
while (!success) {
|
|
@@ -409,9 +400,8 @@ async function withRetries(task) {
|
|
|
409
400
|
continue;
|
|
410
401
|
if (error.error_code === 429) {
|
|
411
402
|
const retryAfter = error.parameters.retry_after;
|
|
412
|
-
if (retryAfter !== undefined)
|
|
413
|
-
await
|
|
414
|
-
}
|
|
403
|
+
if (retryAfter !== undefined)
|
|
404
|
+
await sleep(retryAfter);
|
|
415
405
|
continue;
|
|
416
406
|
}
|
|
417
407
|
}
|
|
@@ -419,4 +409,10 @@ async function withRetries(task) {
|
|
|
419
409
|
}
|
|
420
410
|
}
|
|
421
411
|
}
|
|
412
|
+
/**
|
|
413
|
+
* Returns a new promise that resolves after the specified number of seconds.
|
|
414
|
+
*/
|
|
415
|
+
function sleep(seconds) {
|
|
416
|
+
return new Promise((r) => setTimeout(r, 1000 * seconds));
|
|
417
|
+
}
|
|
422
418
|
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).
|