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

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

События в PRBot.Events

using PRTelegramBot.Models.EventsArgs;
using Telegram.Bot.Types;

namespace PRTelegramBot.Core.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; }

        #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<ErrorLogEventArgs, Task>? OnErrorLog;

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

        #endregion

        #region Методы

        public void OnErrorLogInvoke(Exception exception, Update update) => OnErrorLogInvoke(new ErrorLogEventArgsCreator(exception, update));
  
        public void OnErrorLogInvoke(Exception exception) => OnErrorLogInvoke(new ErrorLogEventArgsCreator(exception));

        public void OnCommonLogInvoke(CommonLogEventArgsCreator e) => OnCommonLog?.Invoke(new CommonLogEventArgs(Bot, e));

        public void OnCommonLogInvoke(string message) => OnCommonLogInvoke(new CommonLogEventArgsCreator(message, "Common"));

        public void OnCommonLogInvoke(string message, string type) => OnCommonLogInvoke(new CommonLogEventArgsCreator(message, type));

        public void OnCommonLogInvoke(string message, string type, Update update) => OnCommonLogInvoke(new CommonLogEventArgsCreator(message, type, update));

        public void OnCommonLogInvoke(string message, string type, ConsoleColor color) => OnCommonLogInvoke(new CommonLogEventArgsCreator(message, type, color));

        public void OnCommonLogInvoke(string message, string type, ConsoleColor color, Update update) => OnCommonLogInvoke(new CommonLogEventArgsCreator(message, type, color, update));

        public void OnErrorOnCommonLogInvokeInvoke(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();
        }

        #endregion
    }
}

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

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

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

namespace ConsoleExample.Examples
{
    public static class ExampleEvent
    {
        public static async Task OnDiceHandle(BotEventArgs e)
        {
            var dice = e.Update.Message.Dice;
            //Обработка данных
        }

        public static async Task OnVideoNoteHandle(BotEventArgs e)
        {
            var videonote = e.Update.Message.VideoNote;
            //Обработка данных
        }

        public static async Task OnGameHandle(BotEventArgs e)
        {
            var game = e.Update.Message.Game;
            //Обработка данных
        }

        public static async Task OnVenueHandle(BotEventArgs e)
        {
            var venue = e.Update.Message.Venue;
            //Обработка данных
        }

        public static async Task OnUnknownHandle(BotEventArgs e)
        {
            //Обработка данных
        }

        public static async Task OnVoiceHandle(BotEventArgs e)
        {
            var voice = e.Update.Message.Voice;
            //Обработка данных
        }

        public static async Task OnStickerHandle(BotEventArgs e)
        {
            var sticker = e.Update.Message.Sticker;
            //Обработка данных
        }

        public static async Task OnPhotoHandle(BotEventArgs e)
        {
            var photo = e.Update.Message.Photo;
            //Обработка данных
        }

        public static async Task OnVideoHandle(BotEventArgs e)
        {
            var video = e.Update.Message.Video;
            //Обработка данных
        }

        public static async Task OnAudioHandle(BotEventArgs e)
        {
            var audio = e.Update.Message.Audio;
            //Обработка данных
        }

        public static async Task OnDocumentHandle(BotEventArgs e)
        {
            var document = e.Update.Message.Document;
            //Обработка данных
        }

        public static async Task OnAccessDenied(BotEventArgs e)
        {
            //Обработка данных
        }

        public static async Task OnWebAppsHandle(BotEventArgs e)
        {
            var webApp = e.Update.Message.WebAppData;
            //Обработка данных
        }

        public static async Task OnPollHandle(BotEventArgs e)
        {
            var poll = e.Update.Message.Poll;
            //Обработка данных
        }

        public static async Task OnContactHandle(BotEventArgs e)
        {
            var contact = e.Update.Message.Contact;
            //Обработка данных
        }

        public static async Task OnLocationHandle(BotEventArgs e)
        {
            var location = e.Update.Message.Location;
            //Обработка данных
        }

        public static async Task OnWrongTypeChat(BotEventArgs e)
        {
            string msg = "Неверный тип чата";
            await Helpers.Message.Send(e.BotClient, e.Update, msg);
        }

        public static async Task OnMissingCommand(BotEventArgs args)
        {
            string msg = "Не найдена команда";
            await Helpers.Message.Send(args.BotClient, args.Update, 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.BotClient, e.Update);
                return;
            }

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

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

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

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

        }

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

        internal static async Task OnUpdateMyChatMember(BotEventArgs args)
        {
            //Обработка информации из myChatHandle
            var myChatHandle = args.Update.MyChatMember;
            try
            {
                if(myChatHandle.NewChatMember.Status == Telegram.Bot.Types.Enums.ChatMemberStatus.Member)
                {
                    if(myChatHandle.NewChatMember.User.Id == args.BotClient.BotId) 
                    {
                        await Helpers.Message.Send(args.BotClient, myChatHandle.Chat.Id, "Hello world");
                    }
                    else
                    {
                        //Другие персонажи
                    }
                }
            }
            catch(Exception ex)
            {
                args.Bot.Events.OnErrorLogInvoke(ex);
            }
        }
    }
}

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

// Парсинг динамических команд из 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.Start();
// Инициализация событий для бота.
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