-
Notifications
You must be signed in to change notification settings - Fork 85
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Архитектура: Какой официально
оптимальный способ организации бота на VK-IO
#387
Comments
Не скажу что "официальный" подход, просто поделюсь личными предпочтениями и немного практической части. Общий дизайнЯ предпочитаю использовать подход monorepo для организации распределённых модулей (собственно его использует библиотека). Можно взять уже готовый шаблон для сервисов, и отделить реализацию бота от библиотеки с помощью абстракций (так как любое критическое изменения потребует большого внимания для его адаптирования). Так же по-хорошему стоит использовать виртуальные машины для идентичных условий в разработке и продакшене, здесь поможет например Docker. АрхитектураЗависимости бота должны быть явными, т.е. никаких добавлений "фич" с помощью одного импорта, иначе тут начнётся сущий кошмар отладки. Абстрактный код: // commands/random.ts
import { Command } from '@my-project/core';
import { getRandomIntegerInRange } from '@my-project/utils';
export const randomCommand = new Command({
slug: 'random',
aliases: [
'рандом',
'random'
],
description = 'рандмоное число в промежутке';
arguments: [
{
type: 'integer',
key: 'min',
label: 'минк/макс',
default: null
},
{
type: 'integer',
key: 'max',
label: 'минк/макс',
default: null
}
],
handler(context) {
// Работаем с аргументами, а не текстом
let { min = null, max = null } = context.commander.params;
if (min === null && max === null) {
min = 0;
max = 100;
} else if (max === null) {
max = min;
min = 0;
}
const result = getRandomIntegerInRange(min, max);
return context.answer({
text: `число в промежутке ${min} - ${max}: ${result}`
});
}
});
// commands/index.ts
export * from './random';
// bot.ts
import {
Bot,
SessionManager,
RedisSessionStorage,
RateLimitManager,
CommanderManager
} from '@my-project/core';
import * as commands from './commands';
const sessionManager = new SessionManager({
storage: new RedisSessionStorage({})
});
const rateLimitManager = new RateLimitManager({
maxPerSecond: 1
});
const commanderManager = new CommanderManager();
for (const command of Object.values(commands)) {
commanderManager.add(command);
}
const bot = new Bot({
// ...options
});
// Это может быть кастомная цепочка middleware в боте
bot.incoming.on('message', sessionManager.middleware);
bot.incoming.on('message', rateLimitManager.middleware);
bot.incoming.on('message', commanderManager.middleware);
bot.start()
.then(() => {
console.log('Bot started', error);
})
.catch((error: Error) => {
console.error('Error starting bot', error);
process.exit(1);
}); Важные вещи из кода выше:
export const dndCommand = new Command({
// ...
handler(context) {
return context.commander.enter('random', {
params: {
min: 1,
max: 20
}
});
}
});
ЗаключениеЭто подход я использовал в моих ботах, и он оказался вполне удобным для реализации от простых до сложных ботов. В лучшем случае пакет export { Bot, Command } from 'super-bot-library';
export { ViewerManager } from './middlewares'; В случаях изменений в библиотеке можно тогда будет заменить один из интерфейсов. Но никто не запрещает держать всё логику только для проекта. Есть ещё интересный вариант реализации логики бота на хуках, который применяется допустим в |
Спасибо, очень хороший и развёрнутый ответ. И я бы хотел попросить, тебя оставить issue открытым, чтобы другие люди тоже смогли прочитать |
Привет, смотрел твой разбор ботов на ютубе, и у них у всех была одна большая проблема: весь код - портянка на 5к строк. Поэтому у меня созрел вопрос: как ты видишь, что должен быть устроен проект с VK-IO. Потому что в нынешнем виде это либо портянка, либо индекс + конфиг + куча файлов, который выглядит примерно вот так:
И у него тоже есть проблемы:
Хотелось бы услышать твой ответ на это и дублирование его в очень явном виде в документацию, и возможно в
README.md
The text was updated successfully, but these errors were encountered: