Files
Telegrator/Telegrator/Handlers/CommandHandler.cs
T

175 lines
5.9 KiB
C#

using Telegram.Bot.Types;
using Telegram.Bot.Types.Enums;
using Telegrator.Attributes;
using Telegrator.Filters.Components;
namespace Telegrator.Handlers
{
/// <summary>
/// Attribute that marks a handler to process command messages.
/// This handler will be triggered when users send bot commands (messages starting with '/').
/// </summary>
/// <param name="concurrency">The maximum number of concurrent executions allowed (default: 1).</param>
public class CommandHandlerAttribute(int concurrency = 1) : UpdateHandlerAttribute<CommandHandler>(UpdateType.Message, concurrency)
{
/// <summary>
/// Gets the command that was extracted from the message (without the '/' prefix and bot username).
/// </summary>
public string ReceivedCommand { get; private set; } = null!;
/// <summary>
/// Checks if the update contains a valid bot command and extracts the command text.
/// </summary>
/// <param name="context">The filter execution context containing the update.</param>
/// <returns>True if the update contains a valid bot command; otherwise, false.</returns>
public override bool CanPass(FilterExecutionContext<Update> context)
{
if (context.Input.Message is not { Entities.Length: > 0, Text.Length: > 0 } message)
return false;
MessageEntity commandEntity = message.Entities[0];
if (commandEntity.Type != MessageEntityType.BotCommand)
return false;
ReceivedCommand = message.Text.Substring(commandEntity.Offset + 1, commandEntity.Length - 1);
if (ReceivedCommand.Contains('@'))
{
string[] split = ReceivedCommand.Split('@');
ReceivedCommand = split[0];
}
return true;
}
}
/// <summary>
/// Abstract base class for handlers that process command messages.
/// Provides functionality to extract and parse command arguments.
/// </summary>
public abstract class CommandHandler : MessageHandler
{
/// <summary>
/// Cached array of command arguments.
/// </summary>
private string[]? _cmdArgsSplit;
/// <summary>
/// Cached string representation of command arguments.
/// </summary>
private string? _argsString;
/// <summary>
/// Gets the command that was extracted from the message.
/// </summary>
protected string ReceivedCommand
{
get => CompletedFilters.Get<CommandHandlerAttribute>(0).ReceivedCommand;
}
/// <summary>
/// Gets the arguments string (everything after the command).
/// </summary>
protected string ArgumentsString
{
get => _argsString ??= ArgsStringify();
}
/// <summary>
/// Gets the command arguments as an array of strings.
/// </summary>
protected string[] Arguments
{
get => _cmdArgsSplit ??= SplitArgs();
}
/// <summary>
/// Splits the command arguments into an array of strings.
/// </summary>
/// <returns>An array of command arguments.</returns>
private string[] SplitArgs()
{
if (Input.Text is not { Length: > 0 })
return [];
return Input.Text.Split([" "], StringSplitOptions.RemoveEmptyEntries).Skip(1).ToArray();
}
/// <summary>
/// Extracts the arguments string from the command message.
/// </summary>
/// <returns>The arguments string (everything after the command).</returns>
private string ArgsStringify()
{
if (Input.Text is not { Length: > 0 })
return string.Empty;
return Input.Text.Substring(ReceivedCommand.Length + 1);
}
}
/// <summary>
/// Abstract base class for branching handlers that process command messages.
/// Provides functionality to extract and parse command arguments for branching scenarios.
/// </summary>
public abstract class BranchingCommandHandler : BranchingMessageHandler
{
/// <summary>
/// Cached array of command arguments.
/// </summary>
private string[]? _cmdArgsSplit;
/// <summary>
/// Cached string representation of command arguments.
/// </summary>
private string? _argsString;
/// <summary>
/// Gets the command that was extracted from the message.
/// </summary>
protected string ReceivedCommand
{
get => CompletedFilters.Get<CommandHandlerAttribute>(0).ReceivedCommand;
}
/// <summary>
/// Gets the arguments string (everything after the command).
/// </summary>
protected string ArgumentsString
{
get => _argsString ??= ArgsStringify();
}
/// <summary>
/// Gets the command arguments as an array of strings.
/// </summary>
protected string[] Arguments
{
get => _cmdArgsSplit ??= SplitArgs();
}
/// <summary>
/// Splits the command arguments into an array of strings.
/// </summary>
/// <returns>An array of command arguments.</returns>
private string[] SplitArgs()
{
if (Input.Text is not { Length: > 0 })
return [];
return Input.Text.Split([" "], StringSplitOptions.RemoveEmptyEntries).Skip(1).ToArray();
}
/// <summary>
/// Extracts the arguments string from the command message.
/// </summary>
/// <returns>The arguments string (everything after the command).</returns>
private string ArgsStringify()
{
if (Input.Text is not { Length: > 0 })
return string.Empty;
return Input.Text.Substring(ReceivedCommand.Length + 1);
}
}
}