Telepage – I built a self-hosted PHP app that turns any Telegram channel into a website
<p>If you run a Telegram channel, you already know the problem: your content is invisible to Google, there's no search, old posts are buried, and readers need the app just to see your work.</p> <p>I built <strong>Telepage</strong> to fix that.</p> <h2> What it does </h2> <p>Telepage connects to your Telegram channel via a bot webhook and turns every post into a searchable web card — automatically, in real time.</p> <p><a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft0zcxkaob0c3c5sglju1.png" class="article-body-image-wrapper"><img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uplo
If you run a Telegram channel, you already know the problem: your content is invisible to Google, there's no search, old posts are buried, and readers need the app just to see your work.
I built Telepage to fix that.
What it does
Telepage connects to your Telegram channel via a bot webhook and turns every post into a searchable web card — automatically, in real time.
Every hashtag in your Telegram posts becomes a colored navigation filter. Every link gets its Open Graph metadata scraped. Every post gets an AI-generated summary and tags if you connect a Gemini key.
The tech stack
Pure PHP 8.1, SQLite with WAL mode, vanilla JS. No frameworks, no Composer, no build step, no MySQL. It runs on standard shared hosting — I tested it on Aruba (a very restrictive Italian host).
Telegram channel │ ▼ webhook (instant) PHP 8.1 + SQLite │ ▼ Your website — card grid, search, tag filtersTelegram channel │ ▼ webhook (instant) PHP 8.1 + SQLite │ ▼ Your website — card grid, search, tag filtersEnter fullscreen mode
Exit fullscreen mode
Interesting technical decisions
Session isolation per installation Multiple Telepage sites on the same domain (e.g. site.com/news/ and site.com/recipes/) need completely separate admin sessions. I solved this with:
session_name('tp_' . substr(md5(TELEPAGE_ROOT), 0, 12)); session_start();session_name('tp_' . substr(md5(TELEPAGE_ROOT), 0, 12)); session_start();Enter fullscreen mode
Exit fullscreen mode
Each installation path produces a unique session name — no shared cookies, no cross-login.
History Scanner Telegram's Bot API has no "get all past messages" endpoint. To import historical content I use the forwardMessage trick: forward each message ID from the channel to itself, read the content, then immediately delete the forwarded copy. It scans backwards from the most recent ID, skipping gaps from deleted messages.
AI integration Optional Google Gemini integration auto-tags and summarizes every post. The models available via the free tier change frequently — I built a cascade fallback that tries multiple model names in order and logs exactly which one succeeded.
What it looks like in production
I've been running it on two test channels:
-
A science/news channel: 23 posts, tagged by topic
-
A recipes channel: 952 posts, fully tagged and summarized by AI
The recipes site went from zero to 952 searchable, tagged posts in a few hours using the History Scanner.
What I'm less happy with
-
AI calls are currently synchronous in the admin panel — for large archives you click "Process AI" repeatedly. A proper background queue would be better.
-
The History Scanner requires manual ID tuning when posts are missing — not ideal for non-technical users.
-
No pagination on the install wizard, though the 5-step flow works fine in practice.
Try it
GitHub: github.com/scibilo/telepage
It's MIT licensed. Works on any PHP 8.1+ shared hosting with HTTPS. The install wizard takes about 5 minutes.
Feedback welcome — this is the first public release and I'm actively improving it.
DEV Community
https://dev.to/scibilo/telepage-i-built-a-self-hosted-php-app-that-turns-any-telegram-channel-into-a-website-2i2bSign in to highlight and annotate this article

Conversation starters
Daily AI Digest
Get the top 5 AI stories delivered to your inbox every morning.
More about
geminimodelreleasedatasette-enrichments-llm 0.2a1
<p><strong>Release:</strong> <a href="https://github.com/datasette/datasette-enrichments-llm/releases/tag/0.2a1">datasette-enrichments-llm 0.2a1</a></p> <blockquote> <ul> <li>The <code>actor</code> who triggers an enrichment is now passed to the <code>llm.mode(... actor=actor)</code> method. <a href="https://github.com/datasette/datasette-enrichments-llm">#3</a></li> </ul> </blockquote> <p>Tags: <a href="https://simonwillison.net/tags/enrichments">enrichments</a>, <a href="https://simonwillison.net/tags/llm">llm</a>, <a href="https://simonwillison.net/tags/datasette">datasette</a></p>
Blazor WASM's Deputy Thread Model Will Break JavaScript Interop - Here's Why That Matters
<h2> The Problem </h2> <p>Microsoft is changing how .NET runs inside WebAssembly. When you enable threading with <code><WasmEnableThreads>true</WasmEnableThreads></code>, the entire .NET runtime moves off the browser's main thread and onto a background Web Worker — what they call the <strong>"Deputy Thread" model</strong>.</p> <p>This sounds like a good idea on paper. The UI stays responsive. .NET gets real threads. Everyone wins.</p> <p>Except it breaks JavaScript interop. Not in a subtle, edge-case way. It breaks it <em>fundamentally</em>.</p> <h2> What Actually Happens </h2> <p>In traditional Blazor WASM (no threading), .NET and JavaScript share the same thread. When JavaScript calls <code>DotNet.invokeMethod</code>, the CPU jumps from the JS stack to the C# stack and back. It's fast. I
The hidden cost of GPT-4o: what every SaaS founder should know about per-user LLM spend it
<p>So you're running a SaaS that leans on an LLM. You check your OpenAI bill at the end of the month, it's a few hundred bucks, you shrug and move on. As long as it's not five figures, who cares, right?</p> <p>Wrong. That total is hiding a nasty secret: you're probably losing money on some of your users.</p> <p>I'm not talking about the obvious free-tier leeches. I'm talking about paying customers who are costing you more in API calls than they're giving you in subscription fees. You're literally paying for them to use your product.</p> <p><strong>The problem with averages</strong></p> <p>Let's do some quick, dirty math. GPT-4o pricing settled at around $3/1M tokens for input and $10/1M for output. It's cheap, but it's not free.</p> <p>Say you have a summarization feature. A user pastes in
Knowledge Map
Connected Articles — Knowledge Graph
This article is connected to other articles through shared AI topics and tags.
More in Releases
I Built a Game That Teaches Git by Making You Type Real Commands
<p>I work in IT, and there's one scene I keep witnessing. A developer joins the team, they're sharp, they ship features, they write clean code. And then someone asks them to rebase, and you can see the panic set in.</p> <p>It's not their fault. Git is taught badly.</p> <p>Every git tutorial I've ever seen follows the same formula: here's a diagram of branches, here's a table of commands, now go practice on your own repo and try not to destroy anything. It's like learning to drive by reading the car manual. Technically accurate. Practically useless.</p> <p>I've watched junior developers memorize <code>git add . && git commit -m "fix" && git push</code> like an incantation, terrified to deviate because the one time they tried <code>git rebase</code> they ended up in a state t
Orders of magnitude: use semitones, not decibels
I'm going to teach you a secret. It's a secret known to few, a secret way of using parts of your brain not meant for mathematics ... for mathematics. It's part of how I (sort of) do logarithms in my head. This is a nearly purposeless skill. What's the growth rate? What's the doubling time? How many orders of magnitude bigger is it? How many years at this rate until it's quintupled? All questions of ratios and scale. Scale... hmm. 'Wait', you're thinking, 'let me check the date...'. Indeed. But please, stay with me for the logarithms. Musical intervals as ratios, and God's joke If you're a music nerd like me, you'll know that an octave (abbreviated 8ve), the fundamental musical interval, represents a doubling of vibration frequency. So if A440 is at 440Hz, then 220Hz and 880Hz are also 'A'.

Maintaining Open Source in the AI Era
<p>I've been maintaining a handful of open source packages lately: <a href="https://pypi.org/project/mailview/" rel="noopener noreferrer">mailview</a>, <a href="https://pypi.org/project/mailjunky/" rel="noopener noreferrer">mailjunky</a> (in both Python and Ruby), and recently dusted off an old Ruby gem called <a href="https://rubygems.org/gems/tvdb_api/" rel="noopener noreferrer">tvdb_api</a>. The experience has been illuminating - not just about package management, but about how AI is changing open source development in ways I'm still processing.</p> <h2> The Packages </h2> <p><strong>mailview</strong> started because I missed <a href="https://github.com/ryanb/letter_opener" rel="noopener noreferrer">letter_opener</a> from the Ruby world. When you're developing a web application, you don

Kia’s compact EV3 is coming to the US this year, with 320 miles of range
At the New York International Auto Show on Wednesday, Kia announced that its compact electric SUV, the EV3, will be available in the US "in late 2026." The EV3 has been available overseas since 2024, when it launched in South Korea and Europe. The 2027 model coming to the US appears to have the same […]

Discussion
Sign in to join the discussion
No comments yet — be the first to share your thoughts!