# dsm-mini [English](README.md) · [Русский](README_RU.md) · [Español](README_ES.md) · [Português](README_PT.md) · [Deutsch](README_DE.md) · [Français](README_FR.md) · [Italiano](README_IT.md) · [Türkçe](README_TR.md) · **Українська** · [Polski](README_PL.md) [![Перевірки](https://github.com/alexlnos/dsm-mini/actions/workflows/ci.yml/badge.svg)](https://github.com/alexlnos/dsm-mini/actions/workflows/ci.yml) [![Ліцензія MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE) Telegram-бот з Mini App для керування домашнім NAS Synology: завантаження Download Station і файли File Station просто з месенджера, без VPN і вебінтерфейсу DSM. Кинули magnet-посилання в чат — бот кнопками запитав, куди качати, і поставив у чергу. Відкрили застосунок — видно, що завантажується, скільки лишилося, що лежить на дисках і як почувається NAS.

Огляд NAS Завантаження Завдання Файли Сховище

> Працює: бот, Mini App і сповіщення. Потрібен DSM 7 або новіший — на DSM 6 > пакет не встановиться, і там його ніхто не перевіряв. Перевірено на DSM 7.2.2 > з Download Station 4.1.2 та File Station 1.4.4. ## Що воно вміє **Завантаження** - Список завдань: поступ, швидкість, час до кінця, сіди й піри - Пауза, відновлення, видалення - Додавання magnet-посиланням, прямим посиланням і файлом `.torrent` - Вибір теки призначення з налаштовуваним списком швидкого доступу - Вибір файлів усередині роздачі та їхнього пріоритету - Повідомлення в чат, коли завдання завершилося або впало **Файли** - Огляд тек, попередній перегляд, вивантаження на NAS - Перейменування, копіювання, перенесення, видалення **Стан NAS** - Навантаження процесора й пам'яті, час роботи, мережа - Диски, пули та томи: температура, зайняте місце, здоров'я - Віртуальні машини та контейнери: запуск і зупинка - Журнал подій DSM **Сповіщення та налаштування** - Те, про що повідомляє сам DSM — радник із безпеки, диски, оновлення, — приходить у чат - Вибір, що бот може надсилати: нічого, лише завантаження, усе - Свій екран у головному меню DSM: там пакет налаштовується після встановлення і там само потім змінюється будь-яке налаштування, без перезапуску **Мова** Застосунок і бот говорять мовою, вибраною в Telegram: англійська, російська, іспанська, португальська, німецька, французька, італійська, турецька, українська, польська. Незнайома мова отримує англійську. --- ## Встановлення Півгодини, і більшість піде на сертифікат, а не на сам сервіс. Потрібен NAS Synology з DSM 7 і Download Station; більше нічого заздалегідь ставити не треба. > **Публічна адреса потрібна лише для Mini App.** Telegram відкриває Mini App > лише через `https://` зі справжнім сертифікатом — локальний `192.168.…` і > самопідписаний не відкриються. Без адреси бот працює сам — посилання, файли > `.torrent`, `/status` і сповіщення, — і відкривати NAS назовні не потрібно. > Три способи отримати адресу — у кроці 4, два з них обходяться без прокидання > портів на роутері. **1. Створити бота.** [@BotFather](https://t.me/BotFather) → `/newbot` → ім'я та логін, що закінчується на `bot`. У відповідь прийде токен; збережіть його, це пароль від вашого бота. **2. Дізнатися свій номер.** [@userinfobot](https://t.me/userinfobot) → Start. Він відповість рядком `Id`. **3. Завести користувача DSM для служби.** Панель керування → Користувач і група → Створити. Доступ лише до Download Station і File Station, без двоетапної перевірки — одноразовий код нізвідки взяти у файлі налаштувань. Адміністратора не давайте: служба вміє видаляти файли. Чи вистачає цьому обліковому запису прав, покаже кнопка **Перевірити обліковий запис** у вікні DSM mini (крок 6): вона входить від імені цього користувача й перелічує, що DSM йому дозволяє. **4. Отримати адресу для Mini App** — або пропустіть цей крок, і бот працюватиме сам. Адреса має відкриватися через `https://` на телефоні, де у вас Telegram. Способів три. Перший — через DSM, із прокиданням портів на роутері; його можна пропустити, якщо в NAS уже є домен із чинним сертифікатом: - Панель керування → Зовнішній доступ → DDNS → Додати, постачальник `Synology` — вийде щось на кшталт `alex-nas.synology.me`. - На роутері прокиньте на NAS порти **80** і **443**. Без 80 не випуститься сертифікат, без 443 не відкриється застосунок. - Панель керування → Безпека → Сертифікат → Додати → від Let's Encrypt, на те саме ім'я. Перевірте з телефона мобільним інтернетом: `https://alex-nas.synology.me:5001` має відкрити DSM без попереджень. Другий — **Cloudflare Tunnel**, без прокидання портів; потрібен домен, DNS якого в Cloudflare. Створіть тунель у панелі Cloudflare, встановіть пакет **Cloudflare Tunnel** із [SynoCommunity](https://synocommunity.com) з токеном цього тунелю й додайте тунелю публічне ім'я — скажімо, `mini.example.com` — зі службою `http://localhost:58080`. Третій — **Tailscale**, лише для своїх пристроїв. Встановіть Tailscale на NAS і на телефон, увімкніть сертифікати HTTPS у налаштуваннях DNS своєї мережі Tailscale й виконайте на NAS `sudo tailscale serve --bg 58080`: він видасть адресу на кшталт `https://nas.tail1234.ts.net`. Застосунок відкриватиметься, поки телефон під'єднано до Tailscale. **5. Встановити пакет.** Центр пакетів → Налаштування → Джерела пакетів → Додати, ім'я `dsm-mini` і адреса за вашою архітектурою: - Intel і AMD, більшість моделей: `https://alexlnos.github.io/dsm-mini/amd64.json` - ARM, бюджетні моделі: `https://alexlnos.github.io/dsm-mini/arm64.json` Далі Налаштування → Загальні → Рівень довіри → **Будь-який видавець**, і встановіть **DSM mini — Telegram Mini App** з розділу **Спільнота**. Не впевнені в архітектурі? Спробуйте `amd64`: невідповідний пакет просто не встановиться. Під час встановлення нічого не запитується. Або встановіть `.spk` з [випусків](https://github.com/alexlnos/dsm-mini/releases) вручну, через Центр пакетів → Ручне встановлення. **6. Налаштувати.** Відкрийте **DSM mini** в головному меню DSM або натисніть **Відкрити** в Центрі пакетів — він і сам підкаже це після встановлення. Заповніть значення, зібрані на кроках вище, — вікно пояснить кожне, — а в розділі **Доступ до Mini App** виберіть спосіб із кроку 4 або **Лише бот, без Mini App**. Натисніть **Зберегти**, а потім **Запустити** вгорі вікна. Статус там покаже, коли відповіли DSM і бот, а якщо не відповіли — що не так. Для першого способу правило зворотного проксі вікно створює саме: впишіть ім'я в поле **Спрямувати ім'я до служби**. Вручну це Панель керування → Портал входу → Додатково → Зворотний проксі → Створити. Джерело: `HTTPS`, ваше ім'я, порт `443`. Призначення: `HTTP`, `localhost`, порт `58080`. З тунелем чи Tailscale виберіть **Інший спосіб** і впишіть адресу, яку вони видали. > Порт **80** для цього імені не проксіюйте: через нього DSM продовжує > сертифікат, і перехоплення зламає продовження за три місяці. **7. Перевірити.** Якщо адреса є, `https://ваша-адреса/healthz` у браузері має відповісти `{"status":"ok"}`. Без підпису Telegram назовні нічого не віддається. **8. Відкрити застосунок.** Знайдіть бота за логіном, натисніть Start — поряд із полем введення з'явиться кнопка **Завантаження**. Надішліть йому будь-яке magnet-посилання, він запропонує теки кнопками. Без адреси кнопки не буде — посилання просто надсилайте боту в чат. ## Якщо щось пішло не так | Що бачите | У чому річ | Що робити | |---|---|---| | Бот мовчить на `/start` | Бот вимкнений або не налаштований, чи хибний токен | Відкрийте **DSM mini** в головному меню DSM: статус угорі скаже, що саме, а **Запустити** увімкне бота | | «Доступ до цього бота закрито» | Вашого ID немає в списку | Впишіть номер із кроку 2 в дозволені ID у вікні **DSM mini** | | Кнопки застосунку немає | Публічна адреса порожня — тоді працює лише бот — або не `https://` | Вікно **DSM mini**, розділ **Доступ до Mini App** | | Кнопка є, застосунок не відкривається | Не працює зворотний проксі або сертифікат | Відкрийте `https://ваша-адреса/healthz` у браузері | | «Відкрийте застосунок через бота» | Застосунок відкрито прямим посиланням у браузері | Так і задумано: відкривайте з бота | | «Доступ закрито: вашого Telegram ID…» | Сервіс вас не впізнав | У дозволених ID лише цифри, через кому | | Вікно пише, що DSM не прийняв вхід | Пароль, 2FA або права користувача | Крок 3: пароль без описок, 2FA вимкнена, застосунки дозволені | | Вікно пише, що Download Station не запущено | Її не встановлено або заборонено користувачеві | Центр пакетів і права з кроку 3 | | Пакет зупиняється одразу після запуску | Його порт зайнятий чимось іншим — журнал так і скаже | Змініть `LISTEN_ADDR` у `config.env` через SSH (див. нижче) | Перше, куди дивитися, — рядок стану вгорі вікна **DSM mini**: він каже, чи відповіли DSM і Telegram, а якщо ні — чому. Подробиці — у журналі пакета, `/var/packages/dsm-mini/var/dsm-mini.log`, він же відкривається з Центру пакетів. Журнал ведеться англійською, вікно, інтерфейс і повідомлення бота — вашою мовою. ### Змінити налаштування **Відкрийте DSM mini в головному меню DSM** — там усі налаштування. Пароль і токен лише на запис: залиште поле порожнім, і воно збереже попереднє. Збереження застосовується одразу: служба сама перезапускається з новими налаштуваннями, пакет перезапускати не треба. Налаштування лежать на NAS в одному файлі `/var/packages/dsm-mini/var/config.env` з правами `600`. Його можна виправити й через SSH (Панель керування → Термінал і SNMP → увімкнути SSH), а потім перезапустити пакет: ```bash sudo sed -i "s|^TELEGRAM_BOT_TOKEN=.*|TELEGRAM_BOT_TOKEN='ваш-новий-токен'|" /var/packages/dsm-mini/var/config.env sudo synopkg restart dsm-mini ``` Оновлення файл не чіпає, тому налаштування його переживають. ## Оновлення Якщо додано джерело пакетів, Центр пакетів сам покаже оновлення. Без джерела — завантажте свіжий `.spk` із [випусків](https://github.com/alexlnos/dsm-mini/releases) і поставте поверх. Налаштування й база в обох випадках залишаться: вони лежать у каталозі `var` пакета, а оновлення його не чіпає. ## Де зберігаються дані Усе в `/var/packages/dsm-mini/var/`: - `config.env` — налаштування з вікна DSM mini, права `600`; - `dsm-mini.db` — база SQLite: закріплені теки, мова й останні відомі статуси завдань, за якими сервіс розуміє, про що вже повідомляв; - `dsm-mini.log` — журнал. Оновлення пакета зберігає всі три. Видалення пакета — видаляє. ## Безпека Сервіс виставлений в інтернет і вміє видаляти файли на NAS, тому: - **Окремий користувач DSM**, а не адміністратор (крок 3). - **Без двоетапної перевірки** в цього облікового запису: одноразовий код у конфігурації працювати не буде. - **Дозволені ID — білий список.** Порожній список закриває доступ усім, а не відкриває. - Кожен запит до `/api/` перевіряється двічі: підпис `initData` ключем від токена бота й ідентифікатор у списку дозволених. Підпис доводить лише те, що людина відкрила бота, — відкрити його може будь-хто. - Назовні віддається загальна фраза, подробиці — в журнал: повідомлення про те, що саме не зійшлося в підписі, підказувало б, як його підібрати. - Токен бота й пароль DSM живуть лише в `config.env` на самому NAS із правами `600` і в журнал не потрапляють: при відмові пишеться причина, але не значення. - Служба слухає тільки `127.0.0.1` — тобто із самого NAS. Усе ззовні йде через те, що обслуговує публічну адресу, — зворотний проксі DSM, тунель чи Tailscale, — він же розбирає TLS. Без адреси ззовні до неї не доходить нічого. ## Розробка ```bash cd web && npm install && npm run build # Mini App потрапить у internal/web/dist cd .. && go build ./cmd/dsm-mini # бінарник із вбудованим застосунком go test ./... ``` Фронтенд окремо, з автооновленням: ```bash cd web && npm run dev # ходить у бекенд на localhost:58080 ``` Локальний запуск бекенда читає `config.env` зі `STATE_DIR`, як і пакет, а змінні середовища доповнюють те, чого у файлі немає. Зручно тримати їх у файлі: ```bash cp .env.example .env # заповніть set -a; . ./.env; set +a go run ./cmd/dsm-mini ``` Зібраний інтерфейс лежить у репозиторії (`internal/web/dist`) — його забирає `go:embed`. Після правок фронтенду перезберіть і закомітьте результат, інакше перевірки не пройдуть. Інтеграційні тести працюють проти справжнього NAS і типово пропускаються: ```bash DSM_URL=https://192.168.1.10:5001 DSM_USER=... DSM_PASSWORD=... \ DSM_INSECURE_TLS=true go test -tags=integration ./... ``` Тести, які змінюють стан NAS, потребують окремого дозволу: `DSM_TEST_MUTATIONS=1`, а для файлових операцій ще й `DSM_TEST_FOLDER` — теку, всередині якої можна створювати тимчасові файли. Усе створене вони прибирають за собою. Нова мова інтерфейсу — один файл словника з кожного боку: `web/src/i18n/<код>.ts` та `internal/i18n/<код>.go`. Пропустити рядок не вийде: на фронтенді за цим стежить тип, на сервері — тест. Код, коментарі та журнал у проєкті — англійською; інші мови живуть лише у словниках. Подробиці — у [CLAUDE.md](CLAUDE.md). ## Особливості Synology API Web API Synology подекуди поводиться не так, як написано в документації: та сама дія відповідає в трьох різних форматах, `limit = -1` кладе File Station, а `_sid` під час вивантаження файлу треба передавати інакше, ніж усюди. Усе, що з'ясовано на живому NAS, зібрано в [docs/synology-api.md](docs/synology-api.md). ## Ліцензія [MIT](LICENSE)