Создание телеграм-бота для магазина на Python — это отличный проект, который требует интеграции нескольких ключевых компонентов:
Библиотека для работы с Telegram API: для взаимодействия с Telegram. База данных: для хранения информации о товарах, пользователях, заказах. Логика магазина: обработка заказов, корзина, оплата.
Давайте рассмотрим общую архитектуру и предоставим упрощенный пример кода.
Архитектура Телеграм-бота-магазина
Telegram Bot API: Взаимодействие с серверами Telegram. Python-библиотека для Telegram:
aiogram (асинхронная, рекомендуемая для новых проектов). pyTelegramBotAPI (синхронная, проще для старта, но менее производительная). python-telegram-bot (также популярная, имеет свои преимущества).
База данных:
SQLite: Простая, файловая БД, отличный выбор для небольших проектов. PostgreSQL/MySQL: Для более крупных проектов, требующих масштабирования и сетевого доступа. ORM (Object-Relational Mapper): SQLAlchemy или peewee для удобной работы с БД из Python.
Платежная система (опционально):
Интеграция с платежными шлюзами (например, Stripe, ЮKassa, PayPal) через их API. Telegram поддерживает платежи через провайдеров.
Административная панель (опционально):
Для управления товарами, заказами, пользователями (можно сделать прямо в Telegram через админские команды, или отдельное веб-приложение).
Пример реализации с использованием Aiogram и SQLite
Этот пример покажет базовую структуру:
Список товаров. Добавление в корзину. Просмотр корзины. Оформление заказа (без реальной оплаты).
Шаг 1: Подготовка окружения
Bash
Pip install aiogram aiosqlite
Шаг 2: Получение токена бота
В Telegram найдите @BotFather. Отправьте ему команду /newbot. Следуйте инструкциям, чтобы создать бота и получить Токен API. Сохраните его.
Шаг 3: Создание базы данных (db. py)
Python
Import aiosqlite
DB_NAME = ‘shop. db’
Async def init_db():
async with aiosqlite. connect(DB_NAME) as db:
await db. execute(»’
CREATE TABLE IF NOT EXISTS products (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
price REAL NOT NULL,
description TEXT
)
»’)
await db. execute(»’
CREATE TABLE IF NOT EXISTS carts (
user_id INTEGER NOT NULL,
product_id INTEGER NOT NULL,
quantity INTEGER NOT NULL,
PRIMARY KEY (user_id, product_id),
FOREIGN KEY (product_id) REFERENCES products(id)
)
»’)
await db. execute(»’
CREATE TABLE IF NOT EXISTS orders (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER NOT NULL,
order_date TEXT NOT NULL,
total_amount REAL NOT NULL,
status TEXT NOT NULL DEFAULT ‘pending’
)
»’)
await db. execute(»’
CREATE TABLE IF NOT EXISTS order_items (
order_id INTEGER NOT NULL,
product_id INTEGER NOT NULL,
product_name TEXT NOT NULL,
price REAL NOT NULL,
quantity INTEGER NOT NULL,
PRIMARY KEY (order_id, product_id),
FOREIGN KEY (order_id) REFERENCES orders(id)
)
»’)
await db. commit()
print("База данных инициализирована.")
Async def add_initial_products():
async with aiosqlite. connect(DB_NAME) as db:
# Проверяем, есть ли уже продукты, чтобы не добавлять дубликаты
cursor = await db. execute("SELECT COUNT(*) FROM products")
count = (await cursor. fetchone())[0]
if count == 0:
products_data = [
("Ноутбук", 1200.00, "Мощный ноутбук для работы и игр."),
("Мышь игровая", 50.00, "Эргономичная мышь с подсветкой."),
("Клавиатура механическая", 100.00, "Надежная механическая клавиатура."),
("Монитор 27 дюймов", 300.00, "Full HD монитор для комфортной работы."),
]
await db. executemany("INSERT INTO products (name, price, description) VALUES (?, ?, ?)", products_data)
await db. commit()
print("Первоначальные продукты добавлены.")
else:
print("Продукты уже существуют в базе данных.")
Async def get_products():
async with aiosqlite. connect(DB_NAME) as db:
cursor = await db. execute("SELECT id, name, price, description FROM products")
return await cursor. fetchall()
Async def get_product_by_id(product_id):
async with aiosqlite. connect(DB_NAME) as db:
cursor = await db. execute("SELECT id, name, price, description FROM products WHERE id = ?", (product_id,))
return await cursor. fetchone()
Async def add_to_cart(user_id, product_id, quantity=1):
async with aiosqlite. connect(DB_NAME) as db:
await db. execute("INSERT OR REPLACE INTO carts (user_id, product_id, quantity) VALUES (?, ?, COALESCE((SELECT quantity FROM carts WHERE user_id = ? AND product_id = ?), 0) + ?)",
(user_id, product_id, user_id, product_id, quantity))
await db. commit()
Async def get_cart_items(user_id):
async with aiosqlite. connect(DB_NAME) as db:
cursor = await db. execute(»’
SELECT p. id, p. name, p. price, c. quantity
FROM carts c
JOIN products p ON c. product_id = p. id
WHERE c. user_id = ?
»’, (user_id,))
return await cursor. fetchall()
Async def clear_cart(user_id):
async with aiosqlite. connect(DB_NAME) as db:
await db. execute("DELETE FROM carts WHERE user_id = ?", (user_id,))
await db. commit()
Async def create_order(user_id, total_amount, cart_items):
async with aiosqlite. connect(DB_NAME) as db:
# Создаем новый заказ
cursor = await db. execute("INSERT INTO orders (user_id, order_date, total_amount) VALUES (?, ?, ?)",
(user_id, pd. Timestamp. now().isoformat(), total_amount))
order_id = cursor. lastrowid # Получаем ID только что вставленного заказа
# Добавляем позиции заказа
order_items_data = [(order_id, item[0], item[1], item[2], item[3]) for item in cart_items]
await db. executemany("INSERT INTO order_items (order_id, product_id, product_name, price, quantity) VALUES (?, ?, ?, ?, ?)", order_items_data)
await db. commit()
return order_id
Шаг 4: Основной код бота (bot. py)
Python
Import logging
From aiogram import Bot, Dispatcher, types
From aiogram. types import InlineKeyboardMarkup, InlineKeyboardButton
From aiogram. utils import executor
Import db # Импортируем наш модуль для работы с БД
# Конфигурация логирования
Logging. basicConfig(level=logging. INFO)
# Замените ‘YOUR_BOT_TOKEN’ на ваш токен BotFather
BOT_TOKEN = ‘YOUR_BOT_TOKEN’
# Инициализация бота и диспетчера
Bot = Bot(token=BOT_TOKEN)
Dp = Dispatcher(bot)
# — Клавиатуры —
Def get_main_menu_keyboard():
keyboard = InlineKeyboardMarkup(row_width=2)
keyboard. add(
InlineKeyboardButton("🛒 Товары", callback_data="show_products"),
InlineKeyboardButton("📦 Корзина", callback_data="show_cart")
)
return keyboard
Def get_product_keyboard(product_id):
keyboard = InlineKeyboardMarkup()
keyboard. add(
InlineKeyboardButton("➕ Добавить в корзину", callback_data=f"add_to_cart_{product_id}")
)
return keyboard
Def get_cart_keyboard():
keyboard = InlineKeyboardMarkup(row_width=2)
keyboard. add(
InlineKeyboardButton("✅ Оформить заказ", callback_data="checkout"),
InlineKeyboardButton("🗑️ Очистить корзину", callback_data="clear_cart")
)
return keyboard
# — Обработчики команд —
@dp. message_handler(commands=[‘start’, ‘help’])
Async def send_welcome(message: types. Message):
await message. reply("Привет! Это демонстрационный магазин. Выберите действие:",
reply_markup=get_main_menu_keyboard())
# — Обработчики Callback-запросов —
@dp. callback_query_handler(lambda c: c. data == ‘show_products’)
Async def process_show_products(callback_query: types. CallbackQuery):
await bot. answer_callback_query(callback_query. id)
products = await db. get_products()
if not products:
await bot. send_message(callback_query. from_user. id, "В магазине пока нет товаров.")
return
for product in products:
product_id, name, price, description = product
message_text = (
f"**{name}**\n"
f"Цена: {price:.2f} $\n"
f"Описание: {description}"
)
await bot. send_message(callback_query. from_user. id, message_text,
parse_mode="Markdown", reply_markup=get_product_keyboard(product_id))
await bot. send_message(callback_query. from_user. id, "Что еще?", reply_markup=get_main_menu_keyboard())
@dp. callback_query_handler(lambda c: c. data and c. data. startswith(‘add_to_cart_’))
Async def process_add_to_cart(callback_query: types. CallbackQuery):
await bot. answer_callback_query(callback_query. id)
product_id = int(callback_query. data. split(‘_’)[3])
user_id = callback_query. from_user. id
product = await db. get_product_by_id(product_id)
if product:
await db. add_to_cart(user_id, product_id)
await bot. send_message(user_id, f"✅ ‘{product[1]}’ добавлен в корзину!")
else:
await bot. send_message(user_id, "Такого товара не существует.")
await bot. send_message(user_id, "Что дальше?", reply_markup=get_main_menu_keyboard())
@dp. callback_query_handler(lambda c: c. data == ‘show_cart’)
Async def process_show_cart(callback_query: types. CallbackQuery):
await bot. answer_callback_query(callback_query. id)
user_id = callback_query. from_user. id
cart_items = await db. get_cart_items(user_id)
if not cart_items:
await bot. send_message(user_id, "Ваша корзина пуста.", reply_markup=get_main_menu_keyboard())
return
message_text = "Ваша корзина:\n\n"
total_amount = 0
for item in cart_items:
product_id, name, price, quantity = item
item_total = price * quantity
total_amount += item_total
message_text += f"- {name} (x{quantity}) — {price:.2f}$ каждый = {item_total:.2f}$\n"
message_text += f"\nИтого: **{total_amount:.2f}$**"
await bot. send_message(user_id, message_text, parse_mode="Markdown", reply_markup=get_cart_keyboard())
@dp. callback_query_handler(lambda c: c. data == ‘clear_cart’)
Async def process_clear_cart(callback_query: types. CallbackQuery):
await bot. answer_callback_query(callback_query. id)
user_id = callback_query. from_user. id
await db. clear_cart(user_id)
await bot. send_message(user_id, "Ваша корзина очищена.", reply_markup=get_main_menu_keyboard())
@dp. callback_query_handler(lambda c: c. data == ‘checkout’)
Async def process_checkout(callback_query: types. CallbackQuery):
await bot. answer_callback_query(callback_query. id)
user_id = callback_query. from_user. id
cart_items = await db. get_cart_items(user_id)
if not cart_items:
await bot. send_message(user_id, "Ваша корзина пуста, невозможно оформить заказ.", reply_markup=get_main_menu_keyboard())
return
total_amount = sum(item[2] * item[3] for item in cart_items) # price * quantity
# В реальном приложении здесь была бы интеграция с платежной системой
# Например: PaymentMethodRequest. send_invoice(…)
# Вместо этого мы просто "оформляем" заказ в БД
order_id = await db. create_order(user_id, total_amount, cart_items)
await db. clear_cart(user_id) # Очищаем корзину после оформления
await bot. send_message(user_id,
f"🎉 Ваш заказ №{order_id} на сумму **{total_amount:.2f}$** успешно оформлен!\n"
"Мы свяжемся с вами для уточнения деталей.",
parse_mode="Markdown",
reply_markup=get_main_menu_keyboard())
# — Запуск бота —
Async def on_startup(dp):
await db. init_db() # Инициализация БД при запуске
await db. add_initial_products() # Добавление тестовых продуктов
If __name__ == ‘__main__’:
executor. start_polling(dp, on_startup=on_startup, skip_updates=True)
Как запустить бота:
Сохраните код для базы данных как db. py. Сохраните код для бота как bot. py. ОБЯЗАТЕЛЬНО замените ‘YOUR_BOT_TOKEN’ на ваш реальный токен API в Bot. py. Откройте терминал, перейдите в папку, где лежат эти файлы. Выполните: python bot. py В Telegram найдите вашего бота и отправьте ему /start.
Дальнейшее развитие (что можно добавить):
Обработка количества товаров в корзине: Добавление/удаление определенного количества товара. Реальная оплата: Интеграция с платежными шлюзами (см. документацию aiogram по платежам). Административные команды: Добавление/удаление товаров, просмотр заказов для администратора. Состояния (States): Для более сложного взаимодействия с пользователем (например, ввод адреса доставки). aiogram имеет отличную поддержку конечных автоматов. Изображения товаров: Отправка фото к описанию товара. Категории товаров. Уведомления: Отправка уведомлений о статусе заказа. Обработка ошибок и логирование: Более детальное логирование и пользовательские сообщения об ошибках. Хостинг: Развертывание бота на сервере (Heroku, AWS, DigitalOcean, VDS), чтобы он работал 24/7. Мягкое удаление товаров из корзины: Не просто очистка, а возможность удалить 1 позицию.
Этот пример дает хорошую отправную точку для создания полноценного магазина на Telegram. Удачи в разработке!