A Vercel app that combines:
- a simple web entrance
- a readable article extraction API
- a Telegram webhook for bot updates
Telegram bot: @Readabbot
Web app: https://readability-bot.vercel.app
api/ Vercel serverless functions
lib/server/ shared backend logic used by the API handlers
public/ static assets copied as-is by Vite
src/ Svelte frontend
Endpoint: /api/readability?url={URL}&format=json (e.g.)
Returns either:
- HTML: a cleaned article page
- JSON: the extracted Readability payload when
format=json
Optional parameters:
-
?summary=0— Disable AI-generated summary (enabled by default). Example:https://readability-bot.vercel.app/api/readability?url=...&summary=0When enabled, the API generates a 2-3 sentence summary of the article text using an external LLM. The summary appears as a styled block in the HTML view and as the
summaryfield in the JSON response. If the LLM is unavailable, the summary is silently omitted.
The Telegram bot returns "readable" articles with Instant View enabled automatically.
It supports three Telegram entry points:
- private chat: send a message that contains a URL anywhere in the text
- inline mode: type
@Readabbot <url>in any chat - guest mode: mention
@Readabbotin a chat message to summon the bot; it first tries to extract the first available link from the message being replied to, and falls back to the summoning message if needed, then replies once through Telegram's guest interaction flow
For guest mode, enable Guest Mode for your bot in BotFather's Mini App settings. Telegram documents guest interactions in the Bot Features guide: https://core.telegram.org/bots/features#guest-interactions
If you want Telegram to treat @Readabbot as a regular mention instead of opening inline mode, place a space before the @ and send it as part of a normal chat message.
It is also possbile to apply a quick Instant View to any* website programmatically with the help of the web service.
Assuming ARTICLE_TITLE="Lorem Ipsum", ARTICLE_URL="https://example.org/blog-post/1" and CHANNEL is the ID of channel, which typically is the subscribing channel for a (news/blog/etc.) website:
JavaScript:
const readableUrl = `https://readability-bot.vercel.app/api/readability?url=${encodeURIComponent(
ARTICLE_URL
)}`;
const ivUrl = `https://t.me/iv?url=${encodeURIComponent(
readableUrl
)}&rhash=71b64d09b0a20d`;
const message = `<a href="${ivUrl}"> </a><a href="${articleUrl}">${ARTICLE_TITLE}</a>`;
bot.sendMessage(CHANNEL, message, (parseMode = "html"));Python:
import urllib.parse import quote as percent_encode
# ... ...
readable_url = f'https://readability-bot.vercel.app/api/readability?url={percent_encode(ARTICLE_URL, safe="")}';
iv_url = f'https://t.me/iv?url={percent_encode(readable_url, safe="")}&rhash=71b64d09b0a20d';
message = f'<a href="{iv_url}"> </a><a href="{article_url}">{articleTitle}</a>';
bot.send_message(CHANNEL, message, parse_mode="html") # await it?*: Almost, with no guarantee. Instant View may fail to render when the source page has deeply nested HTML structures, or when Telegram is unable to fetch external media (e.g. hotlink-protected images). Compatibility issues about Instant View rendering are welcome in this project; issues about the article extraction itself should go to readability.js.
Set these environment variables:
BOT_TOKEN: REQUIRED for the bot service. Do not forget to set the webhook address to{APP_URL}/api/webhook.APP_URL: Optional, defaults to the Vercel production URL fromVERCEL_PROJECT_PRODUCTION_URL. Override only if you use a custom domain not configured in Vercel.READABILITY_API_URL: Optional, inferred automatically as{APP_URL}/api/readability.IV_RHASH: Required for Instant View to render. Create a custom IV template by tracking an article link of the deployed instance in instantview.telegram.org, apply rules.iv as the template rules, and pick the rhash value at the end of the preview link. The template editor there also shows detailed IV rendering errors, which is useful for debugging failures.
pnpm install
pnpm devnpx vercel deploy --prod