The Link That Won’t Tap — Opening Obsidian Notes From Telegram
Self-Hosting Build Guide, Part 15. Finishing the build guide isn’t the end — once you actually use it, follow-on problems surface. The note we synced in Part 13: its link wouldn’t tap on the phone.
← Previous: Part 13 — My Notes on My Server (Obsidian LiveSync)
TL;DR
- An Obsidian note carries its own link, shaped like
obsidian://open?vault=...&file=... - Send that link over Telegram and you get gray dead text, not a blue link — it won’t tap
- Why: chat apps auto-linkify only
http/https. Custom schemes likeobsidian://are ignored - Fix: insert one https hop — a “shuttle” page that receives over https and bounces the browser to
obsidian:// - We put that shuttle on a Cloudflare Worker (serverless) instead of the home server — works even when the home machine is off, $0
1. Symptom — A Link Gone Gray and Dead
Obsidian gives every note its own link. Right-click a note and hit “Copy Obsidian URL” and you get something like obsidian://open?vault=MyVault&file=folder/note. I expected it to turn blue in Telegram, but it came up as gray plain text. Tapping does nothing. It was never a link — just letters.
2. Cause — Chat Apps Only Linkify http/https
A chat app scans the text of a message and, when it spots a URL, turns it into a tappable link on its own. But that auto-conversion applies only to http:///https:// (and Telegram’s own tg://). App-specific custom schemes like obsidian://, notion://, slack:// aren’t converted — they stay as plain text. Telegram’s iOS repo has the same issue on file: links with a custom URI scheme aren’t clickable.
Can’t you route around it with a button or a markdown link? No. The inline buttons and links a bot attaches to a message also allow only http/https/tg. Custom schemes are rejected.
3. The Standard Pattern — Insert One https “Shuttle”
Since the custom scheme can’t go directly, route it through https once in the middle.
- Send Telegram an https link → it becomes a blue link
- Tap it and the browser opens that https page
- The page’s JavaScript bounces to
obsidian://→ Obsidian opens
This pattern isn’t new. A free public service called obsid.net does exactly this one thing — a static page that takes vault and file and hands the browser off to obsidian://. You could just use it.
4. So Why Build My Own
The reason I built my own anyway, despite obsid.net, is the same one that runs through this series.
- No third party in the path — my vault name and note paths don’t pass through someone else’s server (even one that claims no logging)
- My own domain — one line,
o.mydomain, and the link is mine - I control the page — I can add the button to tap when the auto-redirect is blocked, and the filename that shows which note it is (this matters because of the traps in section 7)
At first I dropped the page into the static folder of another app I already had running. It worked, but it meant wedging a notification redirect inside an unrelated app — the boundaries got dirty. A redirect belongs to no single app; it’s a generic utility. So I pulled it out and let it stand alone.
5. Where to Put It — Home Server vs the Edge
If it’s going to stand alone, it’s one of two places.
| A small web server on the home box | Cloudflare Worker (edge) | |
|---|---|---|
| Runs when | only if the home machine is on | even when the home machine is off |
| Certificate | issue/renew yourself | automatic |
| Cost | electricity | free (100k requests/day) |
| Dependency | none | Cloudflare |
A redirect is a one-second static response, so there’s no reason to keep the home server awake for it. I picked the Cloudflare Worker — put a snippet of code on the cloud edge and it answers without you running a server (this is called serverless). The domain I bought in Part 6 is already on Cloudflare, so attaching one subdomain is all it takes.
6. How It Works — https Receives, Bounces to obsidian://
What the Worker does is short. It takes ?f=note-path and returns a single HTML page that turns it into an obsidian:// link.
export default {
async fetch(request) {
const url = new URL(request.url);
const file = url.searchParams.get('f') || '';
const vault = url.searchParams.get('v') || 'MyVault';
const uri = 'obsidian://open?vault=' +
encodeURIComponent(vault) + '&file=' + encodeURIComponent(file);
const html = '<!doctype html><meta charset=utf-8>'
+ '<p>' + file + '</p>'
+ '<a href="' + uri + '">Open note</a>'
+ '<script>setTimeout(function(){location.href=' + JSON.stringify(uri) + '},350)</' + 'script>';
return new Response(html, {
headers: { 'content-type': 'text/html; charset=utf-8' }
});
}
}
To Telegram you send only https://o.mydomain/?f=note-path. That’s https, so it becomes a blue link; tap it and the page above comes up and hands off to Obsidian.
7. Three Traps
① The auto-redirect gets blocked. Even if you set location.href = obsidian://... for an automatic jump, mobile browsers (especially Android Chrome and the in-app browsers inside chat apps) sometimes block, for security, a custom-scheme navigation the user didn’t tap themselves (“Navigation is blocked”). So you can’t lean on the auto-redirect alone — always include an “Open note” button for the user to tap. That’s why an auto-only page fails now and then.
② The vault name differs per device. The X in obsidian://open?vault=X must exactly match the vault’s display name registered on that device. If it opens on your PC but the phone says “note not found,” nine times out of ten the vault name differs. The Obsidian forum has the same case: the app opens on Android but the note doesn’t. Match it with &v=PhoneVaultName in the link.
③ Sync comes first. A link opens a note; it doesn’t create one. The note has to be synced to the phone (Part 13, LiveSync) for it to open.
8. Cost
- Cloudflare Worker: $0 (free plan, 100k requests/day)
- Domain: already owned (Part 6), no extra charge for a subdomain
- Home server load: none (the edge answers)
In One Line
Chat apps turn only http/https into links. An app link like obsidian:// needs one https shuttle inserted to become tappable. Put that shuttle on a Cloudflare Worker and it runs free, independent of your home server. Just include a button, since the auto-redirect can be blocked, and match the vault name to the device.