Работа с событиями

Поскольку PRTelegramBot основан на библиотеке Telegram.Bot, он может использовать его функционал. Из-за того что в PRTelegramBot можно создавать сразу несколько экземпляров ботов, были реализованы разные события на функционал библиотеки Telegram.Bot.

События в PRBot.Events

    /// <summary>
    /// События для бота.
    /// </summary>
    public sealed class TEvents
    {
        #region Поля и свойства

        /// <summary>
        /// Бот для событий.
        /// </summary>
        public PRBotBase Bot { get; private set; }

        /// <summary>
        /// События для обновления типа сообщения.
        /// </summary>
        public MessageEvents MessageEvents { get; private set; }

        /// <summary>
        /// События обновлений.
        /// </summary>
        public UpdateEvents UpdateEvents { get; private set; }

        /// <summary>
        /// События команд.
        /// </summary>
        public CommandsEvents CommandsEvents { get; private set; }

        #endregion

        #region События

        /// <summary>
        /// Событие когда отказано в доступе.
        /// </summary>
        public event Func<BotEventArgs, Task>? OnAccessDenied;

        /// <summary>
        /// Событие когда пользователь написал start с аргументом.
        /// </summary>
        public event Func<StartEventArgs, Task>? OnUserStartWithArgs;

        /// <summary>
        /// Событие когда нужно проверить привилегии перед выполнением команды.
        /// </summary>
        public event Func<PrivilegeEventArgs, Task>? OnCheckPrivilege;

        /// <summary>
        /// Событие когда указан не верный тип сообщения.
        /// </summary>
        public event Func<BotEventArgs, Task>? OnWrongTypeMessage;

        /// <summary>
        /// Событие когда указан не верный тип чат.
        /// </summary>
        public event Func<BotEventArgs, Task>? OnWrongTypeChat;

        /// <summary>
        /// Событие когда не найдена команда.
        /// </summary>
        public event Func<BotEventArgs, Task>? OnMissingCommand;

        /// <summary>
        /// Событие когда произошла ошибка при обработке команды.
        /// </summary>
        public event Func<BotEventArgs, Task>? OnErrorCommand;

        /// <summary>
        /// Событие ошибки.
        /// </summary>
        public event Func<ErrorLogEventArgs, Task>? OnErrorLog;

        /// <summary>
        /// Событие общих логов.
        /// </summary>
        public event Func<CommonLogEventArgs, Task>? OnCommonLog;

        #endregion

        #region Методы

        /// <summary>
        /// Вызвать событие <see cref="OnUserStartWithArgs"/>.
        /// </summary>
        /// <param name="e">Аргументы события.</param>
        internal void OnUserStartWithArgsInvoke(StartEventArgs e) => OnUserStartWithArgs?.Invoke(e);

        /// <summary>
        /// Вызвать событие <see cref="OnMissingCommand"/>.
        /// </summary>
        /// <param name="e">Аргументы события.</param>
        internal void OnMissingCommandInvoke(BotEventArgs e) => OnMissingCommand?.Invoke(e);

        /// <summary>
        /// Вызвать событие <see cref="OnErrorCommand"/>.
        /// </summary>
        /// <param name="e">Аргументы события.</param>
        internal void OnErrorCommandInvoke(BotEventArgs e) => OnErrorCommand?.Invoke(e);

        /// <summary>
        /// Вызвать событие <see cref="OnAccessDenied"/>.
        /// </summary>
        /// <param name="e">Аргументы события.</param>
        internal void OnAccessDeniedInvoke(BotEventArgs e) => OnAccessDenied?.Invoke(e);

        /// <summary>
        /// Вызвать событие <see cref="OnCheckPrivilege"/>.
        /// </summary>
        /// <param name="e">Аргументы события.</param>
        internal void OnCheckPrivilegeInvoke(PrivilegeEventArgs e) => OnCheckPrivilege?.Invoke(e);

        /// <summary>
        /// Вызвать событие <see cref="OnWrongTypeMessage"/>.
        /// </summary>
        /// <param name="e">Аргументы события.</param>
        internal void OnWrongTypeMessageInvoke(BotEventArgs e) => OnWrongTypeMessage?.Invoke(e);

        /// <summary>
        /// Вызвать событие <see cref="OnWrongTypeChat"/>.
        /// </summary>
        /// <param name="e">Аргументы события.</param>
        internal void OnWrongTypeChatInvoke(BotEventArgs e) => OnWrongTypeChat?.Invoke(e);

        /// <summary>
        /// Вызвать событие <see cref="OnErrorLog"/>.
        /// </summary>
        /// <param name="e">Аргументы события.</param>
        public void OnErrorLogInvoke(ErrorLogEventArgs e) => OnErrorLog?.Invoke(e);

        /// <summary>
        /// Вызвать событие <see cref="OnCommonLog"/> через готовый объект аргументов.
        /// </summary>
        /// <param name="e">Создатель аргументов события.</param>
        public void OnCommonLogInvoke(CommonLogEventArgsCreator e) =>
            OnCommonLog?.Invoke(new CommonLogEventArgs(e.Context, e));

        /// <summary>
        /// Вызвать событие <see cref="OnCommonLog"/> с простым сообщением.
        /// </summary>
        /// <param name="message">Текст сообщения.</param>
        public void OnCommonLogInvoke(string message) =>
            OnCommonLogInvoke(new CommonLogEventArgsCreator(message, "Common"));

        /// <summary>
        /// Вызвать событие <see cref="OnCommonLog"/> с указанием типа лога.
        /// </summary>
        /// <param name="message">Текст сообщения.</param>
        /// <param name="type">Тип лога.</param>
        public void OnCommonLogInvoke(string message, string type) =>
            OnCommonLogInvoke(new CommonLogEventArgsCreator(message, type));

        /// <summary>
        /// Вызвать событие <see cref="OnCommonLog"/> с контекстом бота.
        /// </summary>
        /// <param name="message">Текст сообщения.</param>
        /// <param name="type">Тип лога.</param>
        /// <param name="context">Контекст бота.</param>
        public void OnCommonLogInvoke(string message, string type, BotContext context) =>
            OnCommonLogInvoke(new CommonLogEventArgsCreator(message, type, context));

        /// <summary>
        /// Вызвать событие <see cref="OnCommonLog"/> с цветом текста.
        /// </summary>
        /// <param name="message">Текст сообщения.</param>
        /// <param name="type">Тип лога.</param>
        /// <param name="color">Цвет текста в консоли.</param>
        public void OnCommonLogInvoke(string message, string type, ConsoleColor color) =>
            OnCommonLogInvoke(new CommonLogEventArgsCreator(message, type, color));

        /// <summary>
        /// Вызвать событие <see cref="OnCommonLog"/> с цветом текста и контекстом бота.
        /// </summary>
        /// <param name="message">Текст сообщения.</param>
        /// <param name="type">Тип лога.</param>
        /// <param name="color">Цвет текста в консоли.</param>
        /// <param name="context">Контекст бота.</param>
        public void OnCommonLogInvoke(string message, string type, ConsoleColor color, BotContext context) =>
            OnCommonLogInvoke(new CommonLogEventArgsCreator(message, type, color, context));

        /// <summary>
        /// Дополнительный метод вызова <see cref="OnCommonLog"/> с типом лога.
        /// </summary>
        /// <param name="message">Текст сообщения.</param>
        /// <param name="type">Тип лога.</param>
        public void OnCommonLogInvokeInvoke(string message, string type) =>
            OnCommonLogInvoke(new CommonLogEventArgsCreator(message, type));

        #endregion

        #region Конструкторы

        /// <summary>
        /// Конструктор.
        /// </summary>
        /// <param name="bot">Бот.</param>
        public TEvents(PRBotBase bot)
        {
            Bot = bot;
            MessageEvents = new MessageEvents();
            UpdateEvents = new UpdateEvents();
            CommandsEvents = new CommandsEvents();
        }

        #endregion
    }

Пример подписки и использования событий

Создадим статический класс ExampleEvent, который будет хранить методы для событий:

using ConsoleExample.Extension;
using PRTelegramBot.Extensions;
using PRTelegramBot.Models.EventsArgs;
using Helpers = PRTelegramBot.Helpers;

namespace ConsoleExample.Examples.Events
{
    public static class ExampleEvents
    {
        public static async Task OnWrongTypeChat(BotEventArgs e)
        {
            string msg = "Неверный тип чата";
            await Helpers.Message.Send(e.Context, msg);
        }

        public static async Task OnMissingCommand(BotEventArgs args)
        {
            string msg = "Не найдена команда";
            await Helpers.Message.Send(args.Context, msg);
        }

        public static async Task OnErrorCommand(BotEventArgs args)
        {
            string msg = "Произошла ошибка при обработке команды";
            await Helpers.Message.Send(args.Context, msg);
        }

        /// <summary>
        /// Событие проверки привилегий пользователя
        /// </summary>
        /// <param name="callback">callback функция выполняется в случае успеха</param>
        /// <param name="mask">Маска доступа</param>
        /// Подписка на событие проверки привелегий <see cref="Program"/>
        public static async Task OnCheckPrivilege(PrivilegeEventArgs e)
        {
            if (!e.Mask.HasValue)
            {
                // Нет маски доступа, выполняем метод.
                await e.ExecuteMethod(e.Context);
                return;
            }

            // Получаем значение маски требуемого доступа.
            var requiredAccess = e.Mask.Value;

            // Получаем флаги доступа пользователя.
            // Здесь вы на свое усмотрение реализываете логику получение флагов, например можно из базы данных получить.
            var userFlags = e.Context.Update.LoadExampleFlagPrivilege();

            if (requiredAccess.HasFlag(userFlags))
            {
                // Доступ есть, выполняем метод.
                await e.ExecuteMethod(e.Context);
                return;
            }

            // Доступа нет.
            string errorMsg = "У вас нет доступа к данной функции";
            await Helpers.Message.Send(e.Context, errorMsg);
            return;

        }

        public static async Task OnUserStartWithArgs(StartEventArgs args)
        {
            string msg = "Пользователь отправил старт с аргументом";
            await Helpers.Message.Send(args.Context, msg);
        }
        public static async Task OnWrongTypeMessage(BotEventArgs e)
        {
            string msg = "Неверный тип сообщения";
            await Helpers.Message.Send(e.Context, msg);
        }
    }
}

Ниже представлен пример создание нового бота, который подписывается на эти события.

// Парсинг динамических команд из json файла в формате ключ:значение.
var botJsonProvider = new BotConfigJsonProvider(".\\Configs\\commands.json");
var dynamicCommands = botJsonProvider.GetKeysAndValues();

var telegram = new PRBotBuilder("")
                    .SetBotId(0)
                    .AddConfigPath(ExampleConstants.BUTTONS_FILE_KEY, ".\\Configs\\buttons.json")
                    .AddConfigPath(ExampleConstants.MESSAGES_FILE_KEY, ".\\Configs\\messages.json")
                    .AddAdmin(1111111)
                    .SetClearUpdatesOnStart(true)
                    .AddReplyDynamicCommands(dynamicCommands)
                    .AddMiddlewares(new OneMiddleware(), new TwoMiddleware(), new ThreeMiddleware())
                    .Build();

// Подписка на простые логи.
telegram.Events.OnCommonLog += Telegram_OnLogCommon;
// Подписка на логи с ошибками.
telegram.Events.OnErrorLog += Telegram_OnLogError;
// Запуск работы бота.
await telegram.StartAsync();
// Инициализация событий для бота.
InitEvents(telegram);

void InitEvents(PRBotBase bot)
{
    // Обработка до всех update 
    bot.Events.UpdateEvents.OnPreUpdate += Handler_OnUpdate;

    // Обработка после всех update
    bot.Events.UpdateEvents.OnPostUpdate += Handler_OnPostUpdate;

    // Обработка не правильный тип сообщений
    bot.Events.OnWrongTypeMessage += ExampleEvent.OnWrongTypeMessage;

    // Обработка пользователь написал в чат start с deeplink
    bot.Events.OnUserStartWithArgs += ExampleEvent.OnUserStartWithArgs;

    // Обработка проверка привилегий
    bot.Events.OnCheckPrivilege += ExampleEvent.OnCheckPrivilege;

    // Обработка пропущенной  команды
    bot.Events.OnMissingCommand += ExampleEvent.OnMissingCommand;

    // Обработка не верного типа чата
    bot.Events.OnWrongTypeChat += ExampleEvent.OnWrongTypeChat;

    // Обработка локаций
    bot.Events.MessageEvents.OnLocationHandle += ExampleEvent.OnLocationHandle;

    // Обработка контактных данных
    bot.Events.MessageEvents.OnContactHandle += ExampleEvent.OnContactHandle;

    // Обработка голосований
    bot.Events.MessageEvents.OnPollHandle += ExampleEvent.OnPollHandle;

    // Обработка WebApps
    bot.Events.MessageEvents.OnWebAppsHandle += ExampleEvent.OnWebAppsHandle;

    // Обработка, когда пользователю отказано в доступе
    bot.Events.OnAccessDenied += ExampleEvent.OnAccessDenied;

    //Обработка сообщения с документом
    bot.Events.MessageEvents.OnDocumentHandle += ExampleEvent.OnDocumentHandle;

    //Обработка сообщения с аудио
    bot.Events.MessageEvents.OnAudioHandle += ExampleEvent.OnAudioHandle;

    //Обработка сообщения с видео
    bot.Events.MessageEvents.OnVideoHandle += ExampleEvent.OnVideoHandle;

    //Обработка сообщения с фото
    bot.Events.MessageEvents.OnPhotoHandle += ExampleEvent.OnPhotoHandle;

    //Обработка сообщения с стикером
    bot.Events.MessageEvents.OnStickerHandle += ExampleEvent.OnStickerHandle;

    //Обработка сообщения с голосовым сообщением
    bot.Events.MessageEvents.OnVoiceHandle += ExampleEvent.OnVoiceHandle;

    //Обработка сообщения с неизвестным типом
    bot.Events.MessageEvents.OnUnknownHandle += ExampleEvent.OnUnknownHandle;

    //Обработка сообщения с местоположением
    bot.Events.MessageEvents.OnVenueHandle += ExampleEvent.OnVenueHandle;

    //Обработка сообщения с игрой
    bot.Events.MessageEvents.OnGameHandle += ExampleEvent.OnGameHandle;

    //Обработка сообщения с видеозаметкой
    bot.Events.MessageEvents.OnVideoNoteHandle += ExampleEvent.OnVideoNoteHandle;

    //Обработка сообщения с игральной костью
    bot.Events.MessageEvents.OnDiceHandle += ExampleEvent.OnDiceHandle;

    //Обработка обновления изменения группы/чата
    bot.Events.UpdateEvents.OnMyChatMemberHandle += ExampleEvent.OnUpdateMyChatMember;
}

async Task<UpdateResult> Handler_OnUpdate(BotEventArgs e)
{
    return UpdateResult.Continue;
}

async Task Handler_OnWithoutMessageUpdate(BotEventArgs e)
{
    //Обработка обновление кроме message и callback
}

Last updated