8 мин.

Как создать Telegram-бота на VPS: пример финансового бота

Хотите автоматизировать рутинные задачи, получать уведомления или создать простой сервис, но не знаете, с чего начать? Telegram-боты – это мощный инструмент, доступный каждому. В этой статье вы пройдёте полный путь от идеи до работающего сервиса: создадите финансового бота, который поможет вести учёт личных денег, и запустите его на виртуальном сервере (VPS) для круглосуточной работы. Мы разберём каждый шаг: от регистрации бота в Telegram до настройки автозапуска на сервере. В конце у вас будет готовый проект, который можно сразу использовать и развивать дальше.

Что такое Telegram-бот и зачем ему нужен VPS

Telegram-бот – это специальная программа, которая взаимодействует с мессенджером Telegram через его API. В отличие от обычного личного аккаунта, ботом управляет программа: он может автоматически отвечать на сообщения, отправлять уведомления, обрабатывать команды и интегрироваться с другими сервисами.

Боты решают множество задач: от простых напоминалок до сложных систем поддержки клиентов и интернет-магазинов.

Для стабильной работы 24/7 боту нужен сервер, который всегда включен и подключён к интернету. Запускать его на домашнем компьютере неудобно – при выключении ПК бот перестанет отвечать.

Виртуальный сервер (VPS) – это арендованный виртуальный сервер в дата-центре. Он работает непрерывно, обеспечивая вашему боту стабильность, постоянный IP-адрес и независимость от вашего интернета. Для большинства простых ботов, включая нашего будущего финансового помощника, хватит недорогого тарифа. Например, у Mnogoweb есть подходящие VPS в локациях Нидерландов и США стоимостью от 400 рублей в месяц.

Что понадобится для запуска вашего финансового бота

Перед началом убедитесь, что у вас уже есть всё необходимое из этого списка:

  1. Аккаунт в Telegram и любой клиент Telegram.
  2. VPS с операционной системой Ubuntu. Мы будем использовать эту популярную и стабильную версию Linux. Для нашего бота не нужна мощная конфигурация, подойдёт самый бюджетный вариант. Многие провайдеры, включая Mnogoweb, предлагают тарифы, оптимальные для подобных задач, с локациями в Европе и США.
  3. Доступ по SSH. Это стандартный защищённый протокол для удалённого управления сервером. Данные для подключения (IP-адрес, логин и пароль) вы получите от провайдера после заказа VPS.
  4. Python 3. Язык программирования, на котором мы напишем бота. Мы установим его на сервер в следующем шаге.

Это всё. Глубоких знаний программирования или администрирования не потребуется.

Шаг 1: Регистрация бота в Telegram

Жизнь Telegram-бота начинается в самом Telegram. Откройте любой Telegram-клиент и найдите в поиске пользователя @BotFather. Это официальный бот от Telegram для создания и управления другими ботами.

  1. Начните диалог с BotFather и отправьте команду /newbot.
  2. BotFather попросит придумать имя для вашего бота (например, «Мой финансовый помощник»). Это имя будет отображаться в чате.
  3. Затем нужно задать username бота. Он должен быть уникальным в системе Telegram и обязательно заканчиваться на слово bot (например, my_finance_helper_bot).
  4. После успешного создания BotFather пришлёт вам токен доступа. Он выглядит примерно так: 6123456789:AAHdqTcvCH1vGWJxfSeofSAs0K5PALDsaw.

Обязательно сохраните этот токен в надёжном месте. Это ключ для взаимодействия нашего бота с Telegram. Никому его не передавайте и не публикуйте в открытом доступе.

Шаг 2: Подготовка VPS

Теперь подключимся к серверу и подготовим его для работы. Откройте терминал на своём компьютере (на macOS и Linux это встроенное приложение, на Windows можно использовать PuTTY или встроенный SSH в PowerShell).

Выполните команду для подключения, подставив свой IP-адрес и имя пользователя (обычно root):

ssh root@ip_адрес_вашего_сервера

После ввода пароля вы окажетесь в командной строке сервера. Первым делом обновим список пакетов и установим обновления системы для безопасности:

sudo apt update && sudo apt upgrade -y

Установим Python 3 и менеджер пакетов pip, если они ещё не установлены (в Ubuntu 22.04 они часто идут по умолчанию):

sudo apt install python3 python3-pip -y

Проверим установку:

python3 --version

Команда должна вывести версию Python (например, 3.10.12). Теперь сервер готов.

Шаг 3: Разработка бота - пишем логику учёта финансов

Это основной этап, где мы создадим рабочее ядро бота. Мы будем использовать язык Python и популярную библиотеку python-telegram-bot.

Создаём базу данных SQLite для хранения операций

Нашему боту нужно где-то хранить данные о доходах и расходах. Для этого мы будем использовать лёгкую встроенную базу данных SQLite – для неё не нужен отдельный сервер.

Структура простая: каждая запись будет содержать уникальный ID, тип операции (доход или расход), сумму и дату. Работа с базой данных требует аккуратности. Помните, что восстановление данных после сбоя – сложная задача, поэтому важно правильно настроить резервное копирование вашего сервера.

Ядро бота: обработка команд и работа с данными

Теперь напишем сам код бота. Создадим на сервере директорию для проекта и файл с программой.

Вернитесь в терминал сервера и выполните:

mkdir ~/finance_bot
cd ~/finance_bot
python3 -m venv venv
source venv/bin/activate

Первая команда создаёт папку, вторая переходит в неё. Третья команда создаёт виртуальное окружение Python (изолированную среду для зависимостей проекта), а четвёртая активирует это окружение.

Установим необходимую библиотеку:

pip install python-telegram-bot

Теперь создадим файл bot.py с помощью текстового редактора nano:

nano bot.py

Скопируйте и вставьте в открывшийся редактор следующий код. Обязательно замените YOUR_BOT_TOKEN на токен, полученный от @BotFather.

import sqlite3
import logging
from datetime import datetime
from telegram import Update
from telegram.ext import Application, CommandHandler, ContextTypes

# Настройка логирования
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO)

# Токен вашего бота (ЗАМЕНИТЕ НА СВОЙ!)
TOKEN = 'YOUR_BOT_TOKEN'

# Подключение к базе данных SQLite
def init_db():
    conn = sqlite3.connect('finance.db')
    cursor = conn.cursor()
    cursor.execute('''CREATE TABLE IF NOT EXISTS transactions
                      (id INTEGER PRIMARY KEY AUTOINCREMENT,
                       type TEXT NOT NULL,
                       amount REAL NOT NULL,
                       date TIMESTAMP DEFAULT CURRENT_TIMESTAMP)''')
    conn.commit()
    conn.close()

# Обработчик команды /start
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
    await update.message.reply_text('Привет! Я бот для учёта финансов.\n' 
                                    'Доступные команды:\n' 
                                    '/income [сумма] - добавить доход\n' 
                                    '/expense [сумма] - добавить расход\n' 
                                    '/balance - показать текущий баланс\n' 
                                    '/history - показать историю операций')

# Обработчик команды /income
async def add_income(update: Update, context: ContextTypes.DEFAULT_TYPE):
    try:
        amount = float(context.args[0])
        conn = sqlite3.connect('finance.db')
        cursor = conn.cursor()
        cursor.execute("INSERT INTO transactions (type, amount) VALUES ('income', ?)", (amount,))
        conn.commit()
        conn.close()
        await update.message.reply_text(f'Доход {amount} руб. добавлен.')
    except (IndexError, ValueError):
        await update.message.reply_text('Используйте: /income [сумма]')

# Обработчик команды /expense
async def add_expense(update: Update, context: ContextTypes.DEFAULT_TYPE):
    try:
        amount = float(context.args[0])
        conn = sqlite3.connect('finance.db')
        cursor = conn.cursor()
        cursor.execute("INSERT INTO transactions (type, amount) VALUES ('expense', ?)", (amount,))
        conn.commit()
        conn.close()
        await update.message.reply_text(f'Расход {amount} руб. добавлен.')
    except (IndexError, ValueError):
        await update.message.reply_text('Используйте: /expense [сумма]')

# Обработчик команды /balance
async def show_balance(update: Update, context: ContextTypes.DEFAULT_TYPE):
    conn = sqlite3.connect('finance.db')
    cursor = conn.cursor()
    cursor.execute("SELECT SUM(amount) FROM transactions WHERE type='income'")
    total_income = cursor.fetchone()[0] or 0
    cursor.execute("SELECT SUM(amount) FROM transactions WHERE type='expense'")
    total_expense = cursor.fetchone()[0] or 0
    balance = total_income - total_expense
    conn.close()
    await update.message.reply_text(f'Текущий баланс: {balance:.2f} руб.\n' 
                                    f'Доходы: {total_income:.2f} руб.\n' 
                                    f'Расходы: {total_expense:.2f} руб.')

# Обработчик команды /history
async def show_history(update: Update, context: ContextTypes.DEFAULT_TYPE):
    conn = sqlite3.connect('finance.db')
    cursor = conn.cursor()
    cursor.execute("SELECT type, amount, date FROM transactions ORDER BY date DESC LIMIT 10")
    transactions = cursor.fetchall()
    conn.close()
    
    if not transactions:
        await update.message.reply_text('История операций пуста.')
        return
    
    history_text = 'Последние 10 операций:\n'
    for trans in transactions:
        op_type = 'Доход' if trans[0] == 'income' else 'Расход'
        history_text += f"{trans[2]}: {op_type} {trans[1]} руб.\n"
    
    await update.message.reply_text(history_text)

def main():
    # Инициализация базы данных
    init_db()
    
    # Создание приложения и передача токена
    application = Application.builder().token(TOKEN).build()
    
    # Регистрация обработчиков команд
    application.add_handler(CommandHandler("start", start))
    application.add_handler(CommandHandler("income", add_income))
    application.add_handler(CommandHandler("expense", add_expense))
    application.add_handler(CommandHandler("balance", show_balance))
    application.add_handler(CommandHandler("history", show_history))
    
    # Запуск бота
    application.run_polling()

if __name__ == '__main__':
    main()

Сохраните файл (в nano: Ctrl+O, затем Enter) и закройте редактор (Ctrl+X).

Библиотека python-telegram-bot использует асинхронную модель. Когда пользователь отправляет команду (например, /income 1000), Telegram отправляет её на серверы бота. Наш скрипт, работающий на VPS, постоянно «опросом» (polling) проверяет наличие новых сообщений. Получив команду, он вызывает соответствующий обработчик (add_income), который извлекает сумму из аргументов, добавляет запись в базу данных SQLite и отправляет ответ пользователю.

Шаг 4: Запуск и тестирование бота на VPS

Осталось запустить нашего бота и протестировать его. Убедитесь, что вы находитесь в директории проекта ~/finance_bot и виртуальное окружение активировано (в начале строки терминала должно быть (venv)).

Выполните команду:

python3 bot.py

Если всё сделано правильно, вы увидите сообщение вроде Application running. Бот запущен и ожидает сообщения от Telegram.

Теперь откройте Telegram, найдите своего бота по выбранному при создании username (например, @my_finance_helper_bot) и начните диалог. Отправьте команду /start, чтобы увидеть приветственное сообщение. Затем протестируйте основные функции:

  • /income 3000 - бот ответит: Доход 3000 руб. добавлен.
  • /expense 500 - бот ответит: Расход 500 руб. добавлен.
  • /balance - бот покажет: Текущий баланс: 2500 руб. Доходы: 3000 руб. Расходы: 500 руб.
  • /history - бот выведет список последних операций с датами.

Поздравляем! Ваш финансовый бот работает. Но пока он запущен только в текущей сессии терминала. Если закрыть подключение SSH, бот остановится. Исправим это.

Шаг 4: Запуск и тестирование бота на VPS

Осталось запустить бота и протестировать его. Убедитесь, что вы находитесь в директории проекта ~/finance_bot и виртуальное окружение активировано (в начале строки терминала должно быть (venv)).

Выполните команду:

python3 bot.py

Если всё сделано правильно, вы увидите сообщение вроде Application running. Бот запущен и начал «слушать» сообщения от Telegram.

Теперь откройте Telegram, найдите своего бота по username (например, @my_finance_helper_bot) и начните диалог. Отправьте команду /start, чтобы увидеть приветственное сообщение. Затем протестируйте основные функции:

  • /income 3000 - бот ответит: «Доход 3000 руб. добавлен.»
  • /expense 500 - бот ответит: «Расход 500 руб. добавлен.»
  • /balance - бот покажет: «Текущий баланс: 2500 руб. Доходы: 3000 руб. Расходы: 500 руб.»
  • /history - бот выведет список последних операций с датами.

Поздравляем! Ваш финансовый бот работает. Но пока он запущен только в текущей сессии терминала. Если закрыть подключение SSH, бот остановится. Исправим это.

Шаг 5: Настройка автозапуска бота

Для настройки автозапуска бота будем использовать Systemd, это стандартная система инициализации и управления службами в Linux. Она позволяет запускать скрипты и программы в виде фоновых служб, а также автоматически стартует их при загрузке сервера и перезапускается в случае сбоя.

Сначала остановите бота, нажав в терминале Ctrl+C.

Создадим конфигурационный файл службы. Выполните команду:

sudo nano /etc/systemd/system/finance-bot.service

Вставьте в файл следующее содержимое. Обязательно укажите правильный путь к вашему Python и скрипту (в примере используется путь для пользователя ubuntu).

[Unit]
Description=Finance Telegram Bot
After=network.target

[Service]
Type=simple
User=ubuntu
WorkingDirectory=/home/ubuntu/finance_bot
ExecStart=/home/ubuntu/finance_bot/venv/bin/python3 /home/ubuntu/finance_bot/bot.py
Restart=always
RestartSec=10
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=finance-bot

[Install]
WantedBy=multi-user.target

Сохраните и закройте файл. Теперь нужно сообщить Systemd о новой службе, включить её автозагрузку и запустить:

sudo systemctl daemon-reload
sudo systemctl enable finance-bot
sudo systemctl start finance-bot

Проверим статус службы:

sudo systemctl status finance-bot

Если всё настроено верно, вы увидите статус active (running). Теперь бот будет работать постоянно, даже после перезагрузки сервера. Вы можете отключиться от SSH, бот продолжит отвечать в Telegram. Этот же подход используется для развёртывания профессиональных проектов на VPS.

Куда развивать проект: идеи для улучшения финансового бота

Вместе мы создали бота, позволяющего учитывать доходы и расходы. Теперь его функционал можно развивать, добавляя новые возможности.

Вот несколько идей:

  1. Категории расходов. Модифицируйте таблицу в базе данных, добавив поле category. Добавьте возможность указывать категорию при добавлении расхода, например так: /expense 500 продукты. Затем добавьте отчёт по категориям.
  2. Ежемесячные отчёты. Настройте автоматическую отправку сводки в конце месяца. Можно использовать готовую библиотеку для генерации простых графиков или отправлять текстовый отчёт.
  3. Эспорт в Excel/CSV. Добавьте команду /export, которая будет формировать файл с историей операций за выбранный период и отправлять его пользователю.
  4. Уведомления о тратах. Реализуйте лимиты по категориям. При превышении лимита бот может отправлять предупреждающее сообщение.
  5. Веб-интерфейс. Используя фреймворк вроде Flask или Django, можно сделать простой веб-интерфейс для просмотра статистики и управления данными, который будет работать на том же сервере.

Каждое из этих улучшений – отдельный интересный проект, который углубит ваши знания в разработке и администрировании, а Mnogoweb в случае необходимости с радостью поможет инфраструктурой.