UNPKG

telegraf

Version:

Modern Telegram Bot Framework

85 lines (84 loc) 3.06 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Polling = void 0; const abort_controller_1 = require("abort-controller"); const debug_1 = require("debug"); const util_1 = require("util"); const error_1 = require("./error"); const debug = (0, debug_1.default)('telegraf:polling'); const wait = (0, util_1.promisify)(setTimeout); function always(x) { return () => x; } const noop = always(Promise.resolve()); class Polling { constructor(telegram, allowedUpdates) { this.telegram = telegram; this.allowedUpdates = allowedUpdates; this.abortController = new abort_controller_1.default(); this.skipOffsetSync = false; this.offset = 0; } async *[Symbol.asyncIterator]() { var _a, _b; debug('Starting long polling'); do { try { const updates = await this.telegram.callApi('getUpdates', { timeout: 50, offset: this.offset, allowed_updates: this.allowedUpdates, }, this.abortController); const last = updates[updates.length - 1]; if (last !== undefined) { this.offset = last.update_id + 1; } yield updates; } catch (err) { if (err.name === 'AbortError') return; if (err.name === 'FetchError' || (err instanceof error_1.TelegramError && err.code >= 500)) { const retryAfter = (_b = (_a = err.parameters) === null || _a === void 0 ? void 0 : _a.retry_after) !== null && _b !== void 0 ? _b : 5; debug('Failed to fetch updates, retrying after %ds.', retryAfter, err); await wait(retryAfter * 1000); continue; } if (err instanceof error_1.TelegramError && // Unauthorized Conflict (err.code === 401 || err.code === 409)) { this.skipOffsetSync = true; throw err; } throw err; } } while (!this.abortController.signal.aborted); } async syncUpdateOffset() { if (this.skipOffsetSync) return; debug('Syncing update offset...'); await this.telegram.callApi('getUpdates', { offset: this.offset, limit: 1 }); } async loop(handleUpdates) { if (this.abortController.signal.aborted) { throw new Error('Polling instances must not be reused!'); } try { for await (const updates of this) { await handleUpdates(updates); } } finally { debug('Long polling stopped'); // prevent instance reuse this.stop(); await this.syncUpdateOffset().catch(noop); } } stop() { this.abortController.abort(); } } exports.Polling = Polling;