Vk-io: рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░: рд╡реАрдХреЗ-рдЖрдИрдУ рдкрд░ рдмреЙрдЯ рдХреЛ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд░рдиреЗ рдХрд╛ 'рдЖрдзрд┐рдХрд╛рд░рд┐рдХ' рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рддрд░реАрдХрд╛ рдХреНрдпрд╛ рд╣реИ?

рдХреЛ рдирд┐рд░реНрдорд┐рдд 14 рджрд┐рд╕ре░ 2020  ┬╖  2рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ  ┬╖  рд╕реНрд░реЛрдд: negezor/vk-io

рдирдорд╕реНрдХрд╛рд░, рдореИрдВрдиреЗ YouTube рдкрд░ рдЖрдкрдХреЗ рдмреЙрдЯреНрд╕ рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рджреЗрдЦрд╛, рдФрд░ рдЙрди рд╕рднреА рдореЗрдВ рдПрдХ рдмрдбрд╝реА рд╕рдорд╕реНрдпрд╛ рдереА: рд╕рднреА рдХреЛрдб 5k рд▓рд╛рдЗрдиреЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рдлрд╝реБрдЯрдХреНрд▓реЙрде рд╣реИред рдЗрд╕рд▓рд┐рдП, рдореЗрд░рд╛ рдПрдХ рдкреНрд░рд╢реНрди рд╣реИ: рдЖрдк рдХреИрд╕реЗ рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ рд╡реАрдХреЗ-рдЖрдИрдУ рдХреЗ рд╕рд╛рде рдПрдХ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреА рд╡реНрдпрд╡рд╕реНрдерд╛ рдХреА рдЬрд╛рдиреА рдЪрд╛рд╣рд┐рдПред рдХреНрдпреЛрдВрдХрд┐ рдЕрдкрдиреЗ рд╡рд░реНрддрдорд╛рди рд╕реНрд╡рд░реВрдк рдореЗрдВ рдпрд╣ рдпрд╛ рддреЛ рдПрдХ рдлреБрдЯрдХреНрд▓реЙрде рдпрд╛ рдПрдХ рдЗрдВрдбреЗрдХреНрд╕ + рдХреЙрдиреНрдлрд┐рдЧ + рдлрд╛рдЗрд▓реЛрдВ рдХрд╛ рдПрдХ рдЧреБрдЪреНрдЫрд╛ рд╣реИ рдЬреЛ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:

Frame 4

/** <strong i="8">@filename</strong>: config.ts */
export const vk = new VK({ /* ... */ })
/** <strong i="11">@filename</strong>: feat1.ts */
import { vk } from "./config"

vk.updates.on('message', async(ctx, next) => {
  /* code */
})
/** <strong i="14">@filename</strong>: index.ts */
import { vk } from "./config"
import "./feat1"

vk.updates.startPolling().then(() => console.log("Bot works!"))

рдФрд░ рдЗрд╕рдореЗрдВ рд╕рдорд╕реНрдпрд╛рдПрдВ рднреА рд╣реИрдВ:

  1. рд╕реВрдЪрдХрд╛рдВрдХ рдореЗрдВ рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдХреЛ рд╢рд╛рдорд┐рд▓ рдХрд░рдиреЗ рдХрд╛ рдХреНрд░рдо рдмреЙрдЯ рдХреЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЛ рдкреНрд░рднрд╛рд╡рд┐рдд рдХрд░рддрд╛ рд╣реИ
  2. рдЖрдк рдХрд┐рд╕реА рд╕реБрд╡рд┐рдзрд╛ рдХреЛ рдЬреЛрдбрд╝рдирд╛ рднреВрд▓ рд╕рдХрддреЗ рд╣реИрдВ
  3. рдХрд╛рдо рдХреЛ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рд╡реАрдХреЗ рдХрд╛ рдЖрд░рдВрднрд┐рдХ рдЙрджрд╛рд╣рд░рдг рд╡рд┐рдиреНрдпрд╛рд╕ рдореЗрдВ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП
  4. рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдХреЗ рдмреАрдЪ рд╕рдВрдмрдВрдзреЛрдВ рдкрд░ рдирдЬрд╝рд░ рд░рдЦрдирд╛ рдореБрд╢реНрдХрд┐рд▓

рдЗрд╕ рдкрд░ рдЖрдкрдХрд╛ рдЙрддреНрддрд░ рд╕реБрдирдирд╛ рдФрд░ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реАрдХрд░рдг рдореЗрдВ рдЗрд╕реЗ рдмрд╣реБрдд рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рджреЛрд╣рд░рд╛рдирд╛ рдкрд╕рдВрдж рдХрд░реЗрдВрдЧреЗ, рдФрд░ рд╕рдВрднрд╡рддрдГ README.md

рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА

рдореИрдВ рдпрд╣ рдирд╣реАрдВ рдХрд╣реВрдВрдЧрд╛ рдХрд┐ "рдЖрдзрд┐рдХрд╛рд░рд┐рдХ" рджреГрд╖реНрдЯрд┐рдХреЛрдг, рдореИрдВ рдХреЗрд╡рд▓ рдЕрдкрдиреА рд╡реНрдпрдХреНрддрд┐рдЧрдд рдкреНрд░рд╛рдердорд┐рдХрддрд╛рдПрдВ рдФрд░ рдереЛрдбрд╝рд╛ рд╕рд╛ рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рд╣рд┐рд╕реНрд╕рд╛ рд╕рд╛рдЭрд╛ рдХрд░реВрдВрдЧрд╛ред

рд╕рд╛рдорд╛рдиреНрдп рдбрд┐рдЬрд╛рдЗрди

рдореИрдВ рд╡рд┐рддрд░рд┐рдд рдореЙрдбреНрдпреВрд▓ рдХреЛ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдореЛрдиреЛрд░реЗрдкреЛ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдкрд╕рдВрдж рдХрд░рддрд╛ рд╣реВрдВ (рдкреБрд╕реНрддрдХрд╛рд▓рдп рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ)ред рдЖрдк рд╕реЗрд╡рд╛рдУрдВ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рдЯреЗрдореНрдкрд▓реЗрдЯ рд▓реЗ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдЕрдореВрд░реНрдд рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкреБрд╕реНрддрдХрд╛рд▓рдп рд╕реЗ рдмреЙрдЯ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рдЕрд▓рдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ (рдХреНрдпреЛрдВрдХрд┐ рдХрд┐рд╕реА рднреА рдмреНрд░реЗрдХрд┐рдВрдЧ рдкрд░рд┐рд╡рд░реНрддрди рдХреЛ рдЗрд╕реЗ рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рдЕрдзрд┐рдХ рдзреНрдпрд╛рди рджреЗрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА)ред рд╡рд┐рдХрд╛рд╕ рдФрд░ рдЙрддреНрдкрд╛рджрди рдореЗрдВ рд╕рдорд╛рди рдкрд░рд┐рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рд╡рд░реНрдЪреБрдЕрд▓ рдорд╢реАрдиреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рднреА рдПрдХ рдЕрдЪреНрдЫрд╛ рд╡рд┐рдЪрд╛рд░ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдбреЙрдХрд░ рдпрд╣рд╛рдВ рдорджрдж рдХрд░реЗрдЧрд╛ред

рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░

рдмреЙрдЯ рдирд┐рд░реНрднрд░рддрд╛ рд╕реНрдкрд╖реНрдЯ рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдП, рдЕрд░реНрдерд╛рддред рдПрдХ рдЖрдпрд╛рдд рдХреЗ рд╕рд╛рде "рдлреАрдЪрд░реНрд╕" рдирд╣реАрдВ рдЬреЛрдбрд╝рдирд╛, рдЕрдиреНрдпрдерд╛ рдПрдХ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдбрд┐рдмрдЧрд┐рдВрдЧ рджреБрдГрд╕реНрд╡рдкреНрди рдпрд╣рд╛рдВ рд╢реБрд░реВ рд╣реЛрдЧрд╛ред рд╕рд╛рд░ рдХреЛрдб:

// 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);
    });

рдЙрдкрд░реЛрдХреНрдд рдХреЛрдб рд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрд╛рддреЗрдВ:

  1. рдореВрд▓ рдкреИрдХреЗрдЬ @my-project/core рд▓рд╛рдЧреВ рдХрд┐рдпрд╛, рдЬрд┐рд╕рдореЗрдВ рдмреЙрдЯ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рдЪреАрдЬреЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реИрдВред
  2. рдХрдорд╛рдВрдб рдкреИрд░рд╛рдореАрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рдЗрд╕ рдкреНрд░рдХрд╛рд░ Dispatcher рдХреЛ рд╕рд╛рдХрд╛рд░ рдХрд░рддреЗ рд╣реИрдВред рдпрд╣ рдХреНрдпреЛрдВ рдЬрд░реВрд░реА рд╣реИ? рд╕рдм рдХреБрдЫ рдмрд╣реБрдд рд╕рд░рд▓ рд╣реИ - рдЖрдк рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╣реАрдВ рд╕реЗ рднреА рдХрдорд╛рдВрдб рдХреЛ рдХреЙрд▓ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдкрд╛рда рд╕реЗ, рд╣рдо рдХрд┐рд╕реА рднреА рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рддрд░реАрдХреЗ рд╕реЗ рдХрдорд╛рдВрдб рдореЗрдВ рд╡рд░реНрдгрд┐рдд рддрд░реНрдХреЛрдВ рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдХреАрдмреЛрд░реНрдб рдореЗрдВ рдмрдЯрди рдмрд╕ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЙрдирдХреЗ рд╕рд╛рде рд╕реЗрдЯ рд╣реЛрддреЗ рд╣реИрдВ рдФрд░ рд╣рдореЗрдВ рдЬрд┐рд╕ рдХрдорд╛рдВрдб рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдЙрд╕реЗ рд╕рдВрдмреЛрдзрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╣рдордиреЗ рддрд░реНрдХ рдХреЗ рджреЛрд╣рд░рд╛рд╡ рд╕реЗ рдмрдЪрд╛ рдФрд░ рддрд░реНрдХреЛрдВ рдХреЗ рд╕рддреНрдпрд╛рдкрди рдХреЛ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд┐рдпрд╛ред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдПрдХ рдХрдорд╛рдВрдб рдХреЛ рджреВрд╕рд░реЗ рд╕реЗ рдХреЙрд▓ рдХрд░рдирд╛:
export const dndCommand = new Command({
    // ...
    handler(context) {
        return context.commander.enter('random', {
            params: {
                min: 1,
                max: 20
            }
        });
    }
});
  1. рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЧрдП рдкреНрд░рддреНрдпреЗрдХ рдкреНрд░рдмрдВрдзрдХ рдореЙрдбреНрдпреВрд▓ рдХреА рдЕрдкрдиреА рдЬрд┐рдореНрдореЗрджрд╛рд░реА рдХрд╛ рдХреНрд╖реЗрддреНрд░ рд╣реЛрддрд╛ рд╣реИ рдФрд░ рдЬреЛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдЙрдкрд▓рдмреНрдз рд╣реЛрддрд╛ рд╣реИ рдЙрд╕рдХреА рд╕реНрдкрд╖реНрдЯ рд╕рдордЭ рджреЗрддрд╛ рд╣реИред

рдирд┐рд╖реНрдХрд░реНрд╖

рдпрд╣ рд╡рд╣ рддрд░реАрдХрд╛ рд╣реИ рдЬрд┐рд╕рдХрд╛ рдореИрдВрдиреЗ рдЕрдкрдиреЗ рдмреЙрдЯреНрд╕ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдерд╛, рдФрд░ рдпрд╣ рд╕рд░рд▓ рд╕реЗ рдЬрдЯрд┐рд▓ рдмреЙрдЯреНрд╕ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╛рдлреА рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдирд┐рдХрд▓рд╛ред рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛, рдкреИрдХреЗрдЬ @my-project/core рдХреЗрд╡рд▓ рдПрдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХрд╛ рдПрдХ рдЙрдкрдирд╛рдо рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП рдЬреЛ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд╕рдм рдХреБрдЫ рд▓рд╛рдЧреВ рдФрд░ рдкрд░реАрдХреНрд╖рдг рдХрд░ рдЪреБрдХрд╛ рд╣реИ, рдФрд░ рдлрд╝рд╛рдЗрд▓ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддреА рд╣реИ:

export { Bot, Command } from 'super-bot-library';

export { ViewerManager } from './middlewares';

рдкреБрд╕реНрддрдХрд╛рд▓рдп рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди рдХреЗ рдорд╛рдорд▓реЛрдВ рдореЗрдВ, рддрдм рдХрд┐рд╕реА рдПрдХ рдЗрдВрдЯрд░рдлреЗрд╕ рдХреЛ рдмрджрд▓рдирд╛ рд╕рдВрднрд╡ рд╣реЛрдЧрд╛ред рд▓реЗрдХрд┐рди рдХреЗрд╡рд▓ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЗ рд▓рд┐рдП рд╕рднреА рддрд░реНрдХ рд░рдЦрдиреЗ рд╕реЗ рдХреЛрдИ рдордирд╛ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред

рд╣реБрдХ рдкрд░ рдмреЙрдЯ рддрд░реНрдХ рдХрд╛ рдПрдХ рдФрд░ рджрд┐рд▓рдЪрд╕реНрдк рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП React рдпрд╛ Vue рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЖрдк рдЗрд╕ рдХреЛрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрд╕реЗ рд▓рд╛рдЗрд╡ рдкреЛрдХ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рд╕рднреА 2 рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

рдореИрдВ рдпрд╣ рдирд╣реАрдВ рдХрд╣реВрдВрдЧрд╛ рдХрд┐ "рдЖрдзрд┐рдХрд╛рд░рд┐рдХ" рджреГрд╖реНрдЯрд┐рдХреЛрдг, рдореИрдВ рдХреЗрд╡рд▓ рдЕрдкрдиреА рд╡реНрдпрдХреНрддрд┐рдЧрдд рдкреНрд░рд╛рдердорд┐рдХрддрд╛рдПрдВ рдФрд░ рдереЛрдбрд╝рд╛ рд╕рд╛ рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рд╣рд┐рд╕реНрд╕рд╛ рд╕рд╛рдЭрд╛ рдХрд░реВрдВрдЧрд╛ред

рд╕рд╛рдорд╛рдиреНрдп рдбрд┐рдЬрд╛рдЗрди

рдореИрдВ рд╡рд┐рддрд░рд┐рдд рдореЙрдбреНрдпреВрд▓ рдХреЛ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдореЛрдиреЛрд░реЗрдкреЛ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдкрд╕рдВрдж рдХрд░рддрд╛ рд╣реВрдВ (рдкреБрд╕реНрддрдХрд╛рд▓рдп рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ)ред рдЖрдк рд╕реЗрд╡рд╛рдУрдВ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рдЯреЗрдореНрдкрд▓реЗрдЯ рд▓реЗ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдЕрдореВрд░реНрдд рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкреБрд╕реНрддрдХрд╛рд▓рдп рд╕реЗ рдмреЙрдЯ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рдЕрд▓рдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ (рдХреНрдпреЛрдВрдХрд┐ рдХрд┐рд╕реА рднреА рдмреНрд░реЗрдХрд┐рдВрдЧ рдкрд░рд┐рд╡рд░реНрддрди рдХреЛ рдЗрд╕реЗ рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рдЕрдзрд┐рдХ рдзреНрдпрд╛рди рджреЗрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА)ред рд╡рд┐рдХрд╛рд╕ рдФрд░ рдЙрддреНрдкрд╛рджрди рдореЗрдВ рд╕рдорд╛рди рдкрд░рд┐рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рд╡рд░реНрдЪреБрдЕрд▓ рдорд╢реАрдиреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рднреА рдПрдХ рдЕрдЪреНрдЫрд╛ рд╡рд┐рдЪрд╛рд░ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдбреЙрдХрд░ рдпрд╣рд╛рдВ рдорджрдж рдХрд░реЗрдЧрд╛ред

рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░

рдмреЙрдЯ рдирд┐рд░реНрднрд░рддрд╛ рд╕реНрдкрд╖реНрдЯ рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдП, рдЕрд░реНрдерд╛рддред рдПрдХ рдЖрдпрд╛рдд рдХреЗ рд╕рд╛рде "рдлреАрдЪрд░реНрд╕" рдирд╣реАрдВ рдЬреЛрдбрд╝рдирд╛, рдЕрдиреНрдпрдерд╛ рдПрдХ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдбрд┐рдмрдЧрд┐рдВрдЧ рджреБрдГрд╕реНрд╡рдкреНрди рдпрд╣рд╛рдВ рд╢реБрд░реВ рд╣реЛрдЧрд╛ред рд╕рд╛рд░ рдХреЛрдб:

// 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);
    });

рдЙрдкрд░реЛрдХреНрдд рдХреЛрдб рд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрд╛рддреЗрдВ:

  1. рдореВрд▓ рдкреИрдХреЗрдЬ @my-project/core рд▓рд╛рдЧреВ рдХрд┐рдпрд╛, рдЬрд┐рд╕рдореЗрдВ рдмреЙрдЯ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рдЪреАрдЬреЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реИрдВред
  2. рдХрдорд╛рдВрдб рдкреИрд░рд╛рдореАрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рдЗрд╕ рдкреНрд░рдХрд╛рд░ Dispatcher рдХреЛ рд╕рд╛рдХрд╛рд░ рдХрд░рддреЗ рд╣реИрдВред рдпрд╣ рдХреНрдпреЛрдВ рдЬрд░реВрд░реА рд╣реИ? рд╕рдм рдХреБрдЫ рдмрд╣реБрдд рд╕рд░рд▓ рд╣реИ - рдЖрдк рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╣реАрдВ рд╕реЗ рднреА рдХрдорд╛рдВрдб рдХреЛ рдХреЙрд▓ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдкрд╛рда рд╕реЗ, рд╣рдо рдХрд┐рд╕реА рднреА рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рддрд░реАрдХреЗ рд╕реЗ рдХрдорд╛рдВрдб рдореЗрдВ рд╡рд░реНрдгрд┐рдд рддрд░реНрдХреЛрдВ рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдХреАрдмреЛрд░реНрдб рдореЗрдВ рдмрдЯрди рдмрд╕ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЙрдирдХреЗ рд╕рд╛рде рд╕реЗрдЯ рд╣реЛрддреЗ рд╣реИрдВ рдФрд░ рд╣рдореЗрдВ рдЬрд┐рд╕ рдХрдорд╛рдВрдб рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдЙрд╕реЗ рд╕рдВрдмреЛрдзрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╣рдордиреЗ рддрд░реНрдХ рдХреЗ рджреЛрд╣рд░рд╛рд╡ рд╕реЗ рдмрдЪрд╛ рдФрд░ рддрд░реНрдХреЛрдВ рдХреЗ рд╕рддреНрдпрд╛рдкрди рдХреЛ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд┐рдпрд╛ред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдПрдХ рдХрдорд╛рдВрдб рдХреЛ рджреВрд╕рд░реЗ рд╕реЗ рдХреЙрд▓ рдХрд░рдирд╛:
export const dndCommand = new Command({
    // ...
    handler(context) {
        return context.commander.enter('random', {
            params: {
                min: 1,
                max: 20
            }
        });
    }
});
  1. рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЧрдП рдкреНрд░рддреНрдпреЗрдХ рдкреНрд░рдмрдВрдзрдХ рдореЙрдбреНрдпреВрд▓ рдХреА рдЕрдкрдиреА рдЬрд┐рдореНрдореЗрджрд╛рд░реА рдХрд╛ рдХреНрд╖реЗрддреНрд░ рд╣реЛрддрд╛ рд╣реИ рдФрд░ рдЬреЛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдЙрдкрд▓рдмреНрдз рд╣реЛрддрд╛ рд╣реИ рдЙрд╕рдХреА рд╕реНрдкрд╖реНрдЯ рд╕рдордЭ рджреЗрддрд╛ рд╣реИред

рдирд┐рд╖реНрдХрд░реНрд╖

рдпрд╣ рд╡рд╣ рддрд░реАрдХрд╛ рд╣реИ рдЬрд┐рд╕рдХрд╛ рдореИрдВрдиреЗ рдЕрдкрдиреЗ рдмреЙрдЯреНрд╕ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдерд╛, рдФрд░ рдпрд╣ рд╕рд░рд▓ рд╕реЗ рдЬрдЯрд┐рд▓ рдмреЙрдЯреНрд╕ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╛рдлреА рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдирд┐рдХрд▓рд╛ред рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛, рдкреИрдХреЗрдЬ @my-project/core рдХреЗрд╡рд▓ рдПрдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХрд╛ рдПрдХ рдЙрдкрдирд╛рдо рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП рдЬреЛ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд╕рдм рдХреБрдЫ рд▓рд╛рдЧреВ рдФрд░ рдкрд░реАрдХреНрд╖рдг рдХрд░ рдЪреБрдХрд╛ рд╣реИ, рдФрд░ рдлрд╝рд╛рдЗрд▓ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддреА рд╣реИ:

export { Bot, Command } from 'super-bot-library';

export { ViewerManager } from './middlewares';

рдкреБрд╕реНрддрдХрд╛рд▓рдп рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди рдХреЗ рдорд╛рдорд▓реЛрдВ рдореЗрдВ, рддрдм рдХрд┐рд╕реА рдПрдХ рдЗрдВрдЯрд░рдлреЗрд╕ рдХреЛ рдмрджрд▓рдирд╛ рд╕рдВрднрд╡ рд╣реЛрдЧрд╛ред рд▓реЗрдХрд┐рди рдХреЗрд╡рд▓ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЗ рд▓рд┐рдП рд╕рднреА рддрд░реНрдХ рд░рдЦрдиреЗ рд╕реЗ рдХреЛрдИ рдордирд╛ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред

рд╣реБрдХ рдкрд░ рдмреЙрдЯ рддрд░реНрдХ рдХрд╛ рдПрдХ рдФрд░ рджрд┐рд▓рдЪрд╕реНрдк рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП React рдпрд╛ Vue рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЖрдк рдЗрд╕ рдХреЛрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрд╕реЗ рд▓рд╛рдЗрд╡ рдкреЛрдХ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдмрд╣реБрдд рдЕрдЪреНрдЫреЗ рдФрд░ рд╡рд┐рд╕реНрддреГрдд рдЙрддреНрддрд░ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рджред рдФрд░ рдореИрдВ рдЖрдкрд╕реЗ рдЗрд╕ рдореБрджреНрджреЗ рдХреЛ рдЦреБрд▓рд╛ рдЫреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╣рдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛ рддрд╛рдХрд┐ рдЕрдиреНрдп рд▓реЛрдЧ рднреА рдЗрд╕реЗ рдкрдврд╝ рд╕рдХреЗрдВ

рдХреНрдпрд╛ рдпрд╣ рдкреГрд╖реНрда рдЙрдкрдпреЛрдЧреА рдерд╛?
0 / 5 - 0 рд░реЗрдЯрд┐рдВрдЧреНрд╕

рд╕рдВрдмрдВрдзрд┐рдд рдореБрджреНрджреЛрдВ

T1MOXA picture T1MOXA  ┬╖  29рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

Saiv46 picture Saiv46  ┬╖  9рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

Pacmard picture Pacmard  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

zardoy picture zardoy  ┬╖  18рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

alexey2baranov picture alexey2baranov  ┬╖  8рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ