Skip to content

alleexxeeyy/funpay-universal

Repository files navigation

FunPay Universal

telegram plugins python stars forks

Современный бот-помощник для FunPay 🤖🟦


🗺️ Навигация

⚙️ Функционал

🤖 Управление в Telegram боте

  • 🎪 Удобное и понятное меню
  • 💬 Отправка сообщений в чаты
  • 🖼️ Отправка изображений в чаты
  • 🛠️ Настройка конфигов
  • 📊 Просмотр статистики (за 24 часа, неделю, месяц и всё время)
  • 👤 Просмотр профиля (вся информация)
  • 🗒️ Просмотр логов из консоли
  • 🔔 Уведомления о событиях (новые сообщения, продажи...)
  • ⚡ Быстрые ответы (сообщения по нажатию одной кнопки)
  • 👤 Просмотр профиля
  • и многое другое...

✨ Широкие возможности

  • 🧩 Система модулей (плагины, подключаемые к боту)
  • 🟢 Вечный онлайн на сайте
  • 🎈 Сообщения на события (приветственное, новая продажа...)
  • ❗ Собственные команды
  • 🚀 Авто-выдача товаров (поштучная и сообщением)
  • ⬆️ Авто-поднятие лотов
  • 📞 Авто-создание тикетов на закрытие заказов
  • 🌐 Подключение прокси
  • и многое другое...

⬇️ Установка

🔷 Windows

  1. Установите Python версии 3.12.x (на других версиях работа бота не гарантируется), перейдя по ссылке https://www.python.org/downloads/release/python-31210/ (при установке нажмите на пункт Add to PATH).
  2. Скачайте последнюю Release версию и распакуйте в любое удобное для вас место.
  3. Откройте install.bat и дождитесь установки всех необходимых зависимостей, а после закройте окно.
  4. Чтобы запустить бота, откройте запускатор start.bat.
  5. После первого запуска следуйте действиям в консоли.

Возникли проблемы с установкой? Нажми на меня

🍎 macOS

  1. Установите Python версии 3.12.x с официального сайта или через Homebrew:
    brew install python@3.12
  2. Скачайте последнюю Release версию и распакуйте в любое удобное место.
  3. Дважды кликните install_mac.command — откроется Terminal, дождитесь установки зависимостей.
  4. Запустите бота двойным кликом по start_mac.command.
  5. Следуйте инструкциям в консоли.

♨️ Linux (Ubuntu 24)

  1. Выполните команду
    bash <(curl -s https://raw.githubusercontent.com/alleexxeeyy/funpay-universal/main/install.sh)
  2. Следуйте инструкциям установщика. Он автоматически установит все необходимые для работы компоненты.

🕹️ Команды для управления

Команда Что делает
fpuniversal 🕹️ Меню с командами
fpuniversal setup ⚙️ Первичная настройка
fpuniversal start 🟢 Запуск бота
fpuniversal stop ⛔ Остановка бота
fpuniversal restart 🔄️ Перезапуск бота
fpuniversal status 📈 Статус бота
fpuniversal log 🗒️ Логи бота
fpuniversal log100 📃 Последние 100 логов
fpuniversal update 🔵 Обновление бота
fpuniversal enable ☑️ Включить авто-запуск бота
fpuniversal disable ❌ Выключить авто-запуск бота

📚 Для разработчиков

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

📌 Основные ивенты

Ивенты бота (BOT_EVENT_HANDLERS)

Ивенты, которые выполняются при определённом действии бота.

Ивент Когда вызывается Передающиеся аргументы
ON_MODULE_ENABLED При включении модуля (включая первое подключение и перезагрузку) Module
ON_MODULE_DISABLED При выключении модуля (включая перезагрузку) Module
ON_INIT При инициализации бота -
ON_FUNPAY_BOT_INIT При инициализации (запуске) FunPay бота FunPayBot
ON_TELEGRAM_BOT_INIT При инициализации (запуске) Telegram бота TelegramBot

Ивенты FunPay (FUNPAY_EVENT_HANDLERS)

Ивенты, получаемые в слушателе событий в FunPay боте.

Ивент Когда вызывается Передающиеся аргументы
EventTypes.CHAT_INITIALIZED Чат инициализирован FunPayBot, ChatInitializedEvent
EventTypes.NEW_MESSAGE Новое сообщение в чате FunPayBot, NewMessageEvent
EventTypes.NEW_DEAL Создана новая сделка (когда покупатель оплатил товар) FunPayBot, NewDealEvent
EventTypes.NEW_REVIEW Новый отзыв по сделке FunPayBot, NewReviewEvent
EventTypes.DEAL_CONFIRMED Сделка подтверждена FunPayBot, DealConfirmedEvent
EventTypes.DEAL_ROLLED_BACK Продавец оформил возврат сделки FunPayBot, DealRolledBackEvent
EventTypes.DEAL_HAS_PROBLEM Пользователь сообщил о проблеме в сделке FunPayBot, DealHasProblemEvent
EventTypes.DEAL_PROBLEM_RESOLVED Проблема в сделке решена FunPayBot, DealProblemResolvedEvent
EventTypes.DEAL_STATUS_CHANGED Статус сделки изменён FunPayBot, DealStatusChangedEvent
EventTypes.ITEM_PAID Пользователь оплатил предмет FunPayBot, ItemPaidEvent
EventTypes.ITEM_SENT Предмет отправлен (продавец подтвердил выполнение сделки) FunPayBot, ItemSentEvent
📁 Строение модуля


Модуль - это папка, внутри которой находятся важные компоненты. Вы можете изучить строение модуля, опираясь на шаблонный модуль, но стоит понимать, что это лишь пример, сделанный нами.

Обязательные константы хендлеров:

Константа Тип Описание
BOT_EVENT_HANDLERS dict[str, list[Any]] В этом словаре задаются хендлеры ивентов бота
FUNPAY_EVENT_HANDLERS dict[EventTypes, list[Any] В этом словаре задаются хендлеры ивентов FunPay
TELEGRAM_BOT_ROUTERS list[Router] В этом массиве задаются роутеры модульного Telegram бота

Обязательные константы метаданных:

Константа Тип Описание
PREFIX str Префикс
VERSION str Версия
NAME str Название
DESCRIPTION str Описание
AUTHORS str Авторы
LINKS str Ссылки на авторов

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

🔧 Пример содержимого:

Обратите внимание, что метаданные были вынесены в отдельный файл meta.py, но импортируются в __init__.py. Это сделано для избежания конфликтов импорта в дальнейшей части кода модуля.

meta.py:

from colorama import Fore, Style

PREFIX = f"{Fore.LIGHTCYAN_EX}[test module]{Fore.WHITE}"
VERSION = "0.1"
NAME = "test_module"
DESCRIPTION = "Тестовый модуль. /test_module в Telegram боте для управления"
AUTHORS = "@alleexxeeyy"
LINKS = "https://t.me/alleexxeeyy, https://t.me/alexeyproduction"

__init__.py:

from FunPayApi.common.enums import EventTypes
from core.modules_manager import Module, disable_module

from .plbot.handlers import on_funpay_bot_init, on_new_message, on_new_deal
from .tgbot import router
from .tgbot._handlers import on_telegram_bot_init
from .meta import *


_module: Module = None


def set_module(module: Module):
    global _module
    _module = module

def get_module():
    return _module

async def on_module_enabled(module: Module):
    try:
        set_module(module)
        print(f"{PREFIX} Модуль подключен и активен")
    except:
        await disable_module(_module.uuid)


BOT_EVENT_HANDLERS = {
    "ON_MODULE_ENABLED": [on_module_enabled],
    "ON_FUNPAY_BOT_INIT": [on_funpay_bot_init],
    "ON_TELEGRAM_BOT_INIT": [on_telegram_bot_init]
}
FUNPAY_EVENT_HANDLERS = {
    EventTypes.NEW_MESSAGE: [on_new_message],
    EventTypes.NEW_DEAL: [on_new_deal],
    # ...
}
TELEGRAM_BOT_ROUTERS = [router]
🛠️ Полезные инструменты

📝 Настроенные врапперы файлов конфигурации и файлов данных

Вместо того, чтобы лишний раз мучаться с файлами конфигурациями, написанием кода для управлениями ими, мы подготовили для вас готовое решение. У бота есть уже настроенные классы в файлах settings.py и data.py

Как это работает?

Допустим, вы хотите создать файл конфигурации в своём модуле, для этого вам нужно будет создать файл settings.py в корне папки модуля. Содержимое settings.py должно быть примерно следующим:

import os
from settings import (
    Settings as sett,
    SettingsFile
)


CONFIG = SettingsFile(
    name="config", #  название файла конфигурации
    path=os.path.join(os.path.dirname(__file__), "module_settings", "config.json"), #  путь к файлу конфигурации (в данном случае относительно папки модуля)
    need_restore=True, #  нужно ли восстанавливать конфиг
    default={
        "bool_param": True,
        "str_param": "qwerty",
        "int_param": 123
    } #  стандартное содержимое файла
)

DATA = [CONFIG]


class Settings:
  
    @staticmethod
    def get(name: str) -> dict:
        return sett.get(name, DATA)

    @staticmethod
    def set(name: str, new: list | dict) -> dict:
        return sett.set(name, new, DATA)

Файл конфигурации задаётся с помощью датакласса SettingsFile, который в свою очередь, передаётся в массив DATA.

Далее, получить данные из конфига или сохранить данные в конфиг можно вот так:

from . import settings as sett

config = sett.get("config") #  получаем конфиг
print(config["bool_param"]) # -> True
print(config["str_param"]) #  -> qwerty
print(config["int_param"]) #  -> 123
config["bool_param"] = False
config["str_param"] = "uiop"
config["int_param"] = 456
sett.set("config", config) #  задаём конфигу новое значение

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

Описание аргументов датакласса SettingsFile:

Аргумент Описание
name Название файла конфигурации, которое будем использовать при получении и записи
path Путь к файлу конфигурации
need_restore Нужно ли восстанавливать конфиг? Допустим, в стандартное значение конфига у вас добавились новые данные, а в уже созданном ранее файле конфигурации они отсутствуют. Если параметр включен, скрипт будет сверять текущие данные конфига со стандартными указанными, и если в текущих данных не будет того или иного ключа, который есть в стандартном значении, он автоматически добавится в конфиг. Так же, если тип значения ключа стандартного конфига не соответствует существующему (например, в файле строковый тип, а в стандартном значении числовой), также этот ключ в текущем конфиге будет заменён на стандартное значение
default Стандартное значение файла конфигурации


Точно также устроен и файл данных, но он нужен для хранения информации, собранной самим скриптом, а не указанной пользователей. Например, вы хотите создать файл данных в своём модуле, для этого вам нужно будет создать файл data.py в корне папки модуля.

Содержимое data.py должно быть примерно следующим:

import os
from data import (
    Data as data,
    DataFile
)


LATEST_EVENTS_TIMES = DataFile(
    name="new_forms", #  название файла данных
    path=os.path.join(os.path.dirname(__file__), "module_data", "new_forms.json"), #  путь к файлу данных (в данном случае относительно папки модуля)
    default={} #  стандартное содержимое файла
)

DATA = [LATEST_EVENTS_TIMES]


class Data:

    @staticmethod
    def get(name: str) -> dict:
        return data.get(name, DATA)

    @staticmethod
    def set(name: str, new: list | dict) -> dict:
        return data.set(name, new, DATA)

Здесь всё аналогично файлу конфигурации, только служит для другой задачи.

🔌 Удобное управление состояниями модуля

Используя методы из core/modules.py, можно удобно включать/выключать/перезагружать текущий модуль. Для того, чтобы это сделать, нужно прежде всего получить UUID текущего запущенного модуля, который генерируется при его инициализации.

Например, в файле __init__.py можно делать так:

# import ...


_module: Module = None


async def set_module(module: Module):
    global _module
    _module = module

def get_module():
    return _module


BOT_EVENT_HANDLERS = {
    "ON_MODULE_ENABLED": [set_module],
    # ...
}
# ...

А потом в любом удобном месте управлять модулем:

from core.modules import enable_module, disable_module, reload_module

from . import get_module


await disable_module(get_module().uuid) #  выключает модуль
await enable_module(get_module().uuid) #  включает модуль
await reload_module(get_module().uuid) #  перезагружает модуль
❗ Примечания


Функционал Telegram бота написан на библиотеке aiogram 3, система внедрения пользовательского функционала Telegram бота работает на основе роутеров, которые сливаются с основным, главным роутером бота. И так, как они сливаются воедино, могут возникнуть осложнения, если, например Callback данные имеют идентичное название. Поэтому, после написания функционала Telegram бота для модуля, лучше переименуйте эти данные уникальным образом, чтобы они не совпадали с названиями основного бота или дополнительных подключаемых модулей.

🔗 Ссылки

About

Современный бот-помощник для FunPay с модульной системой. Полностью открыт для разработчиков

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors