Back up notes, folders and your whole vault to a Telegram channel or chat with your own bot. Type a trigger in a note to send it instantly.
Back up your Obsidian notes to a Telegram channel (or group, or private chat) with your own Telegram bot. Send the current note with one command, type ;;backup inside a note to push it instantly, or let the plugin back up your whole vault on a schedule. Telegram gives you free, unlimited cloud storage that you can reach from any device, and this plugin turns it into a fast, searchable backup history for your vault.
;;backup anywhere in a note and it is sent immediately; the trigger text disappears from the note.;;send to send only that line (a quick message, a reminder, an idea) to your channel..md file (restorable), readable Telegram messages (headings, bold, lists, check boxes, quotes, code blocks…), or automatic (text when short, file when long).#project/alpha → #project_alpha), so you can search your channel by tag.https://github.com/SoheilShiravi/Obsidian-Telegram-Backup.main.js, manifest.json and styles.css from the latest release.<your vault>/.obsidian/plugins/telegram-backup/ and copy the three files into it. (The .obsidian folder is hidden on some systems.)The plugin needs Obsidian 1.13.2 or newer.
Setting up takes about five minutes. You need the Telegram app on your phone or computer.
/newbot.My Vault Backup.bot, for example my_vault_backup_bot. If the name is taken, try another one.1234567890:AAHdqTcvCH1vGWJxfSeofSAs0K5PALDsaw. Copy it.[!WARNING] Keep the token secret. Anyone with the token can control your bot. If it ever leaks, open @BotFather, send
/revoke, pick your bot, and use the new token.
A private channel is the best place for backups: only you can see it, and it can hold an unlimited number of files.
Give it a name such as Obsidian Backups, choose Private Channel, and finish creating it. You can skip adding members.
You can also use a group, a group with topics, or a private chat with your bot. See Other destinations.
telegram-backup-token (lowercase letters, numbers and dashes) and paste the token from BotFather as the value. Then select the new secret and select Save./start to your bot) and select Detect again. Telegram only remembers these updates for 24 hours.You're done. Open a note and run Telegram Backup: Back up current note, or type ;;backup at the end of the note.
If Detect does not work (for example because another app is reading your bot's updates), use one of these:
@my_backups.https://web.telegram.org/a/. The address ends with the chat ID, for example #-1001234567890.https://api.telegram.org/bot<YOUR_TOKEN>/getUpdates in a browser (replace <YOUR_TOKEN>). Look for "chat":{"id":-100….Channel and supergroup IDs start with -100.
/setjoingroups to BotFather and enable it.https://t.me/c/1234567890/42/100, the topic ID is 42.All commands are in the command palette (Ctrl/Cmd + P) under Telegram Backup. None of them has a default hotkey; you can assign your own in Settings → Hotkeys.
With triggers enabled (they are by default):
| Type this | What happens |
|---|---|
;;backup |
The trigger is removed and the whole note is backed up, including changes that are not saved yet. |
Buy milk ;;send |
The trigger is removed and only Buy milk is sent as a message, followed by the note name. |
;;send on an empty line |
The paragraph above the empty line is sent. |
The trigger fires the moment you type its last character, in both Live Preview and Source mode. Undoing the removal does not send the note again. You can change both triggers in the settings, for example to /backup (if you do not use Obsidian's Slash commands core plugin) or !tg.
Select text and run Send selected text, or right-click the selection and choose Send selection to Telegram.
| Command or menu | Contents |
|---|---|
| Back up the entire vault as zip archives | All files (or only notes, see settings) except excluded folders and tags. |
| Back up files changed since the last vault backup | Only files modified since the last vault or changes backup. The first one includes everything. |
| Back up a folder as a zip archive, or right-click a folder → Back up folder to Telegram | One folder and its subfolders. |
| Select several files in the file explorer → right-click → Back up … items to Telegram | The selected files and folders. |
Large backups are split into several archives (MyVault-2026-10-18_2130-part1.zip, …-part2.zip, …). Every part is a complete zip file on its own; extract all parts into the same folder to get everything back. A progress notice with a Cancel button is shown while an archive is created and uploaded. Each archive caption has a hashtag (#vault_backup, #changes_backup, #folder_backup, #files_backup) so you can find them quickly in Telegram.
If you use the plugin on several devices with a synced vault, turn on scheduled backups on one device only.
Telegram downloads folder of your vault with Download.Restoring works for notes that were sent as a file (the default format). Telegram only lets bots download files of up to 20 MB, and only backups that are still in the plugin's history can be restored from inside Obsidian. You can always download any file manually in Telegram.
Show backup history lists recent backups with their time, size and format, failures with the reason, links to open each message in Telegram (for channels and groups), and restore buttons. Show backups of current note shows only the current note. On desktop the status bar shows when the last backup happened; select it to open the history.
Obsidian's command line interface (desktop) can start backups, for example from a cron job or the Windows Task Scheduler. Turn it on in Settings → General → Command line interface. If Obsidian is not running, the first command starts it; add vault="My vault" to target a specific vault.
obsidian telegram-backup # status
obsidian telegram-backup:vault # back up the whole vault
obsidian telegram-backup:changes # back up changed files
obsidian telegram-backup:note path="Inbox/Idea.md" # back up one note
obsidian telegram-backup:send text="Hello from the terminal"
| Setting | Description | Default |
|---|---|---|
| Bot token | Secret that holds the token from BotFather. | — |
| Chat ID | Channel, group or chat that receives backups. | — |
| Topic ID | Topic in a group with topics. | empty |
| Send notes as | File (exact copy), text messages, or text when short and a file when long. | File |
| Text style | Formatted, plain text, or a code block that is easy to copy. | Formatted |
| Leave out properties | Skip the YAML properties block in text messages. | On |
| Caption template | Caption of files and header of text messages. See Caption template. | see below |
| Attachments | Send as separate files, bundle with the note in a zip archive, or do not send. | Separate files |
| Send unchanged attachments again | Re-send attachments even if they did not change. | Off |
| When a note is backed up again | Post a new message (keep every version) or update the previous message. | New message |
| Add the note name to sent text | Selections and ;;send lines end with the note name. |
On |
| Enable triggers, Backup trigger, Send trigger | In-note triggers. | On, ;;backup, ;;send |
| Back up notes when they change, Wait after the last change | Automatic note backups. | Off, 5 min |
| Scheduled vault backup, Frequency, What to back up | Scheduled archives. | Off, every day, whole vault |
| Skip when nothing changed | Skip a scheduled full backup when no file changed. | On |
| Run on mobile devices | Allow scheduled backups on mobile. | Off |
| Files in vault archives | Notes and attachments, or notes, canvases and bases only. | Notes and attachments |
| Include the configuration folder | Add .obsidian (settings, themes, plugins) to full vault backups. Other plugins' settings can contain passwords and API keys. |
Off |
| Maximum archive size | Size of each archive part (5–47 MB). | 45 MB |
| Excluded folders, Excluded tags | Left out of automatic backups and archives. Notes you back up explicitly are always sent. | empty |
| Send silently | Notifications without sound. | Off |
| Protect content | Prevent forwarding and saving of backup messages in Telegram. | Off |
| Show status bar item, Show success notifications | Interface options. | On |
| Bot API server | Change only for a self-hosted Bot API server or a proxy you trust. | https://api.telegram.org |
| History size | Number of backups kept in the history (50–1000). | 300 |
All settings appear in Obsidian's settings search.
The caption template is used as the caption of backup files and as the header of text messages. It supports Telegram HTML formatting (<b>, <i>, <u>, <s>, <code>, <a href="…">) and these placeholders:
| Placeholder | Value |
|---|---|
{{title}} |
Note name without extension |
{{path}} |
Path in the vault, for example Projects/Plan.md |
{{folder}} |
Folder of the note (/ for the vault root) |
{{vault}} |
Vault name |
{{tags}} |
Tags as Telegram hashtags |
{{date}}, {{time}}, {{datetime}} |
Current date and time |
{{created}}, {{modified}} |
Creation and modification time of the file |
{{words}}, {{chars}} |
Word and character count of a note |
{{size}} |
File size, for example 12.4 KB |
Dates accept any Moment.js format: {{date:DD MMMM YYYY}}, {{modified:HH:mm}}. A line whose placeholders are all empty is removed, so a tags line disappears for notes without tags.
The default template:
📝 <b>{{title}}</b>
📁 <code>{{path}}</code>
🕒 {{datetime}}
{{tags}}
| In Obsidian | In Telegram |
|---|---|
| Headings | Bold lines |
**bold**, *italic*, ~~strike~~, ==highlight== |
Bold, italic, strikethrough, underline |
`code` and code blocks |
Monospace, code blocks with the language name |
- [ ] task, - [x] done |
☐ task, ☑ done |
| Callouts and quotes | Quotes; folded callouts become expandable quotes |
[[Note|alias]], [text](https://…) |
The alias, clickable links |
![[image.png]] |
🖼 image.png (the image itself is sent as an attachment) |
| Tables, math | Monospace blocks |
%% comments %% |
Removed |
Long notes are split into several messages (at most 4096 characters each). A note that would need more than 10 messages is sent as a file instead.
These limits come from the Telegram Bot API:
| Limit | Value |
|---|---|
| Text message | 4096 characters |
| File caption | 1024 characters (longer captions are shortened) |
| File upload | 50 MB per file (larger attachments are skipped and reported) |
| File download (restore) | 20 MB per file |
| Sending speed | About 1 message per second and 20 messages per minute per chat; the plugin waits when Telegram asks it to slow down |
The plugin talks to the Telegram Bot API over HTTPS. If Telegram is blocked in your country, choose one of these options:
VPN: a VPN that routes all traffic of your device works for Obsidian on desktop and mobile without any change in the plugin.
System proxy (desktop): Obsidian follows the proxy configured in your operating system's network settings, so a proxy app in "system proxy" mode works too.
Your own Bot API server: run the official Telegram Bot API server on a server you control, and set Bot API server to its address. A self-hosted server also raises the upload limit to 2000 MB.
Your own reverse proxy: forward requests to api.telegram.org through a server you control, for example a small Cloudflare Worker:
export default {
async fetch(request) {
const url = new URL(request.url);
url.hostname = "api.telegram.org";
return fetch(new Request(url, request));
},
};
Then set Bot API server to the worker's address, such as https://my-proxy.example.workers.dev.
[!WARNING] Only use servers you trust. Every request contains your bot token and your notes. Never point the plugin at a proxy run by someone else.
https://api.telegram.org by default), through two kinds of requests: Bot API calls (/bot<token>/<method>, to send, edit and check messages and files) and file downloads (/file/bot<token>/<path>, only when you restore or download a backup). It sends data only when you start a backup or when you turn on automatic or scheduled backups.data.json, so it is not synced or committed to git with your vault. Obsidian encrypts secrets with your operating system's secret store; on systems without one (some Linux desktops), it shows a warning that secrets are stored without encryption.data.json (in .obsidian/plugins/telegram-backup/) keeps the settings and the backup history: note paths, times, message links and Telegram file IDs.| Message or problem | What to do |
|---|---|
| Telegram rejected the bot token | Copy the token from BotFather again (send /mybots → your bot → API Token) and update the secret in Settings → Keychain. Make sure the secret is linked in Bot token. |
| Chat not found | Check the chat ID, make sure the bot was added to the channel or group, and try Detect. |
| The bot is not allowed to post in this chat | Make the bot an administrator of the channel with Post messages. In a group, allow it to send messages. |
| Open your bot in Telegram and press Start | For a private chat, open your bot in Telegram and select Start once. |
| Could not reach Telegram | Check your internet connection. If Telegram is blocked, see If Telegram is blocked where you live. Check the Bot API server setting. |
| The file is too large | Bots can upload up to 50 MB per file. Lower Maximum archive size, or exclude folders with large videos. |
| Detect finds no chats | Post a message in the channel (or send /start to the bot) and try again within 24 hours. If another app uses the same bot, enter the ID manually. |
| A trigger does nothing | Check that triggers are on, that you are in a Markdown note in Live Preview or Source mode, and that you typed the exact trigger text. |
| A scheduled backup did not run | Obsidian must be open. On mobile, turn on Run on mobile devices. Last scheduled backup in the settings shows when it last ran. |
| Restore is missing | Only notes sent as a file, up to 20 MB, and still in the history can be restored. |
Can I restore my whole vault from Telegram? Yes. Download all parts of a vault backup from your channel, extract them into an empty folder, and open that folder as a vault in Obsidian. For a recent state, extract the last full backup first and then the newer "changed files" archives in order.
Does it work on my phone? Yes, on Android and iOS. The status bar item is desktop-only, and scheduled backups are off on mobile unless you turn them on.
Will my channel fill up with copies? Each backup is a new message by default, which gives you a version history. Choose Update the previous message to keep one message per note instead. Unchanged notes are never sent automatically, and unchanged attachments are not re-sent.
Can I use several vaults? Yes. Use a separate channel, or one channel for all vaults: captions and archive names include the vault name.
Why is a note sent as a file even though I chose text messages? Notes that would need more than 10 messages are sent as a file so the chat is not flooded.
You need Node.js 22 or newer.
npm install # install dependencies
npm run dev # rebuild main.js on every change
npm run build # type-check and create a production build
npm run lint # check the code with eslint-plugin-obsidianmd
npm test # run the unit tests
To try your changes, copy main.js, manifest.json and styles.css into <vault>/.obsidian/plugins/telegram-backup/ (or create a symbolic link to this folder) and reload Obsidian. The Hot-Reload plugin reloads the plugin automatically after each build.
src/
├── main.ts Plugin lifecycle, settings and state storage
├── settings.ts Settings, defaults and validation
├── settings-tab.ts Settings tab (declarative setting definitions)
├── commands.ts Commands and context menus
├── triggers.ts ;;backup and ;;send editor triggers (CodeMirror 6)
├── actions.ts Notices, status bar and error reporting
├── cli.ts Obsidian command line handlers
├── backup/ Note, archive, automatic and restore logic
├── format/ Markdown → Telegram HTML, message splitting, templates
├── telegram/ Bot API client (requestUrl), multipart uploads, errors
├── zip/ ZIP writer and archive splitting (deflate by fflate)
├── ui/ Modals, status bar and progress notice
└── utils/ Small helpers
test/ Unit tests (Node.js test runner)
Releases are built by GitHub Actions: npm version patch updates manifest.json and versions.json and creates the version tag, and pushing the tag publishes a release named after the version with main.js, manifest.json and styles.css attached.