Telegram-бот на Dart + Docker + VDS
В этой статье я хочу поделиться своим опытом создания Telegram-бота написанного на Dart и запущенного через Docker на VDS.
Оригинал статьи размещён тут.
В конце у вас будет работающий Telegram-бот, написанный на Dart, запущенный в контейнере Docker и размещенный на VDS. Вы сможете отправлять сообщения боту и получать ответы, а также отправлять фотографии, хранить их на VDS и удалять, при необходимости.
Эта статья представляет собой реальный кейс, когда мне пришлось загружать фотографии на VDS (которые пользователь отправил боту), отправлять их в базу данных, а затем удалять их с VDS.
И так, для того, чтобы все это сделать, нам нужно следующее:
- Создать нового бота с помощью BotFather;
- Создать новый dart-проект и написать код бота;
- Настроить все необходимые пакеты и плагины на VDS;
- Запустить контейнер Docker и протестировать бота.
Telegram-бот и VDS, которые использовались для этой статьи, удалены, поэтому все данные, такие как токен Telegram API или IP-адрес VDS, должны быть заменены.
1. Новый бот
Это самая простая часть, все, что нам нужно сделать, это перейти к BotFather, нажав на эту ссылку, и создать нового бота.
Выберите в меню «Создать нового бота» или введите команду /newbot в текстовом поле.
Вас попросят указать имя бота (оно может быть не уникальным) и имя пользователя бота, которые должны быть уникальными и содержать «_bot» в конце.
Для этой статьи я выбрал имя пользователя ak_medium_bot. BotFather дал мне токен для доступа к Telegram API (пример на скриншоте). Вы всегда можете получить его или сбросить с помощью BotFather.
С этим всё!
2. Проект Dart
Сначала установите Dart на вашу машину. Все шаги описаны на официальном сайте, и это довольно просто, поэтому у вас не должно быть никаких проблем.
После установки Dart откройте терминал на компьютере Mac или Linux, перейдите в папку в которой вы хотите сохранить проект и выполните следующую команду (у вас должны быть права администратора):
(для получения дополнительной информации о создании проектов Dart посетите этот сайт).
Теперь откройте созданную папку в любой IDE, которой вам нравится. Например, я использую VS Code.
В терминале вашей IDE (или просто в терминале) выполните следующую команду для установки пакета Teledart:
Перейдите в папку bin, откройте bot_medium.dart и замените его содержимое следующим:
Важно! Не храните ключи API, как это было сделано в этой статье! Всегда держите их в секрете и подальше от гита!
Приведенный выше код запускает Telegram-бота и ждет, когда пользователь введет определенные ключевые слова. Если какое-либо ключевое слово будет отправлено боту, он запускает соответствующие действие.
Далее создадим новый файл в корне папки проекта и присвоим ему имя Dockerfile, без какого-либо типа или точки в конце. Заполните его следующим:
Dockerfile создает образ Docker из нашего проекта Dart.
Теперь пришло время создать новый репозиторий, например, на GitHub. Перейдите в терминале в папку проекта и выполните следующие действия:
Обратите внимание! Ваш git remote add origin https://github.com/kharitonovAL/bot_medium.git будет отличаться.
Отлично! Двигаемся дальше!
3. VDS
Чтобы бот был доступен 24/7, мы должны запустить его на сервере. Вы можете использовать любого поставщика услуг VDS, которого хотите. Что касается меня — я использую сервис reg.ru, он не дорогой, стабильный и имеет предварительно настроенные образы операционной системы.
Если вы используете другого поставщика услуг VDS, я рекомендую вам установить Ubuntu с версией 18.04 или 20.04, как показано на скриншоте:
Я выбираю версию 20.04 для этой статьи.
Так, теперь у нас есть VDS, работающие на Ubuntu со следующими параметрами:
Пароль root пользователя был отправлен на мою электронную почту.
Теперь нам нужно подключиться к нашему серверу и установить Dart и Docker.
Используйте любой ssh-клиент или терминал для подключения к серверу. Если вы используете терминал, запустите следующее: ssh root@89.108.70.91. Вас попросят ввести пароль пользователя root.
Если вы все сделали правильно, вы будете подключены к серверу:
Теперь давайте установим Dart на ваш VDS. Все шаги описаны на официальном сайте.
После установки вы можете ввести в терминале dart --version, чтобы проверить, что Dart установлен:
Далее установим Docker, как описано на официальном сайте.
Убедитесь, что Docker Engine установлен правильно, запустив образ hello-world:
Эта команда загружает тестовый образ и запускает его в контейнере. Когда контейнер запускается, он печатает сообщение и выходит.
Теперь давайте установим официальный контейнер Dart, как описано здесь.
И еще нам нужно создать нового пользователя для Ubuntu, чтобы позже собрать и запустить бота в контейнере Docker. Для этого запустите в терминале следующее:
Выходные данные будут похожи на то, что показано на скриншоте:
Важно! Добавьте нового пользователя в группу Docker, как описано здесь. Там описано всего два шага:
1. Создайте группу docker:
2. Добавьте своего пользователя в группу docker:
Далее нам нужно создать папку, которую мы прикрепим к нашему контейнеру, чтобы сохранять там фотографии. Это необходимый шаг, если вы хотите пробрасывать данными в контейнер. Если вы не создадите и не присоедините папку к контейнеру, вы не сможете сохранить файлы. Другими словами — вы не можете сохранить файл внутри контейнера. Вы должны сделать это в файловой системе хоста. Вы можете прочитать больше об этом здесь и здесь.
Если вам нужно сохранить файлы, вы можете соответствующим образом изменить код бота. В моем случае мне нужно сохранить фотографии (или изображения, если хотите), поэтому сделайте следующее:
- Перейдите в корневой каталог, когда вы сделаете путь в терминале, он должен выглядеть следующим образом: root@89–108–70–91:/# (начинается с /);
- Перейдите в каталог var, выполнив cd var;
- Создать новую папку с загрузкой имени, выполнив mkdir upload в терминале;
- Введите ls и нажмите Enter.
Вы должны увидеть что-то подобное в терминале:
Если вы хотите сначала протестировать своего бота на локальной машине, создайте папку загрузки с тем же путем.
Если вы видите папку загрузки, вы можете двигаться вперед.
Хорошо, теперь давайте клонируем наш репозиторий из GiHub. Перейдите в папку home и выполните следующее:
Отлично, следующий шаг!
4. Сборка и запуск контейнера Docker
Итак, теперь вы все настроили.
Теперь войдите в систему со своим новым пользователем (в моем случае duser). Перейдите в папку вашего бота-проекта (в моем случае он находится по пути /home/bot_medium) и создайте образ Docker следующей командой:
Выходные данные будут аналогичны следующему:
Важно! Если вы попытаетесь запустить docker build -t dart-server. с правами root пользователя, вы получите AOT ошибку компиляции.
Хорошо, теперь нужно сообщить системе, что бот должен быть онлайн 24/7. Для этого выполните следующее в терминале (сделать это нужно root пользователем):
Теперь давайте запустим наш контейнер! Выполните следующее (сделайте это с помощью duser):
Вывод будет примерно следующим:
Чтобы убедиться, что наш контейнер запущен, выполните docker ps в терминале, и вывод будет следующим:
Наконец-то наш бот теперь онлайн. Но это еще не конец. Выполните следующее, чтобы обновить настройки контейнера Docker:
Этой командой мы говорим Docker перезапускать этот контейнер каждый раз, когда он отключается.
Имя моего контейнера в данном случае — vigorous_khayyam. Имя вашего контейнера может быть другим. Выполните команду docker ps. Вы увидите список запущенных контейнеров Docker и сможете увидеть имя вашего.
5. Тестирование
Давайте протестируем нашего бота!
Мы отправили фото! Теперь давайте сделаем паузу и проверим, все ли идет как надо после того, как мы отправили фото. Перейдите в каталог /var/upload и введите команду ls, вы увидите вложенную папку с именем chat_id:
Круто, фото есть! Теперь давайте нажмем кнопку «Удалить изображение» в действиях бота и еще раз проверим содержимое /var/upload:
И теперь фото нет!
Теперь вы знаете как создать Telegram-бота с помощью Dart, Docker и VDS. Эта статья также будет полезна Flutter разработчикам.
Код bot_medium вы можете найти здесь.
Telegram-бот и VDS, которые использовались для этой статьи, удаляются, поэтому все конкретные данные, такие как токен Telegram API или IP-адрес VDS, должны быть заменены.
Спасибо за внимание!