Представьте себе ситуацию: вы внимательно следите за определённым продуктом на Яндекс.Маркете и хотите моментально получить уведомление, как только его цена изменится в желаемую сторону. Или, возможно, вы являетесь владельцем интернет-магазина и стремитесь постоянно отслеживать динамику цен конкурентов, чтобы оперативно реагировать и сохранять свою конкурентоспособность на рынке. В обоих этих случаях, а также во множестве других сценариев, Discord-бот для мониторинга цен станет вашим незаменимым цифровым помощником, работающим 24/7. В рамках этой подробной статьи мы детально разберём процесс создания такого многофункционального бота.

Давайте более подробно рассмотрим ключевые области применения нашего бота и как он может существенно облегчить жизнь пользователей:

  • Поиск выгодных предложений на электронику: Представьте, что вы хотите купить новый телевизор, но текущая цена вас не устраивает. Вместо того чтобы тратить время на постоянный мониторинг различных интернет-магазинов, вы можете добавить интересующий вас товар в список отслеживания. Наш бот будет а��томатически проверять изменения цен и моментально уведомит вас, когда цена станет подходящей. Это позволит вам приобрести товар по выгодной цене без лишних усилий.

  • Анализ конкурентных предложений для онлайн-агрегаторов: Если вы работаете с платформой, которая собирает и сравнивает предложения разных продавцов, наш бот станет важным инструментом для отслеживания и анализа цен. Он будет автоматически мониторить изменения цен у ваших поставщиков, сравнивать их с предложениями конкурентов и своевременно информировать вас о необходимости корректировки ценовой политики. Это позволит вам предлагать лучшие условия для клиентов и поддерживать конкурентоспособность вашей платформы.

Что мы будем делать? Подробный план действий

  • Подготовка технической базы
    В данном разделе мы рассмотрим процесс установки Python, создания изолированной среды разработки и интеграции необходимых библиотек для реализации проекта.

  • Конфигурация Discord-приложения
    Этот этап включает в себя регистрацию нового бота в системе Discord, получение авторизационного токена и настройку ключевых параметров для функционирования бота.

  • Разработка основного функционала Discord-бота
    Здесь мы сосредоточимся на написании базового кода, обеспечивающего подключение к Discord и реализацию основных команд взаимодействия.

  • Внедрение системы мониторинга цен
    На этом этапе мы интегрируем в нашего бота механизмы для сбора и анализа информации о ценах на товары с различных веб-ресурсов, используя специализированные библиотеки для обработки HTTP-запросов и извлечения данных из HTML-структур.

  • Запуск нашего бота в облаке для работ 24/7

    В этом нам поможет Amvera Cloud, где предоставляется возможность развернуть проект используя git push или просто перетянув файлы в интерфейсе. Помимо этого, есть и другие преимущества при использовании Amvera:

    • Удобная доставка обновлений кода через git. Обновление проекта на проде делается всего тремя командами в вашей IDE. Это проще, чем настройка VPS.

    • Вам не нужно делать никаких дополнительных настроек, приложение можно развернуть буквально за 5 минут. Заполняете пару полей в конфигурации, загружаете файлы, и все само настраивается и запускается.

    • Бесплатный баланс при регистрации - 111 рублей.

    • Если вы остановите проект, деньги не списываются и данные не теряются. Вы платите только за работающее приложение.

Но хватит рекламы, приступим к самому важному - разработке бота.

Подготовка окружения

1. Установка Python и необходимых библиотек

Для начала убедимся, что у нас установлен Python версии 3.8 или выше. Если Python ещё не установлен, загрузите его с официального сайта.
После установки откройте терминал и выполните команду:

python --version

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

Создадим и активируем виртуальное окружение:

# Создаём виртуальное окружение 
python -m venv venv 
# Активация виртуального окружения 
# На Windows: 
	.\venv\Scripts\activate  
# На macOS и Linux: 
	source venv/bin/activate

После активации виртуального окружения вы увидите префикс (venv) в начале командной строки.

Теперь установим необходимые библиотеки:

pip install discord.py requests beautifulsoup4 python-dotenv

Разбор установленных библиотек

discord.py: Эта асинхронная библиотека Python предназначена для взаимодействия с API Discord. Она позволяет создавать Discord-ботов, которые могут подключаться к серверам, отправлять и получать сообщения, реагировать на команды пользователей и выполнять множество других задач.

requests: Простая и мощная библиотека для выполнения HTTP-запросов. Она используется для отправки запросов на веб-страницы с целью получения HTML-кода страниц с ценами товаров.

beautifulsoup4: Библиотека для парсинга HTML и XML документов. Она позволяет извлекать нужные данные из HTML-кода страниц, что необходимо для получения цен товаров.

python-dotenv: Эта библиотека загружает переменные окружения из файла .env, что особенно полезно для безопасного хранения конфиденциальной информации, такой как токены API, пароли и другие данные.

Создание и настройка Discord-бота

Создание структуры проекта

Начнем с создания папки для проекта и организации файлов:

# Создаём папку проекта 
mkdir PriceMonitorBot cd PriceMonitorBot  
# Создаём основной файл проекта 
touch main.py  
# Создаём файл для хранения конфиденциальной информации 
touch .env

Создание приложения на Discord

  1. Перейдите на портал разработчиков Discord.

  2. Войдите в свой аккаунт Discord, если вы еще этого не сделали.

  3. На странице портала нажмите кнопку "New Application" .

  4. В открывшемся окне введите название вашего приложения и нажмите "Create".

Создание бота в приложении

  1. После создания приложения вас перенаправит на страницу управления. В меню слева выберите вкладку "Bot".

  2. Нажмите кнопку "Add Bot" (Добавить бота).

  3. Подтвердите создание бота, нажав "Yes, do it!".

Получ��ние токена

  1. На странице бота под заголовком "TOKEN" нажмите кнопку "Copy" (Скопировать).

  2. Это и есть ваш токен — длинная строка символов. Обращайтесь с ним осторожно, так как он является "ключом" доступа к вашему боту.

Важно: Никому не передавайте ваш токен. Если токен попадет в чужие руки, злоумышленники смогут управлять вашим ботом. Если вы случайно раскрыли токен, его можно сбросить, нажав кнопку "Regenerate" (Регенирация).

Чтобы добавить бота на ваш сервер:

  • В разделе "OAuth2" выберите "URL Generator".

  • Отметьте пункт "bot" в разделе "SCOPES".

  • В разделе "BOT PERMISSIONS" выберите нужные разрешения (например, "Send Messages").

  • Скопируйте сгенерированную ссылку и откройте её в браузере. Выберите сервер, на который хотите пригласить бота.

Настройка файла .env

Файл .env будет содержать переменные окружения, которые используются для настройки вашего бота. Эти переменные будут загружаться в коде из файла с помощью библиотеки python-dotenv. Откройте файл .env в любом текстовом редакторе и добавьте в него следующие строки:

DISCORD_TOKEN=YOUR_DISCORD_BOT_TOKEN

Замените YOUR_DISCORD_BOT_TOKEN на фактический токен вашего бота, который мы получили ранее в панели разработчика Discord.

Организация и защита .env файла

Так как .env содержит конфиденциальные данные, важно убедиться, что этот файл не попадет в общий доступ, особенно если вы используете системы контроля версий, такие как Git. Для этого добавьте файл .env в .gitignore, чтобы он не был случайно закоммичен в репозиторий.

Создайте файл .gitignore в корне проекта и добавьте в него строку:

.env

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

Первая часть нашего кода — это импорт всех нужных библиотек. Здесь используются библиотеки, которые помогут нам взаимодействовать с Discord, отправлять HTTP-запросы и парсить HTML, а также управлять переменными окружения:

import discord 
import requests 
from bs4 import BeautifulSoup 
from discord.ext import commands, tasks 
from dotenv import load_dotenv import os
  1. discord: Эта библиотека необходима для работы с API Discord. Она предоставляет классы и методы для управления сервером Discord, ботами, каналами, сообщениями и другими сущностями. Мы будем использовать её для создания и управления нашим ботом.

  2. requests: Используется для отправки HTTP-запросов. Эта библиотека поможет нам получать HTML-страницы с сайтов, чтобы извлекать информацию о ценах.

  3. BeautifulSoup: Библиотека для парсинга HTML и XML. В нашем проекте она используется для поиска и извлечения данных о ценах из HTML-кода страниц товаров.

  4. discord.ext.commands и discord.ext.tasks: Эти модули из discord.ext помогают расширить возможности discord.py. Модуль commands позволяет создавать команды для нашего бота, а tasks — запускать повторяющиеся задачи.

  5. dotenvload_dotenv из этой библиотеки позволяет загружать переменные окружения из файла .env. Это удобный и безопасный способ хранения конфиденциальной информации, такой как токен нашего бота, без необходимости включать её прямо в код.

  6. os: Модуль для взаимодействия с операционной системой. Мы будем использовать его для получения значений переменных окружения.

Загрузка переменных окружения

Использование переменных окружения позволяет нам хранить конфиденциальные данные, такие как токен бота, безопасным способом.

load_dotenv() TOKEN = os.getenv('DISCORD_TOKEN')
  • load_dotenv(): Эта функция загружает все переменные окружения, определенные в файле .env, в текущую сессию Python. Это позволяет нам использовать их в коде, не раскрывая реальные значения.

  • TOKEN: Мы получаем значение токена нашего бота из переменной окружения DISCORD_TOKEN. Это значение нужно будет определить в файле .env перед запуском кода. Использование переменных окружения вместо жесткого кодирования токенов или других конфиденциальных данных делает код более безопасным.

Настройка бота и объявление глобальных переменных

На этом этапе мы создаем экземпляр нашего бота, настраиваем его интенции и определяем глобальные переменные для отслеживания товаров и канала уведомлений.

intents = discord.Intents.default() 
intents.message_content = True 
bot = commands.Bot(command_prefix='!', intents=intents)  

tracked_items = {} 
notification_channel = None
  1. intents: Интенции (intents) — это способ управления тем, какие события бот будет получать от Discord. Использование интенций позволяет снизить нагрузку на бота и улучшить безопасность. Здесь мы используем Intents.default() для создания объекта с базовыми настройками. Установка intents.message_content = True позволяет боту получать содержимое сообщений, что необходимо для обработки команд.

  2. bot: Здесь мы создаем экземпляр бота с использованием класса commands.Bot. Параметр command_prefix='!' указывает, что все команды бота будут начинаться с символа !. Параметр intents=intents задает интенции для бота.

  3. tracked_items: Это словарь, в котором мы будем хранить URL отслеживаемых товаров и их текущие цены. Словарь — удобная структура данных для этой задачи, так как она позволяет легко добавлять, удалять и обновлять элементы.

  4. notification_channel: Переменная, в которой будет храниться ссылка на канал, в который бот будет отправлять уведомления о изменении цен. Изначально она установлена в None, и её нужно будет настроить с помощью специальной команды.

Функция для получения цены товара

Для извлечения цен нам нужна функция, которая будет отправлять запросы на сайты и анализировать полученные HTML-страницы.

def get_price(url): 
	headers = { 
			"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3"}
	response = requests.get(url, headers=headers) 
	soup = BeautifulSoup(response.text, 'html.parser')
	
	price_tag = soup.find('span', {'class': 'price'}) 
	if price_tag: 
		price = 
		float(price_tag.text.replace('\u2009', '').replace('₽', '').replace(' ', '').strip()) 
		return price 
	return None
  1. headers: Установка заголовков, включая User-Agent, делает запросы более похожими на запросы от обычного веб-браузера. Это помогает избежать блокировок или ограничений со стороны сайтов.

  2. requests.get(url, headers=headers): Выполняет HTTP-запрос к указанному URL с указанными заголовками. Если сайт доступен, получаем HTML-код страницы.

  3. BeautifulSoup: Мы используем BeautifulSoup для парсинга полученного HTML. Он помогает нам легко найти нужные теги и извлечь из них информацию.

  4. price_tag: Мы ищем первый элемент с тегом <span> и атрибутом class="price". Это упрощенное предположение, что цена на странице отображается именно в таком формате. В реальном проекте формат HTML может отличаться, и вам, возможно, придётся адаптировать этот код для конкретного сайта.

  5. price: После того как мы нашли тег с ценой, извлекаем текст, удаляем ненужные символы (например, символ валюты и пробелы) и преобразуем его в число с плавающей точкой. Если тег не найден, функция возвращает None.

Реализация команд бота

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

  1. Добавление товара в отслеживание

@bot.command() 
async def track(ctx, url: str):     
	price = get_price(url)     
	if price:         
		tracked_items[url] = price        
			await ctx.send(f"Товар добавлен в отслеживание.Цена:{price}₽")
	else:         
		await ctx.send("Не удалось получить цену для этого товара.")
- **@bot.command()**: Декоратор, который регистрирует функцию как команду бота. Название функции (`track`) будет использоваться как команда, которую нужно отправить боту.
- **track(ctx, url: str)**: Эта команда принимает URL товара и добавляет его в список отслеживаемых товаров, если удаётся получить его цену. `ctx` — это контекст команды, он предоставляет информацию о вызове команды, включая канал, пользователя и т.д.
  1. Удаление товара из отслеживания

@bot.command() 
async def untrack(ctx, url: str):     
  if url in tracked_items:         
  	del tracked_items[url]         
  	await ctx.send(f"Товар удален из отслеживания.")     
  else:         
  	await ctx.send("Этот товар не отслеживается.")`
- **untrack(ctx, url: str)**: Команда для удаления товара из списка отслеживаемых. Она проверяет, есть ли указанный URL в `tracked_items` и удаляет его, если он там есть.
  1. Просмотр списка отслеживаемых товаров

  @bot.command() 
  async def list(ctx):     
      if tracked_items:         
  	    message = "Отслеживаемые товары:\n"         
  		for url, price in tracked_items.items():             
  			message += f"{url} - Текущая цена: {price} ₽\n"        
  		await ctx.send(message)     
  	else:         
  		await ctx.send("Список отслеживаемых товаров пуст.")`
- **list(ctx)**: Команда для отображения всех товаров, которые бот отслеживает, вместе с их текущими ценами. Если список пуст, бот сообщает об этом.
  1. Установка канала для уведомлений

@bot.command() 
async def setchannel(ctx):     
	global notification_channel     
	notification_channel = ctx.channel    
	await ctx.send(f"Уведомления о изменении цен будут отправляться в канал: {ctx.channel.name}")`
c- **setchannel(ctx)**: Команда для установки текущего канала в качестве канала для отправки уведомлений о изменении цен. Эта команда запоминает канал, из которого была вызвана, и сохраняет его в глобальной переменной `notification_channel`.
  1. Обновление цен вручную

@bot.command()
async def update(ctx):
await ctx.send("Обновление цен...")
await price_check()

  
    - **update(ctx)**: Команда для ручного запуска проверки цен. Полезно для случаев, когда нужно немедленно узнать о изменениях цен.

### Задача для регулярной проверки цен

Для автоматизации проверки цен мы создаём задачу, которая будет запускаться каждые 60 минут.

```python
@tasks.loop(minutes=60) 
async def price_check():     
	for url, old_price in tracked_items.items():         
		new_price = get_price(url)         
		if new_price and new_price != old_price:             
			tracked_items[url] = new_price             
			if notification_channel:                 
				await notification_channel.send(f"Цена на товар изменилась! Новая цена: {new_price} ₽ (Старая цена: {old_price} ₽)\n{url}")             
			else:                 
				print("Канал для уведомлений не установлен.")
  • @tasks.loop(minutes=60): Декоратор, который указывает, что функция price_check должна выполняться каждые 60 минут.

  • price_check(): Эта функция проходит по всем отслеживаемым товарам и проверяет их текущие цены. Если цена изменяется, бот обновляет её в словаре tracked_items и отправляет уведомление в установленный канал.

Запуск бота

Последний шаг — это запуск бота с использованием токена.

`@bot.event async def on_ready():     
	print(f'Logged in as {bot.user}')     
	price_check.start()  

bot.run(TOKEN)`
  • on_ready(): Событие, которое вызывается, когда бот успешно подключается к серверу Discord. Здесь мы выводим сообщение в консоль и запускаем задачу price_check.

  • bot.run(TOKEN): Запускает бота с указанным токеном. Токен должен быть определён в файле .env.

Теперь, когда мы настроили и протестировали нашего Telegram-бота на локальной машине, самое время запустить его в облаке, чтобы он был доступен 24/7. В этом шаге мы развернем бота на платформе Amvera, которая предоставляет удобные инструменты для хостинга приложений.

Регистрация в сервисе

  1. Создание аккаунта:

    • Перейдите на сайт Amvera и нажмите на кнопку "Регистрация".

    • Заполните все необходимые поля, включая номер телефона, и нажмите на кнопку "Отправить код".

    • Введите код, полученный в SMS, подтвердите, что вы не робот, и нажмите "Регистрация".

    • После этого подтвердите адрес электронной почты, перейдя по ссылке в письме.

    • Получите на баланс 111 руб. на тесты)

Создание проекта и размещение бота

  1. Создание нового проекта:

    • После входа на платформу, на главной странице нажмите на кнопку "Создать" или "Создать первый!".

    https://habrastorage.org/r/w1560/getpro/habr/upload_files/90a/00c/aa0/90a00caa0d20e5d56d26f898a5eb9fe2.png
  2. Настройка проекта:

    • Присвойте вашему проекту название (лучше на английском языке).

    • Выберите тарифный план. Для развертывания бота будет достаточно самого простого тарифа.

    • Начального баланса хватит для того, чтобы бот работал бесплатно и непрерывно в течение нескольких недель.

    https://habrastorage.org/r/w1560/getpro/habr/upload_files/3d0/1e7/14c/3d01e714ca77535ca452f7afa0ced4a2.png
  3. Подготовка кода для развертывания:

  • Amvera использует git для доставки кода в облако. Вам потребуется создать файл конфигурации amvera.yml, который подскажет облаку, как запускать ваш проект.

  • Для упрощения создания этого файла воспользуйтесь графическим инструментом генерации.
    Выбор окружения и зависимостей:

    • Укажите версию Python и путь до файла requirements.txt, который содержит все необходимые пакеты.

    • Укажите путь до основного файла вашего проекта, например main.py.

  • Хранение данных:

    • Если бот сохраняет данные на диск, они должны размещаться в папке data, чтобы избежать их потери при перезапуске.

  • Генерация и загрузка файла:

    • Нажмите "Generate YAML" для создания файла amvera.yml и загрузите его в корень вашего проекта.

Файл конфигурации amvera.yml служит для того, чтобы платформа Amvera знала, как правильно собрать и запустить ваш проект. Этот файл содержит ключевую информацию об окружении, зависимостях, а также инструкциях для запуска приложения.

Структура файла amvera.yml:

meta:
  environment: python  # Указывает, что проект использует Python в качестве окружения.
  toolchain:
    name: pip          # Определяет менеджер пакетов для установки зависимостей.
    version: "3.8"     # Задает версию Python для окружения проекта.

build:
  requirementsPath: requirements.txt  # Путь к файлу, где указаны все необходимые зависимости.

run:
  scriptName: app.py  # Основной файл вашего проекта, который будет запущен после сборки.
  persistenceMount: /data  # Директория для хранения постоянных данных.
  containerPort: 80    # Порт, на котором будет доступен ваш проект в контейнере.

Для того чтобы наш проект корректно работал в среде Amvera, важно указать все необходимые пакеты в файле requirements.txt. Этот файл определяет все зависимости Python, которые нужны для выполнения кода.

Вот так выглядит наш файл requirements.txt :

discord.py==2.2.3
requests==2.31.0
beautifulsoup4==4.12.2
python-dotenv==1.0.0

Инициализация и отправка проекта в репозиторий:

  • Инициализируйте git репозиторий в корне вашего проекта, если это еще не сделано:

    git init
  • Привяжите локальный репозиторий к удаленному на Amvera:

    git remote add amvera <https://git.amvera.ru/ваш_юзернейм/ваш_проект>
  • Добавьте и зафиксируйте изменения:

    git add .
    git commit -m "Initial commit"
  • Отправьте проект в облако:

    git push amvera master

Сборка и развертывание проекта:

  • После отправки проекта в систему, на странице проекта статус изменится на "Выполняется сборка".

https://habrastorage.org/r/w1560/getpro/habr/upload_files/ebb/8d7/7e3/ebb8d77e3a4c581c15a03843df3386d2.png
Статус сборки появится после загрузки всех файлов и коммита

После завершения сборки проект перейдет в стадию "Выполняется развертывание", а затем в статус "Успешно развернуто".

https://habrastorage.org/r/w1560/getpro/habr/upload_files/c75/56c/5f7/c7556c5f70e0992280694a346ba3f070.png
Среднее время сборки и запуска 5-10 минут. В момент запуска статус может гореть красным - это нормально. Главное смотреть ошибки в логе
Успешный запуск
Успешный запуск

Если проект не развернулся, проверьте логи сборки и логи приложения для отладки.

Если проект завис на этапе "Сборка", убедитесь в корректности файла amvera.yml.

Заключение

В этой статье мы рассмотрели процесс создания и развертывания Discord-бота для мониторинга цен на Яндекс.Маркете. Мы прошли путь от написания кода бота на Python до его размещения в облаке на платформе Amvera.

Ключевые моменты, которые мы охватили:

  • Разработка функционала бота для мониторинга цен

  • Настройка команд и обработка событий в Discord

  • Реализация автоматической проверки цен с заданным интервалом

  • Процесс регистрации и создания проекта на платформе Amvera

  • Подготовка проекта к развертыванию в облаке

  • Настройка и отправка кода в репозиторий Amvera

Автор: Алексей Пономарев


Релевантные статьи