mirror of
https://github.com/DIYgod/RSSHub.git
synced 2026-10-16 16:44:53 +08:00
fix(route/telegram): fall back to the web preview on MTProto flood waits
The MTProto path cached the resolved input entity for the default 5 minutes, so every process that started later or missed the cache called contacts.ResolveUsername again for each channel. That method is heavily rate limited, and once the account hit a flood wait the route failed with "A wait of N seconds is required" even for channels that the public web preview serves fine. Keep the channel ID and access hash for 30 days, since they do not change, and fall back to the web preview when MTProto raises a FloodWaitError. Other MTProto errors are still reported. Closes #20454
This commit is contained in:
@@ -3,11 +3,13 @@ import querystring from 'node:querystring';
|
||||
import { load } from 'cheerio';
|
||||
import { FetchError } from 'ofetch';
|
||||
import pMap from 'p-map';
|
||||
import { errors } from 'teleproto';
|
||||
|
||||
import { config } from '@/config';
|
||||
import type { DataItem, Route } from '@/types';
|
||||
import { ViewType } from '@/types';
|
||||
import cache from '@/utils/cache';
|
||||
import logger from '@/utils/logger';
|
||||
import ofetch from '@/utils/ofetch';
|
||||
import { parseDate } from '@/utils/parse-date';
|
||||
import { fallback, queryToBoolean } from '@/utils/readable-social';
|
||||
@@ -159,7 +161,15 @@ When a reverse proxy removes a public URL prefix (for example, \`/rss\`), set it
|
||||
async function handler(ctx) {
|
||||
const useWeb = ctx.req.param('routeParams') || !config.telegram.session;
|
||||
if (!useWeb) {
|
||||
return tglibchannel(ctx);
|
||||
try {
|
||||
return await tglibchannel(ctx);
|
||||
} catch (error) {
|
||||
// A flood wait blocks the account for minutes to hours, while the public web preview still works
|
||||
if (!(error instanceof errors.FloodWaitError)) {
|
||||
throw error;
|
||||
}
|
||||
logger.warn(`Telegram MTProto requires a wait of ${error.seconds} seconds, falling back to the web preview`);
|
||||
}
|
||||
}
|
||||
|
||||
const username = ctx.req.param('username');
|
||||
|
||||
@@ -148,7 +148,8 @@ export default async function handler(ctx: Context) {
|
||||
if (!peerCache) {
|
||||
const p = await client.getInputEntity(username!);
|
||||
peerCache = JSON.stringify(p.toJSON());
|
||||
await cache.set(`telegram:inputEntity:${username}`, peerCache);
|
||||
// The channel ID and access hash do not change, and contacts.ResolveUsername is heavily rate limited
|
||||
await cache.set(`telegram:inputEntity:${username}`, peerCache, 30 * 24 * 60 * 60);
|
||||
}
|
||||
const peerData = JSON.parse(peerCache, (k, v) => (k === 'channelId' || k === 'accessHash' ? returnBigInt(v) : v));
|
||||
const peer = new Api.InputPeerChannel(peerData);
|
||||
|
||||
Reference in New Issue
Block a user