При внесении изменений в этот репозиторий, сначала обсудите с владельцами этого репозитория, что вы хотите сделать.
Обратите внимание, что у нас есть кодекс поведения, пожалуйста, следуйте ему во всех ваших взаимодействиях с проектом.
- Не балуйтесь.
- Старайтесь.
- Если что, не обижайтесь.
Проект стоит рассматривать как boilerplate для написания собственного бота. Т.е. в данный момент в проекте нет функций, которые бы сразу решали какую-то реальную проблему. Но реализованная концепция определяет правила для написания полезных команд и функций для интеграции с чат-платформами.
- ./config/ - расположение всех конфигурационных файлов и настроек для их чтения
- ./core/ - основное ядро проекта
- ./core/commands/ - расположение функций с командами для отправки в бота
- ./core/gateways/ - интеграция с чат-платформами, на которых будет работать бот
- ./core/repositories/ - репозитории запросов ко внешним ресурсам, которые могут быть нужны для выполнения команд
- ./core/services/ - служебные функции для обслуживания бота
- ./core/test/ - директория с автоматическими тестами
./docs/layer-sequence.puml
Чтением настроек занимается пакет dynaconf
(выбран за универсальность),
по умолчанию формат файлов конфигурации принят как TOML (выбран за простоту и еще он симпатичный).
Демо конфига есть в файле ./config/settings.toml
, там же описание настроек и порядок их передачи через переменные окружения.
Альтернативным вариантом можно скопировать этот файл с именем ./config/local_settings.toml
и переопределить все настройки.
При запуске настроенного бота выполняется соединение с выбранной чат-платформой, из доступных в ./core/gateways/libs/
.
По умолчанию запускается режим работы в командной строке (см. ./core/gateways/libs/cli.py
).
Чтобы бот начал работать на какой-то чат-платформе, у него должна быть реализация с доступом к ней.
Каждая реализация доступа к платформе представлена в виде файла или модуля,
имя которого будет являться ключом для раздела в настройках в секции [default.im]
.
Внутри модуля доступа к платформе должен быть класс с именем Gateway
,
который реализует интерфейс core.gateways.interfaces.GatewayInterface
.
Когда пользователь отправляет сообщение через интерфейс чат-платформы в бот и gateway
, определив что требуется выполнить команду,
отправляет сообщение в слой команд - в функцию core.commands.utils.handle_command
.
Она парсит текст сообщения, определяет требуемую для выполнения функцию (по заданному псевдониму) и вызывает ее.
Все команды публикуются в ./core/commands/libs/
и будут динамически подгружаться (без явного импорта).
Каждая функция команды должна быть задекорирована через @register_command
, все правила и разрешения будут реализовываться через нее.
Сигнатура функции команды должна иметь как минимум (*args, **kwargs)
для игнорирования случайно переданных лишних аргументов.
В общем случае все что идет после названия команды будет передано функцию в сыром виде, т.е. как строка.
Чтобы стандартизировать ответы, функция команды должна возвращать результат в виде объекта одного из подтипов core.commands.interfaces.CommandResult
.
В свою очередь, каждая платформа сама сможет его интерпретировать и отправлять результат в нужном для нее виде.
Демонстрация вариантов готовых команд и вариантов их регистраций см. в
./core/commands/libs/common.py
.
Иногда для выполнения команд могут понадобиться сторонние ресурсы. Чтобы не усложнять логику работы самих команд, рекомендуется выносить работу с внешними ресурсами в отдельные модули. В качестве хранилища для таких модулей предлагается использовать слой с репозиториями.