Бесплатный урок с нашим репетитором!

Узнать подробнее

Новая Школа - онлайн-школа подготовки к ЕГЭ
При поддержке
Посмотреть все вопросы нейросети
Бесплатный пробный урок с репетитором

Узнай больше про репетиторов Новой Школы и запишись на бесплатный пробный урок. Мы проверим твой уровень знаний и составим план обучения по любому предмету и классу

Вопрос от Анонимного юзера 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.

Задай свой вопрос

Напиши любую задачу или вопрос, а нейросеть её решит

Похожие вопросы 15

Бесплатно Мобильное приложение ГДЗ
Мобильное приложение ГДЗ

Задавай вопросы искуcственному интеллекту текстом или фотографиями в приложении на iPhone или Android

qr-codegoogle-playapp-store

Саша — ассистент в телеграмме

Создать юз для телеграмма с BOUNTY
Хорошо. Ниже подробное решение и пошаговый план по созданию Telegram-бота с функциональностью bounty (вознаграждений). Это интерпретация задачи как “создать юзера/бота для Telegram с системой bounty” с практическим кодом и архитектурой. Если нужны адаптации под уровень класса/предмета — скажи, и подстрою стиль объяснения. 1) Что именно будет делать такой бот - Администратор может создать задачу bounty с названием, описанием, вознаграждением и сроком. - Любой пользователь может просмотреть открытые bounty и принять их. - Принявший bounty может сдать работу (прикрепить файл или ссылку). - Администратор подтверждает сдачу и “выплачивает” вознаграждение внутри системы (баланс пользователя). Реальную выплату можно интегрировать позже (платежная система или вывод через внешнюю цепочку). - Пользователь может проверить свой баланс и историю действий. 2) Что понадобится - Активный аккаунт Telegram и бот через BotFather. Получаем токен бота. - Простая база данных (SQLite подходит на старте). - Язык и фреймворк: Python + библиотека python-telegram-bot (v20+) или aiogram. В примере ниже — python-telegram-bot. - Простое окружение: Python 3.8+, доступ к интернету, возможность запускать скрипт на сервере или локально. 3) Архитектура и данные (схема БД) Основные сущности: - 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) ); 4) Пошаговый план реализации (кратно и понятно) Шаг 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. 5) Пример минимального кода (Python, python-telegram-bot v20) Примечание: код ниже — минимальный рабочий каркас. Его можно расширять под ваши требования. - Установите зависимости: - pip install python-telegram-bot sqlite3 - Создайте файл bot_bounty.py со следующим содержанием: ```python 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 , /submit ") # Конвейер создания 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 ") 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 или банковский перевод через внешнюю систему. 6) Как разворачивать и развивать - Резервное копирование БД и логов. - Расширить модели: добавить категории/метатеги, дедлайны в формате даты, уведомления в чатах. - Добавить платежную интеграцию: Telegram Payments или сторонний платежный API. - Добавить веб-интерфейс для админов: создание bounty через веб-форму и автоматическую выдачу. 7) Что можно спросить у ученика/для экзамена - Каковы ключевые сущности в БД и какие связи между ними? - Какие шаги нужны для реализации бот-диалога с администраторами и пользователями? - Как обрабатывать статус bounty на разных этапах (open, accepted, submitted, closed)? - Какие меры безопасности стоит учесть при вводе данных и выплатах? Если хочешь, могу адаптировать под конкретный уровень (класс) и предмет: например, сделать упор на базах данных и структурное программирование для 9-11 класса, или упростить до базового уровня для 7 класса. Также могу привести более детальный пример кода на aiogram или оформить полноценную документацию по API.