Skip to content
alexlnosPublic

About

Telegram bot with a Mini App for a Synology NAS: downloads, files, disks, containers

Topics

Resources

Stars

3 stars

Watchers

0 watching

Forks

Repository files navigation

dsm-mini

English · Русский · Español · Português · Deutsch · Français · Italiano · Türkçe · Українська · Polski

Checks MIT license

A Telegram bot with a Mini App for running a home Synology NAS: Download Station downloads and File Station files straight from the messenger, with no VPN and no DSM web interface.

Drop a magnet link into the chat — the bot asks with buttons where to put it and queues it. Open the app — you see what is downloading, how long is left, what is on the disks and how the NAS is feeling.

NAS overview Downloads A task Files Storage

Working: the bot, the Mini App and notifications. Requires DSM 7 or newer — the package will not install on DSM 6, and it has never been tested there. Checked on DSM 7.2.2 with Download Station 4.1.2 and File Station 1.4.4.

What it can do

Downloads

  • The task list: progress, speed, time left, seeds and peers
  • Pause, resume, delete
  • Adding by magnet link, by direct link and by .torrent file
  • Choosing the destination folder, with a configurable quick-access list
  • Choosing the files inside a torrent and their priority
  • A message in the chat when a task finishes or fails

Files

  • Browsing folders, previews, uploading to the NAS
  • Rename, copy, move, delete

NAS state

  • CPU and memory load, uptime, network
  • Disks, pools and volumes: temperature, space used, health
  • Virtual machines and containers: start and stop
  • The DSM event log

Notifications and settings

  • What DSM announces itself — the security advisor, disks, updates — reaches the chat
  • A choice of what the bot may send: nothing, downloads only, everything
  • A screen of its own in the DSM main menu: the package is set up there after installation, and every setting is changed there later, without a restart

Language

The app and the bot speak the language chosen in Telegram: English, Russian, Spanish, Portuguese, German, French, Italian, Turkish, Ukrainian, Polish. An unknown language gets English.


Installation

Half an hour, most of it spent on the certificate rather than on the service. You need a Synology NAS with DSM 7 and Download Station; nothing else has to be installed beforehand.

The public address is only for the Mini App. Telegram opens a Mini App only over https:// with a real certificate — a local 192.168.… or a self-signed one will not open. Without an address the bot works on its own — links, .torrent files, /status and notifications — with nothing on the NAS reachable from outside. Step 4 has three ways to get one, two of them with no ports opened on the router.

1. Create the bot. @BotFather → /newbot → a name and a username ending in bot. It answers with a token; keep it, it is the password to your bot.

2. Find out your number. @userinfobot → Start. It answers with the Id line.

3. Make a DSM user for the service. Control Panel → User & Group → Create. Access to Download Station and File Station only, no two-factor verification — a one-time code cannot be typed in from a configuration file. Do not give it an administrator: the service can delete files. Whether the account is enough, the Check the account button in the DSM mini window (step 6) shows: it signs in as this user and lists what DSM lets it do.

4. Get an address for the Mini App — or skip this step and use the bot on its own. The address has to open over https:// on the phone you use Telegram on. There are three ways. The first goes through DSM and needs ports forwarded on the router; skip it if the NAS already has a domain with a valid certificate:

  • Control Panel → External Access → DDNS → Add, provider Synology — that gives something like alex-nas.synology.me.
  • On the router, forward ports 80 and 443 to the NAS. Without 80 the certificate will not be issued, without 443 the app will not open.
  • Control Panel → Security → Certificate → Add → from Let's Encrypt, for that same name.

Check it from a phone on mobile internet: https://alex-nas.synology.me:5001 should open DSM with no warnings.

The second is Cloudflare Tunnel, with no ports opened; it needs a domain whose DNS is on Cloudflare. Create a tunnel in the Cloudflare dashboard, install the Cloudflare Tunnel package from SynoCommunity with the tunnel's token, and give the tunnel a public hostname — say mini.example.com — with the service http://localhost:58080.

The third is Tailscale, for your own devices only. Install Tailscale on the NAS and on the phone, turn on HTTPS certificates in your tailnet's DNS settings, and run sudo tailscale serve --bg 58080 on the NAS: it prints an address like https://nas.tail1234.ts.net. The app then opens while the phone is connected to Tailscale.

5. Install the package. Package Center → Settings → Package Sources → Add, name dsm-mini and the address for your architecture:

  • Intel and AMD, most models: https://alexlnos.github.io/dsm-mini/amd64.json
  • ARM, budget models: https://alexlnos.github.io/dsm-mini/arm64.json

Then Settings → General → Trust Level → Any publisher, and install DSM mini — Telegram Mini App from the Community section. Not sure about the architecture? Try amd64: a package that does not fit is simply refused.

Nothing is asked during installation. Or install the .spk from the releases by hand, through Package Center → Manual Install.

6. Set it up. Open DSM mini from the DSM main menu, or press Open in Package Center — it says so itself when the installation is done. Fill in the values collected in the steps above — the window explains each one — and under Mini App access pick the way from step 4, or The bot only, no Mini App. Press Save, then Start at the top of the window. The status there says when DSM and the bot have answered, and what is wrong if they have not.

For the first way, the window creates the reverse proxy rule itself: type your name under Point a name at the service. By hand it is Control Panel → Login Portal → Advanced → Reverse Proxy → Create. Source: HTTPS, your name, port 443. Destination: HTTP, localhost, port 58080. With a tunnel or Tailscale, pick Another way and enter the address they gave.

Do not proxy port 80 for this name: DSM renews the certificate through it, and intercepting it breaks the renewal three months later.

7. Check. With an address, https://your-address/healthz in a browser should answer {"status":"ok"}. Nothing is given away without a Telegram signature.

8. Open the app. Find the bot by its username, press Start, and a Downloads button appears next to the input field. Send it any magnet link — it offers folders as buttons. Without an address there is no such button: send the links to the bot in the chat.

If something went wrong

What you see What it is What to do
The bot is silent on /start The bot is switched off or not set up, or the token is wrong Open DSM mini in the DSM main menu: the status at the top says which, and Start switches the bot on
"Access to this bot is closed" Your ID is not on the list Add the number from step 2 to the allowed IDs in the DSM mini window
There is no app button The public address is empty — the bot on its own — or not https:// The DSM mini window, Mini App access
The button is there, the app does not open The reverse proxy or the certificate is not working Open https://your-address/healthz in a browser
"Open the app through the bot" The app was opened by a direct link in a browser That is intended: open it from the bot
"Access denied: your Telegram ID…" The service did not recognise you The allowed IDs take digits only, comma separated
The window says DSM refused the sign-in The password, 2FA or the user's permissions Step 3: password without typos, 2FA off, applications allowed
The window says Download Station is not running It is not installed, or is denied to the user Package Center and the permissions from step 3
The package stops right after starting Its port is taken by something else — the log says so Change LISTEN_ADDR in config.env over SSH (see below)

The first place to look is the status line at the top of the DSM mini window: it says whether DSM and Telegram have answered and, if not, why. The details are in the package log, /var/packages/dsm-mini/var/dsm-mini.log, which also opens from Package Center.

Changing the settings

Open DSM mini in the DSM main menu — every setting is there. The password and the token are write-only: leave a field empty and it keeps what it had. A save applies at once: the service starts again with it by itself, and the package does not have to be restarted.

The settings live in one file on the NAS, /var/packages/dsm-mini/var/config.env, mode 600. It can also be edited over SSH (Control Panel → Terminal & SNMP → Enable SSH); restart the package afterwards:

sudo sed -i "s|^TELEGRAM_BOT_TOKEN=.*|TELEGRAM_BOT_TOKEN='your-new-token'|" /var/packages/dsm-mini/var/config.env
sudo synopkg restart dsm-mini

An upgrade leaves the file alone, which is why the settings survive an update.

Updating

If the package source was added, Package Center shows the update itself. Without a source, download the fresh .spk from the releases and install it over the old one.

The settings and the database survive either way: they live in the package's var directory, which an upgrade does not touch.

Where the data is kept

Everything is in /var/packages/dsm-mini/var/:

  • config.env — the settings from the DSM mini window, mode 600;
  • dsm-mini.db — an SQLite database: the pinned folders, the language and the last known task statuses, from which the service knows what it has already reported;
  • dsm-mini.log — the log.

An upgrade of the package keeps all three. Uninstalling removes them.

Security

The service is exposed to the internet and can delete files on the NAS, so:

  • A separate DSM user, not an administrator (step 3).
  • No two-factor verification on that account: a one-time code cannot work from a configuration file.
  • The allowed IDs are an allow list. An empty list closes access to everyone, it does not open it.
  • Every request to /api/ is checked twice: the initData signature with a key derived from the bot token, and the id against the allowed list. The signature only proves that a person opened the bot — and anyone can open it.
  • The outside gets a generic phrase, the details go to the log: a message saying exactly what did not match in the signature would be a hint on how to forge it.
  • The bot token and the DSM password live only in config.env on the NAS, mode 600, and never reach the log: on a refusal the reason is written, never the value.
  • The service listens on 127.0.0.1 only — from the NAS itself. Everything from outside comes through whatever serves the public address — the DSM reverse proxy, a tunnel or Tailscale — which also terminates TLS. With no address, nothing from outside reaches it at all.

Development

cd web && npm install && npm run build   # the Mini App lands in internal/web/dist
cd .. && go build ./cmd/dsm-mini         # a binary with the app embedded
go test ./...

The frontend on its own, with hot reload:

cd web && npm run dev    # talks to the backend on localhost:58080

Running the backend locally reads config.env in STATE_DIR, the way the package does, and environment variables fill in what the file does not say. It is convenient to keep them in a file:

cp .env.example .env     # fill it in
set -a; . ./.env; set +a
go run ./cmd/dsm-mini

The built interface is in the repository (internal/web/dist) — go:embed picks it up. After changing the frontend, rebuild and commit the result, otherwise the checks will not pass.

Integration tests run against a real NAS and are skipped by default:

DSM_URL=https://192.168.1.10:5001 DSM_USER=... DSM_PASSWORD=... \
  DSM_INSECURE_TLS=true go test -tags=integration ./...

Tests that change the state of the NAS need separate permission: DSM_TEST_MUTATIONS=1, and for file operations also DSM_TEST_FOLDER — the folder inside which temporary files may be created. They delete everything they created.

A new interface language is one dictionary file on each side: web/src/i18n/<code>.ts and internal/i18n/<code>.go. You cannot miss a string: on the frontend the type watches for that, on the server a test does.

Synology API quirks

The Synology Web API behaves differently from its documentation in places: one and the same action answers in three different shapes, limit = -1 takes File Station down, and _sid during a file upload has to be passed differently from everywhere else. Everything learned on a live NAS is collected in docs/synology-api.md.

License

MIT

About

Telegram bot with a Mini App for a Synology NAS: downloads, files, disks, containers

Topics

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages