Новая Школа - онлайн-школа подготовки к ЕГЭ
Задача Задача №3590879
А
Аноним
24 марта 2026 18:58 · публичный вопрос
А
Аноним

Создать юз для телеграмма с BOUNTY

Ответ нейросети
24 марта 2026 18:58

Хорошо. Ниже подробное решение и пошаговый план по созданию Telegram-бота с функциональностью bounty (вознаграждений). Это интерпретация задачи как “создать юзера/бота для Telegram с системой bounty” с практическим кодом и архитектурой. Если нужны адаптации под уровень класса/предмета — скажи, и подстрою стиль объяснения.

  1. Что именно будет делать такой бот
  • Администратор может создать задачу bounty с названием, описанием, вознаграждением и сроком.
  • Любой пользователь может просмотреть открытые bounty и принять их.
  • Принявший bounty может сдать работу (прикрепить файл или ссылку).
  • Администратор подтверждает сдачу и “выплачивает” вознаграждение внутри системы (баланс пользователя). Реальную выплату можно интегрировать позже (платежная система или вывод через внешнюю цепочку).
  • Пользователь может проверить свой баланс и историю действий.
  1. Что понадобится
  • Активный аккаунт Telegram и бот через BotFather. Получаем токен бота.
  • Простая база данных (SQLite подходит на старте).
  • Язык и фреймворк: Python + библиотека python-telegram-bot (v20+) или aiogram. В примере ниже — python-telegram-bot.
  • Простое окружение: Python 3.8+, доступ к интернету, возможность запускать скрипт на сервере или локально.
  1. Архитектура и данные (схема БД) Основные сущности:
  • Users: хранит пользователей бота и их баланс.
  • Bounties: задачи bounty (id, title, description, reward, deadline, created_by, status).
  • BountyAcceptances: связь пользователей с bounty, статус принят/сдано, ссылка на решение и т.д.
  • Transactions: история операций баланса (пополнение, выплата, начисление).

Пример DDL (SQLite): CREATE TABLE users ( id INTEGER PRIMARY KEY AUTOINCREMENT, telegram_id TEXT UNIQUE, username TEXT, role TEXT DEFAULT 'user', balance REAL DEFAULT 0 );

CREATE TABLE bounties ( id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT, description TEXT, reward REAL, deadline TEXT, created_by INTEGER, status TEXT DEFAULT 'open', FOREIGN KEY (created_by) REFERENCES users(id) );

CREATE TABLE bounty_acceptances ( id INTEGER PRIMARY KEY AUTOINCREMENT, bounty_id INTEGER, user_id INTEGER, status TEXT DEFAULT 'accepted', submission_link TEXT, created_at TEXT, FOREIGN KEY (bounty_id) REFERENCES bounties(id), FOREIGN KEY (user_id) REFERENCES users(id) );

CREATE TABLE transactions ( id INTEGER PRIMARY KEY AUTOINCREMENT, user_id INTEGER, amount REAL, reason TEXT, created_at TEXT, FOREIGN KEY (user_id) REFERENCES users(id) );

  1. Пошаговый план реализации (кратно и понятно)

Шаг 0. Подготовка

  • Получите токен бота от BotFather.
  • Установите окружение и зависимости:
    • pip install python-telegram-bot sqlite3
  • Создайте каталог проекта и файл основного скрипта, например bot_bounty.py, а также файл БД (db.sqlite).

Шаг 1. Базовый каркас бота

  • Реализуйте простейшие команды: /start, /help.
  • Подключение к SQLite и базовые операции чтения/записи.

Шаг 2. Модели и база данных

  • Реализуйте функции: ensure_user(telegram_id, username), create_bounty(...), list_bounties(), get_bounty(id), accept_bounty(bounty_id, user_id), submit_bounty(bounty_id, user_id, link), approve_bounty(bounty_id, admin_id).
  • Добавьте логику баланса: за создание bounty ничего не снимается, за принятие баланса не меняется, за выплату баланс увеличивается у исполнителя.

Шаг 3. Функционал администратора (создание bounty)

  • Команда /new_bounty запускает диалог (ConversationHandler) для ввода:
    • title
    • description
    • reward
    • deadline
  • Сохранение в БД и уведомление в чате.

Шаг 4. Функционал пользователя

  • Команда /bounties: показать список открытых bounty.
  • Команда /bounty : подробности задачи и кнопка/команда “Принять”.
  • Команда /accept или кнопка "Принять": регистрируем связь в bounty_acceptances.
  • Команда /submit с присоединением файла/ссылки: сохраняем submission_link/прикрепление, статус переходит к ожидающему утверждения.
  • Команда /balance и /transactions: показывают текущий баланс и историю операций.

Шаг 5. Выплата и утверждение

  • Команда администратора /approve для подтверждения сдачи и начисления вознаграждения на баланс исполнителя.
  • Уведомления пользователю и админу.

Шаг 6. Безопасность и UX

  • Ограничение администратора по роли (проверка по Telegram user_id или списку админов в БД).
  • Валидация входных данных (число вознаграждения, формат даты).
  • Логи действий и простой аудит.

Шаг 7. Тестирование и развёртывание

  • Прогоните локально: /start → создание bounty → просмотр → принятие → сдача → утверждение.
  • Можно разворачивать на бесплатном хостинге (Heroku, Replit) или на любой VPS.
  1. Пример минимального кода (Python, python-telegram-bot v20)

Примечание: код ниже — минимальный рабочий каркас. Его можно расширять под ваши требования.

  • Установите зависимости:
    • pip install python-telegram-bot sqlite3
  • Создайте файл bot_bounty.py со следующим содержанием:
import asyncio
import sqlite3
from datetime import datetime
from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup
from telegram.ext import ApplicationBuilder, CommandHandler, ContextTypes, ConversationHandler, MessageHandler, CallbackQueryHandler, filters

# Базовые константы
DB = "db.sqlite"
TOKEN = "YOUR_BOT_TOKEN_HERE"

# Этапы диалога создания bounty
TITLE, DESC, REWARD, DEADLINE = range(4)

def init_db():
    conn = sqlite3.connect(DB)
    c = conn.cursor()
    c.execute("""CREATE TABLE IF NOT EXISTS users (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        telegram_id TEXT UNIQUE,
        username TEXT,
        role TEXT DEFAULT 'user',
        balance REAL DEFAULT 0
    )""")
    c.execute("""CREATE TABLE IF NOT EXISTS bounties (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        title TEXT,
        description TEXT,
        reward REAL,
        deadline TEXT,
        created_by INTEGER,
        status TEXT DEFAULT 'open',
        FOREIGN KEY (created_by) REFERENCES users(id)
    )""")
    c.execute("""CREATE TABLE IF NOT EXISTS bounty_acceptances (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        bounty_id INTEGER,
        user_id INTEGER,
        status TEXT DEFAULT 'accepted',
        submission_link TEXT,
        created_at TEXT,
        FOREIGN KEY (bounty_id) REFERENCES bounties(id),
        FOREIGN KEY (user_id) REFERENCES users(id)
    )""")
    c.execute("""CREATE TABLE IF NOT EXISTS transactions (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        user_id INTEGER,
        amount REAL,
        reason TEXT,
        created_at TEXT,
        FOREIGN KEY (user_id) REFERENCES users(id)
    )""")
    conn.commit()
    conn.close()

def ensure_user(telegram_user):
    conn = sqlite3.connect(DB)
    c = conn.cursor()
    c.execute("SELECT id FROM users WHERE telegram_id=?", (str(telegram_user.id),))
    row = c.fetchone()
    if row is None:
        c.execute("INSERT INTO users (telegram_id, username) VALUES (?, ?)", (str(telegram_user.id), telegram_user.username or "anon"))
        conn.commit()
        user_id = c.lastrowid
    else:
        user_id = row[0]
    conn.close()
    return user_id

def add_bounty(title, description, reward, deadline, created_by):
    conn = sqlite3.connect(DB)
    c = conn.cursor()
    c.execute("INSERT INTO bounties (title, description, reward, deadline, created_by) VALUES (?, ?, ?, ?, ?)",
              (title, description, reward, deadline, created_by))
    bounty_id = c.lastrowid
    conn.commit()
    conn.close()
    return bounty_id

def list_bounties():
    conn = sqlite3.connect(DB)
    c = conn.cursor()
    c.execute("SELECT id, title, reward, deadline FROM bounties WHERE status='open' ORDER BY id DESC")
    rows = c.fetchall()
    conn.close()
    return rows

def get_bounty(bounty_id):
    conn = sqlite3.connect(DB)
    c = conn.cursor()
    c.execute("SELECT id, title, description, reward, deadline, created_by, status FROM bounties WHERE id=?", (bounty_id,))
    bounty = c.fetchone()
    conn.close()
    return bounty

def accept_bounty(bounty_id, user_id):
    conn = sqlite3.connect(DB)
    c = conn.cursor()
    c.execute("INSERT INTO bounty_acceptances (bounty_id, user_id, created_at) VALUES (?, ?, ?)",
              (bounty_id, user_id, datetime.utcnow().isoformat()))
    conn.commit()
    conn.close()

def submit_bounty(bounty_id, user_id, link):
    conn = sqlite3.connect(DB)
    c = conn.cursor()
    c.execute("UPDATE bounty_acceptances SET submission_link=?, status='submitted' WHERE bounty_id=? AND user_id=?",
              (link, bounty_id, user_id))
    conn.commit()
    conn.close()

def approve_bounty(bounty_id, admin_id):
    conn = sqlite3.connect(DB)
    c = conn.cursor()
    # Найдите исполнителя, у которого есть submission
    c.execute("""SELECT ba.user_id, b.reward
                 FROM bounty_acceptances ba
                 JOIN bounties b ON ba.bounty_id = b.id
                 WHERE ba.bounty_id = ? AND ba.submission_link IS NOT NULL
                 ORDER BY ba.created_at DESC LIMIT 1""", (bounty_id,))
    row = c.fetchone()
    if row:
        user_id, reward = row
        # Увеличиваем баланс пользователя
        c.execute("UPDATE users SET balance = balance + ? WHERE id = ?", (reward, user_id))
        # Обновляем статус bounty
        c.execute("UPDATE bounties SET status='closed' WHERE id=?", (bounty_id,))
        # Присваиваем запись в транзакциях
        c.execute("INSERT INTO transactions (user_id, amount, reason, created_at) VALUES (?, ?, ' bounty payout', ?)",
                  (user_id, reward, datetime.utcnow().isoformat()))
        conn.commit()
        conn.close()
        return user_id, reward
    conn.close()
    return None

async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
    user_id = ensure_user(update.effective_user)
    await update.message.reply_text(
        "Добро пожаловать в bounty-бот! Список команд:\n"
        "/bounties — список открытых задач\n"
        "/new_bounty — создать новую задачу (админ)\n"
        "/balance — проверить баланс\n"
        "/help — помощь"
    )

async def help_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE):
    await update.message.reply_text("Команды:\n"
                                    "/start - старт\n"
                                    "/bounties - открыть список задач\n"
                                    "/new_bounty - создать новую задачу (админ)\n"
                                    "/balance - баланс\n"
                                    "После выбора задачи используйте: /accept <id>, /submit <id> <link>")

# Конвейер создания bounty (ConversationHandler)
async def new_bounty_start(update: Update, context: ContextTypes.DEFAULT_TYPE):
    # здесь можно проверить, что пользователь админ
    return TITLE

async def new_bounty_title(update: Update, context: ContextTypes.DEFAULT_TYPE):
    context.user_data['bounty_title'] = update.message.text
    await update.message.reply_text("Введите описание bounty:")
    return DESC

async def new_bounty_desc(update: Update, context: ContextTypes.DEFAULT_TYPE):
    context.user_data['bounty_desc'] = update.message.text
    await update.message.reply_text("Введите вознаграждение (число):")
    return REWARD

async def new_bounty_reward(update: Update, context: ContextTypes.DEFAULT_TYPE):
    try:
        reward = float(update.message.text)
    except ValueError:
        await update.message.reply_text("Пожалуйста, введите число для вознаграждения.")
        return REWARD
    context.user_data['bounty_reward'] = reward
    await update.message.reply_text("Введите срок дедлайна (например 2024-12-31):")
    return DEADLINE

async def new_bounty_deadline(update: Update, context: ContextTypes.DEFAULT_TYPE):
    context.user_data['bounty_deadline'] = update.message.text
    # Сохранение в БД
    # Найдите id создателя
    user_id = ensure_user(update.effective_user)
    bounty_id = add_bounty(
        context.user_data['bounty_title'],
        context.user_data['bounty_desc'],
        context.user_data['bounty_reward'],
        context.user_data['bounty_deadline'],
        user_id
    )
    await update.message.reply_text(f"Bounty создана успешно. ID: {bounty_id}")
    return ConversationHandler.END

async def cancel(update: Update, context: ContextTypes.DEFAULT_TYPE):
    await update.message.reply_text("Создание bounty отменено.")
    return ConversationHandler.END

async def list_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE):
    items = list_bounties()
    if not items:
        await update.message.reply_text("Нет открытых bounty.")
        return
    text = "Открытые bounty:\n"
    for b in items:
        text += f"ID {b[0]}: {b[1]} — вознагр. {b[2]} — deadline {b[3]}\n"
    await update.message.reply_text(text)

async def bounty_detail(update: Update, context: ContextTypes.DEFAULT_TYPE):
    arg = context.args[0] if context.args else None
    if not arg:
        await update.message.reply_text("Укажите ID bounty, например /bounty 1")
        return
    bounty = get_bounty(int(arg))
    if not bounty:
        await update.message.reply_text(" bounty не найден.")
        return
    text = f"ID: {bounty[0]}\nTitle: {bounty[1]}\nDescription: {bounty[2]}\nReward: {bounty[3]}\nDeadline: {bounty[4]}\nStatus: {bounty[6]}"
    await update.message.reply_text(text)

async def accept_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE):
    if not context.args:
        await update.message.reply_text("Укажите ID bounty, например /accept 1")
        return
    bounty_id = int(context.args[0])
    user_id = ensure_user(update.effective_user)
    accept_bounty(bounty_id, user_id)
    await update.message.reply_text(f"Вы приняли bounty {bounty_id}. Ожидайте сдачи.")

async def submit_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE):
    if len(context.args) < 2:
        await update.message.reply_text("Используйте: /submit <id> <link>")
        return
    bounty_id = int(context.args[0])
    link = context.args[1]
    user_id = ensure_user(update.effective_user)
    submit_bounty(bounty_id, user_id, link)
    await update.message.reply_text("Заявка отправлена. Ожидайте утверждения администратора.")

async def approve_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE):
    if not context.args:
        await update.message.reply_text("Укажите ID bounty для утверждения, например /approve 1")
        return
    bounty_id = int(context.args[0])
    admin_id = ensure_user(update.effective_user)
    result = approve_bounty(bounty_id, admin_id)
    if result:
        user_id, reward = result
        await update.message.reply_text(f"Утверждено. Пользователь {user_id} получил {reward}.")
    else:
        await update.message.reply_text("Не удалось утверждать. Возможно, нет подходящих сдач.")

def main():
    init_db()
    app = ApplicationBuilder().token(TOKEN).build()

    # базовые команды
    app.add_handler(CommandHandler("start", start))
    app.add_handler(CommandHandler("help", help_cmd))
    app.add_handler(CommandHandler("bounties", list_cmd))
    app.add_handler(CommandHandler("bounty", bounty_detail, pass_args=True))
    app.add_handler(CommandHandler("accept", accept_cmd, pass_args=True))
    app.add_handler(CommandHandler("submit", submit_cmd, pass_args=True))
    app.add_handler(CommandHandler("approve", approve_cmd, pass_args=True))

    # конверсация для создания bounty (менее подробная реализация)
    conv_handler = ConversationHandler(
        entry_points=[CommandHandler('new_bounty', new_bounty_start)],
        states={
            TITLE: [MessageHandler(filters.TEXT & ~filters.COMMAND, new_bounty_title)],
            DESC: [MessageHandler(filters.TEXT & ~filters.COMMAND, new_bounty_desc)],
            REWARD: [MessageHandler(filters.TEXT & ~filters.COMMAND, new_bounty_reward)],
            DEADLINE: [MessageHandler(filters.TEXT & ~filters.COMMAND, new_bounty_deadline)],
        },
        fallbacks=[CommandHandler('cancel', cancel)]
    )
    app.add_handler(conv_handler)

    print("Бот запущен...")
    app.run_polling()

if __name__ == "__main__":
    main()

Важные пояснения к коду:

  • Этот каркас показывает базовый механизм: создание bounty, просмотр, принятие, сдача и утверждение плюс баланс.
  • Функции работы с БД упрощены. В реальном проекте лучше оформить их в отдельный модуль и добавить обработку ошибок, транзакции, логирование.
  • Уровень безопасности: в примере не реализована полноценная система ролей. Добавь хранение админов в БД (поле role) и проверку внутри обработчиков.
  • Для реальной выплаты можно интегрировать Telegram Payments или банковский перевод через внешнюю систему.
  1. Как разворачивать и развивать
  • Резервное копирование БД и логов.
  • Расширить модели: добавить категории/метатеги, дедлайны в формате даты, уведомления в чатах.
  • Добавить платежную интеграцию: Telegram Payments или сторонний платежный API.
  • Добавить веб-интерфейс для админов: создание bounty через веб-форму и автоматическую выдачу.
  1. Что можно спросить у ученика/для экзамена
  • Каковы ключевые сущности в БД и какие связи между ними?
  • Какие шаги нужны для реализации бот-диалога с администраторами и пользователями?
  • Как обрабатывать статус bounty на разных этапах (open, accepted, submitted, closed)?
  • Какие меры безопасности стоит учесть при вводе данных и выплатах?

Если хочешь, могу адаптировать под конкретный уровень (класс) и предмет: например, сделать упор на базах данных и структурное программирование для 9-11 класса, или упростить до базового уровня для 7 класса. Также могу привести более детальный пример кода на aiogram или оформить полноценную документацию по API.