Telegram Integration#
RSSHub provides an RSS feed for public Telegram channels via the route GET /telegram/channel/:username/:routeParams? . The route supports two fetching strategies β web scraping (default) and Telegram MTProto API β selected at runtime based on the presence of a configured TELEGRAM_SESSION.
Route Entry Point#
- Route definition:
lib/routes/telegram/channel.ts - Radar: maps
t.me/s/:usernameβ/channel/:username - Example:
/telegram/channel/awesomeRSSHub - Categories:
social-media
Fetching Strategy: Web Scraping vs. MTProto API#
The handler decides the strategy on every request:
useWeb = (routeParams present) OR (TELEGRAM_SESSION not configured)
| Condition | Strategy used |
|---|---|
No TELEGRAM_SESSION configured, or routeParams supplied | Web scraping via https://t.me/s/<username> |
TELEGRAM_SESSION configured and no routeParams | MTProto API via tglib/channel.ts |
Web Scraping Path#
When useWeb is true, the handler fetches https://t.me/s/${username} (or with ?q=<searchQuery>) and parses the HTML with cheerio. The URL is hardcoded to t.me β there is no configurable domain fallback for the scraping path.
A known quirk: since 2024-04-20 Telegram's t.me/s/ preview incorrectly escapes & as & inside hyperlinks with an onclick attribute; the scraper works around this inline .
If the channel page returns no messages and the .tgme_channel_history container is absent, the route throws a descriptive error pointing the user to verify the preview URL directly .
Supported message types parsed from HTML :
VIDEO, GIF, PHOTO, POLL, VOICE, MUSIC, DOCUMENT, LOCATION, CONTACT, STICKER, ANIMATED_STICKER, VIDEO_STICKER, plus meta-types REPLY, FORWARDED, SERVICE, VIA_BOT, UNSUPPORTED, PARTIALLY_UNSUPPORTED.
MTProto API Path#
When a TELEGRAM_SESSION is set, the handler delegates to tglib/channel.ts, which uses the telegram npm package (GramJS) to call the MTProto API directly . It:
- Resolves the channel peer and caches the
InputPeerChannelundertelegram:inputEntity:<username> - Fetches the last 50 messages
- Groups consecutive media-only messages into a single feed item
- Sets item links as
https://t.me/s/${username}/${message.id}and feed link ashttps://t.me/${username}β both hardcoded tot.me
Media in the API path is served via an internal proxy endpoint /telegram/media/:username/:messageId .
Configuration#
All Telegram env vars are optional . Without TELEGRAM_SESSION, only web scraping is available.
| Environment Variable | Config key | Purpose |
|---|---|---|
TELEGRAM_SESSION | telegram.session | Enables MTProto API path; obtain by running node ./lib/routes/telegram/scripts/get-telegram-session.mjs |
TELEGRAM_API_ID | telegram.apiId | Telegram app API ID (default: 4) |
TELEGRAM_API_HASH | telegram.apiHash | Telegram app API hash (default: hardcoded fallback) |
TELEGRAM_MAX_CONCURRENT_DOWNLOADS | telegram.maxConcurrentDownloads | Max concurrent media downloads (default: 10) |
TELEGRAM_PROXY_HOST | telegram.proxy.host | MTProxy host |
TELEGRAM_PROXY_PORT | telegram.proxy.port | MTProxy port |
TELEGRAM_PROXY_SECRET | telegram.proxy.secret | MTProxy secret |
Config is read from lib/config.ts. MTProxy activates only when all three proxy fields are provided.
Note: Some channels (pornography, copyright, politics) are blocked on Telegram's public preview (
t.me/s/). For these, only the MTProto API path (withTELEGRAM_SESSION) can access the channel.
Route Parameters (routeParams)#
Supplying routeParams forces the web scraping path (regardless of TELEGRAM_SESSION). Parameters are parsed as a query string . For backwards compatibility, an unrecognized value is treated as searchQuery .
| Parameter | Default | Notes |
|---|---|---|
showLinkPreview | true | Show Telegram link previews |
showViaBot | true | Show bot attribution |
showReplyTo | true | Show reply target |
showFwdFrom | true | Show forwarded-from source |
showFwdFromAuthor | true | Show author of forwarded message |
showInlineButtons | false | Show inline keyboard buttons |
showMediaTagInTitle | true | Prepend media type tag to title |
showMediaTagAsEmoji | true | Use emoji rather than text for media tags |
showHashtagAsHyperlink | true | Link hashtags to t.me/s/channel?q=%23hashtag |
includeFwd | true | Include forwarded messages |
includeReply | true | Include reply messages |
includeServiceMsg | true | Include service messages |
includeUnsupportedMsg | false | Include messages unsupported by t.me |
searchQuery | (none) | Keyword filter |
Example minimal feed URL :
/telegram/channel/NewlearnerChannel/showLinkPreview=0&showViaBot=0&showReplyTo=0&showFwdFrom=0&showFwdFromAuthor=0&showInlineButtons=0&showMediaTagInTitle=1&showMediaTagAsEmoji=1&includeFwd=0&includeReply=1&includeServiceMsg=0&includeUnsupportedMsg=0
Key Source Files#
| File | Purpose |
|---|---|
lib/routes/telegram/channel.ts | Route definition, web scraping handler, HTML parsing |
lib/routes/telegram/tglib/channel.ts | MTProto API handler (GramJS) |
lib/routes/telegram/tglib/client.ts | GramJS client singleton, proxy setup |
lib/routes/telegram/scripts/get-telegram-session.mjs | Helper to obtain TELEGRAM_SESSION value |
lib/config.ts | Telegram config keys and defaults |