Added missing XML summaries
This commit is contained in:
@@ -3,22 +3,53 @@ using Telegrator.Filters;
|
|||||||
|
|
||||||
namespace Telegrator.Annotations
|
namespace Telegrator.Annotations
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Attribute for filtering messages where a command argument starts with the specified content.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="content">The content that the command argument should start with.</param>
|
||||||
|
/// <param name="comparison">The string comparison type to use for the check.</param>
|
||||||
|
/// <param name="index">The index of the argument to check (0-based).</param>
|
||||||
public class ArgumentStartsWithAttribute(string content, StringComparison comparison = StringComparison.InvariantCulture, int index = 0)
|
public class ArgumentStartsWithAttribute(string content, StringComparison comparison = StringComparison.InvariantCulture, int index = 0)
|
||||||
: MessageFilterAttribute(new ArgumentStartsWithFilter(content, comparison, index))
|
: MessageFilterAttribute(new ArgumentStartsWithFilter(content, comparison, index))
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Attribute for filtering messages where a command argument ends with the specified content.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="content">The content that the command argument should end with.</param>
|
||||||
|
/// <param name="comparison">The string comparison type to use for the check.</param>
|
||||||
|
/// <param name="index">The index of the argument to check (0-based).</param>
|
||||||
public class ArgumentEndsWithAttribute(string content, StringComparison comparison = StringComparison.InvariantCulture, int index = 0)
|
public class ArgumentEndsWithAttribute(string content, StringComparison comparison = StringComparison.InvariantCulture, int index = 0)
|
||||||
: MessageFilterAttribute(new ArgumentEndsWithFilter(content, comparison, index))
|
: MessageFilterAttribute(new ArgumentEndsWithFilter(content, comparison, index))
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Attribute for filtering messages where a command argument contains the specified content.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="content">The content that the command argument should contain.</param>
|
||||||
|
/// <param name="comparison">The string comparison type to use for the check.</param>
|
||||||
|
/// <param name="index">The index of the argument to check (0-based).</param>
|
||||||
public class ArgumentContainsAttribute(string content, StringComparison comparison = StringComparison.InvariantCulture, int index = 0)
|
public class ArgumentContainsAttribute(string content, StringComparison comparison = StringComparison.InvariantCulture, int index = 0)
|
||||||
: MessageFilterAttribute(new ArgumentContainsFilter(content, comparison, index))
|
: MessageFilterAttribute(new ArgumentContainsFilter(content, comparison, index))
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Attribute for filtering messages where a command argument equals the specified content.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="content">The content that the command argument should equal.</param>
|
||||||
|
/// <param name="comparison">The string comparison type to use for the check.</param>
|
||||||
|
/// <param name="index">The index of the argument to check (0-based).</param>
|
||||||
public class ArgumentEqualsAttribute(string content, StringComparison comparison = StringComparison.InvariantCulture, int index = 0)
|
public class ArgumentEqualsAttribute(string content, StringComparison comparison = StringComparison.InvariantCulture, int index = 0)
|
||||||
: MessageFilterAttribute(new ArgumentEqualsFilter(content, comparison, index))
|
: MessageFilterAttribute(new ArgumentEqualsFilter(content, comparison, index))
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Attribute for filtering messages where a command argument matches a regular expression pattern.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pattern">The regular expression pattern to match against the command argument.</param>
|
||||||
|
/// <param name="options">The regex options to use for the pattern matching.</param>
|
||||||
|
/// <param name="matchTimeout">The timeout for the regex match operation.</param>
|
||||||
|
/// <param name="index">The index of the argument to check (0-based).</param>
|
||||||
public class ArgumentRegexAttribute(string pattern, RegexOptions options = RegexOptions.None, TimeSpan matchTimeout = default, int index = 0)
|
public class ArgumentRegexAttribute(string pattern, RegexOptions options = RegexOptions.None, TimeSpan matchTimeout = default, int index = 0)
|
||||||
: MessageFilterAttribute(new ArgumentRegexFilter(pattern, options, matchTimeout, index))
|
: MessageFilterAttribute(new ArgumentRegexFilter(pattern, options, matchTimeout, index))
|
||||||
{ }
|
{ }
|
||||||
|
|||||||
@@ -5,10 +5,23 @@ using Telegrator.Handlers;
|
|||||||
|
|
||||||
namespace Telegrator.Filters
|
namespace Telegrator.Filters
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Abstract base class for filters that operate on command arguments.
|
||||||
|
/// Provides functionality to extract and validate command arguments from message text.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="index">The index of the argument to filter (0-based).</param>
|
||||||
public abstract class CommandArgumentFilterBase(int index) : Filter<Message>
|
public abstract class CommandArgumentFilterBase(int index) : Filter<Message>
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the chosen argument at the specified index.
|
||||||
|
/// </summary>
|
||||||
protected string Target { get; private set; } = null!;
|
protected string Target { get; private set; } = null!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines whether the filter can pass by extracting the command argument and validating it.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="context">The filter execution context containing the message.</param>
|
||||||
|
/// <returns>True if the argument exists and passes validation; otherwise, false.</returns>
|
||||||
public override bool CanPass(FilterExecutionContext<Message> context)
|
public override bool CanPass(FilterExecutionContext<Message> context)
|
||||||
{
|
{
|
||||||
CommandHandlerAttribute attr = context.CompletedFilters.Get<CommandHandlerAttribute>(0);
|
CommandHandlerAttribute attr = context.CompletedFilters.Get<CommandHandlerAttribute>(0);
|
||||||
@@ -21,57 +34,151 @@ namespace Telegrator.Filters
|
|||||||
return CanPassNext(context);
|
return CanPassNext(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines whether the filter can pass for the given context.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="context">The filter execution context.</param>
|
||||||
|
/// <returns>True if the filter passes; otherwise, false.</returns>
|
||||||
protected abstract bool CanPassNext(FilterExecutionContext<Message> context);
|
protected abstract bool CanPassNext(FilterExecutionContext<Message> context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Filter that checks if a command argument starts with a specified content.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="content">The content to check if the argument starts with.</param>
|
||||||
|
/// <param name="comparison">The string comparison type to use for the check.</param>
|
||||||
|
/// <param name="index">The index of the argument to check (0-based).</param>
|
||||||
public class ArgumentStartsWithFilter(string content, StringComparison comparison = StringComparison.InvariantCulture, int index = 0) : CommandArgumentFilterBase(index)
|
public class ArgumentStartsWithFilter(string content, StringComparison comparison = StringComparison.InvariantCulture, int index = 0) : CommandArgumentFilterBase(index)
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The content to check if the argument starts with.
|
||||||
|
/// </summary>
|
||||||
protected readonly string Content = content;
|
protected readonly string Content = content;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The string comparison type to use for the check.
|
||||||
|
/// </summary>
|
||||||
protected readonly StringComparison Comparison = comparison;
|
protected readonly StringComparison Comparison = comparison;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if the command argument starts with the specified content using the configured comparison.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="_">The filter execution context (unused).</param>
|
||||||
|
/// <returns>True if the argument starts with the specified content; otherwise, false.</returns>
|
||||||
protected override bool CanPassNext(FilterExecutionContext<Message> _)
|
protected override bool CanPassNext(FilterExecutionContext<Message> _)
|
||||||
=> Target.StartsWith(Content, Comparison);
|
=> Target.StartsWith(Content, Comparison);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Filter that checks if a command argument ends with a specified content.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="content">The content to check if the argument ends with.</param>
|
||||||
|
/// <param name="comparison">The string comparison type to use for the check.</param>
|
||||||
|
/// <param name="index">The index of the argument to check (0-based).</param>
|
||||||
public class ArgumentEndsWithFilter(string content, StringComparison comparison = StringComparison.InvariantCulture, int index = 0) : CommandArgumentFilterBase(index)
|
public class ArgumentEndsWithFilter(string content, StringComparison comparison = StringComparison.InvariantCulture, int index = 0) : CommandArgumentFilterBase(index)
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The content to check if the argument ends with.
|
||||||
|
/// </summary>
|
||||||
protected readonly string Content = content;
|
protected readonly string Content = content;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The string comparison type to use for the check.
|
||||||
|
/// </summary>
|
||||||
protected readonly StringComparison Comparison = comparison;
|
protected readonly StringComparison Comparison = comparison;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if the command argument ends with the specified content using the configured comparison.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="_">The filter execution context (unused).</param>
|
||||||
|
/// <returns>True if the argument ends with the specified content; otherwise, false.</returns>
|
||||||
protected override bool CanPassNext(FilterExecutionContext<Message> _)
|
protected override bool CanPassNext(FilterExecutionContext<Message> _)
|
||||||
=> Target.EndsWith(Content, Comparison);
|
=> Target.EndsWith(Content, Comparison);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Filter that checks if a command argument contains a specified content.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="content">The content to check if the argument contains.</param>
|
||||||
|
/// <param name="comparison">The string comparison type to use for the check.</param>
|
||||||
|
/// <param name="index">The index of the argument to check (0-based).</param>
|
||||||
public class ArgumentContainsFilter(string content, StringComparison comparison = StringComparison.InvariantCulture, int index = 0) : CommandArgumentFilterBase(index)
|
public class ArgumentContainsFilter(string content, StringComparison comparison = StringComparison.InvariantCulture, int index = 0) : CommandArgumentFilterBase(index)
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The content to check if the argument contains.
|
||||||
|
/// </summary>
|
||||||
protected readonly string Content = content;
|
protected readonly string Content = content;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The string comparison type to use for the check.
|
||||||
|
/// </summary>
|
||||||
protected readonly StringComparison Comparison = comparison;
|
protected readonly StringComparison Comparison = comparison;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if the command argument contains the specified content using the configured comparison.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="_">The filter execution context (unused).</param>
|
||||||
|
/// <returns>True if the argument contains the specified content; otherwise, false.</returns>
|
||||||
protected override bool CanPassNext(FilterExecutionContext<Message> _)
|
protected override bool CanPassNext(FilterExecutionContext<Message> _)
|
||||||
=> Target.IndexOf(Content, Comparison) >= 0;
|
=> Target.IndexOf(Content, Comparison) >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Filter that checks if a command argument equals a specified content.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="content">The content to check if the argument equals.</param>
|
||||||
|
/// <param name="comparison">The string comparison type to use for the check.</param>
|
||||||
|
/// <param name="index">The index of the argument to check (0-based).</param>
|
||||||
public class ArgumentEqualsFilter(string content, StringComparison comparison = StringComparison.InvariantCulture, int index = 0) : CommandArgumentFilterBase(index)
|
public class ArgumentEqualsFilter(string content, StringComparison comparison = StringComparison.InvariantCulture, int index = 0) : CommandArgumentFilterBase(index)
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The content to check if the argument equals.
|
||||||
|
/// </summary>
|
||||||
protected readonly string Content = content;
|
protected readonly string Content = content;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The string comparison type to use for the check.
|
||||||
|
/// </summary>
|
||||||
protected readonly StringComparison Comparison = comparison;
|
protected readonly StringComparison Comparison = comparison;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if the command argument equals the specified content using the configured comparison.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="_">The filter execution context (unused).</param>
|
||||||
|
/// <returns>True if the argument equals the specified content; otherwise, false.</returns>
|
||||||
protected override bool CanPassNext(FilterExecutionContext<Message> _)
|
protected override bool CanPassNext(FilterExecutionContext<Message> _)
|
||||||
=> Target.Equals(Content, Comparison);
|
=> Target.Equals(Content, Comparison);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ArgumentRegexFilter : CommandArgumentFilterBase
|
/// <summary>
|
||||||
|
/// Filter that checks if a command argument matches a regular expression pattern.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="regex">The regular expression to match against the argument.</param>
|
||||||
|
/// <param name="index">The index of the argument to check (0-based).</param>
|
||||||
|
public class ArgumentRegexFilter(Regex regex, int index = 0) : CommandArgumentFilterBase(index)
|
||||||
{
|
{
|
||||||
private readonly Regex _regex;
|
private readonly Regex _regex = regex;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the match found by the regex.
|
||||||
|
/// </summary>
|
||||||
public Match Match { get; private set; } = null!;
|
public Match Match { get; private set; } = null!;
|
||||||
|
|
||||||
public ArgumentRegexFilter(Regex regex, int index = 0)
|
/// <summary>
|
||||||
: base(index) => _regex = regex;
|
/// Initializes a new instance of <see cref="ArgumentRegexFilter"/> with a regex pattern.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pattern">The regular expression pattern to match.</param>
|
||||||
|
/// <param name="options">The regex options to use.</param>
|
||||||
|
/// <param name="matchTimeout">The timeout for the regex match operation.</param>
|
||||||
|
/// <param name="index">The index of the argument to check (0-based).</param>
|
||||||
public ArgumentRegexFilter(string pattern, RegexOptions options = RegexOptions.None, TimeSpan matchTimeout = default, int index = 0)
|
public ArgumentRegexFilter(string pattern, RegexOptions options = RegexOptions.None, TimeSpan matchTimeout = default, int index = 0)
|
||||||
: base(index) => _regex = new Regex(pattern, options, matchTimeout);
|
: this(new Regex(pattern, options, matchTimeout), index) { }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if the command argument matches the regular expression pattern.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="context">The filter execution context.</param>
|
||||||
|
/// <returns>True if the argument matches the regex pattern; otherwise, false.</returns>
|
||||||
protected override bool CanPassNext(FilterExecutionContext<Message> context)
|
protected override bool CanPassNext(FilterExecutionContext<Message> context)
|
||||||
{
|
{
|
||||||
Match = _regex.Match(Target);
|
Match = _regex.Match(Target);
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ namespace Telegrator.Filters
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class DiceThrowedFilter : MessageFilterBase
|
public class DiceThrowedFilter : MessageFilterBase
|
||||||
{
|
{
|
||||||
private readonly DiceType? Dice;
|
private readonly DiceType Dice;
|
||||||
private readonly int Value;
|
private readonly int Value;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -132,7 +132,7 @@ namespace Telegrator.Filters
|
|||||||
if (Target.Dice == null)
|
if (Target.Dice == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (Dice != null && Target.Dice.Emoji != GetEmojyForDiceType(Dice))
|
if (Target.Dice.Emoji != GetEmojyForDiceType(Dice))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return Target.Dice.Value == Value;
|
return Target.Dice.Value == Value;
|
||||||
|
|||||||
@@ -33,6 +33,10 @@ namespace Telegrator.Handlers
|
|||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public IAwaitingProvider AwaitingProvider { get; }
|
public IAwaitingProvider AwaitingProvider { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes new instance of <see cref="AbstractHandlerContainer{TUpdate}"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="handlerInfo"></param>
|
||||||
public AbstractHandlerContainer(DescribedHandlerInfo handlerInfo)
|
public AbstractHandlerContainer(DescribedHandlerInfo handlerInfo)
|
||||||
{
|
{
|
||||||
ActualUpdate = handlerInfo.HandlingUpdate.GetActualUpdateObject<TUpdate>();
|
ActualUpdate = handlerInfo.HandlingUpdate.GetActualUpdateObject<TUpdate>();
|
||||||
@@ -43,6 +47,15 @@ namespace Telegrator.Handlers
|
|||||||
AwaitingProvider = handlerInfo.AwaitingProvider;
|
AwaitingProvider = handlerInfo.AwaitingProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes new instance of <see cref="AbstractHandlerContainer{TUpdate}"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="actualUpdate"></param>
|
||||||
|
/// <param name="handlingUpdate"></param>
|
||||||
|
/// <param name="client"></param>
|
||||||
|
/// <param name="extraData"></param>
|
||||||
|
/// <param name="filters"></param>
|
||||||
|
/// <param name="awaitingProvider"></param>
|
||||||
public AbstractHandlerContainer(TUpdate actualUpdate, Update handlingUpdate, ITelegramBotClient client, Dictionary<string, object> extraData, CompletedFiltersList filters, IAwaitingProvider awaitingProvider)
|
public AbstractHandlerContainer(TUpdate actualUpdate, Update handlingUpdate, ITelegramBotClient client, Dictionary<string, object> extraData, CompletedFiltersList filters, IAwaitingProvider awaitingProvider)
|
||||||
{
|
{
|
||||||
ActualUpdate = actualUpdate;
|
ActualUpdate = actualUpdate;
|
||||||
@@ -53,6 +66,11 @@ namespace Telegrator.Handlers
|
|||||||
AwaitingProvider = awaitingProvider;
|
AwaitingProvider = awaitingProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates new container of specific update type from thos contatiner
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="QUpdate"></typeparam>
|
||||||
|
/// <returns></returns>
|
||||||
public AbstractHandlerContainer<QUpdate> CreateChild<QUpdate>() where QUpdate : class
|
public AbstractHandlerContainer<QUpdate> CreateChild<QUpdate>() where QUpdate : class
|
||||||
{
|
{
|
||||||
return new AbstractHandlerContainer<QUpdate>(
|
return new AbstractHandlerContainer<QUpdate>(
|
||||||
@@ -61,6 +79,12 @@ namespace Telegrator.Handlers
|
|||||||
CompletedFilters, AwaitingProvider);
|
CompletedFilters, AwaitingProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates new container of specific update type from existing container
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="QUpdate"></typeparam>
|
||||||
|
/// <param name="other"></param>
|
||||||
|
/// <returns></returns>
|
||||||
public static AbstractHandlerContainer<TUpdate> From<QUpdate>(IAbstractHandlerContainer<QUpdate> other) where QUpdate : class
|
public static AbstractHandlerContainer<TUpdate> From<QUpdate>(IAbstractHandlerContainer<QUpdate> other) where QUpdate : class
|
||||||
{
|
{
|
||||||
return new AbstractHandlerContainer<TUpdate>(
|
return new AbstractHandlerContainer<TUpdate>(
|
||||||
|
|||||||
@@ -16,6 +16,9 @@ namespace Telegrator.Handlers
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string ReceivedCommand { get; private set; } = null!;
|
public string ReceivedCommand { get; private set; } = null!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Message text splited by space characters
|
||||||
|
/// </summary>
|
||||||
public string[]? Arguments { get; internal set; } = null;
|
public string[]? Arguments { get; internal set; } = null;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -32,7 +35,10 @@ namespace Telegrator.Handlers
|
|||||||
if (commandEntity.Type != MessageEntityType.BotCommand)
|
if (commandEntity.Type != MessageEntityType.BotCommand)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
ReceivedCommand = message.Text.Substring(commandEntity.Offset + 1, commandEntity.Length - 1);
|
if (commandEntity.Offset != 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
ReceivedCommand = message.Text.Substring(1, commandEntity.Length - 1);
|
||||||
if (ReceivedCommand.Contains('@'))
|
if (ReceivedCommand.Contains('@'))
|
||||||
{
|
{
|
||||||
string[] split = ReceivedCommand.Split('@');
|
string[] split = ReceivedCommand.Split('@');
|
||||||
|
|||||||
@@ -7,21 +7,41 @@ using Telegrator.Handlers.Components;
|
|||||||
|
|
||||||
namespace Telegrator.Handlers
|
namespace Telegrator.Handlers
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Attribute that marks a handler to process inline queries.
|
||||||
|
/// </summary>
|
||||||
public class InlineQueryHandlerAttribute(int importance = 0) : UpdateHandlerAttribute<InlineQueryHandler>(UpdateType.InlineQuery, importance)
|
public class InlineQueryHandlerAttribute(int importance = 0) : UpdateHandlerAttribute<InlineQueryHandler>(UpdateType.InlineQuery, importance)
|
||||||
{
|
{
|
||||||
|
/// <inheritdoc/>
|
||||||
public override bool CanPass(FilterExecutionContext<Update> context) => context.Input.InlineQuery is { } | context.Input.ChosenInlineResult is { };
|
public override bool CanPass(FilterExecutionContext<Update> context) => context.Input.InlineQuery is { } | context.Input.ChosenInlineResult is { };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Abstract base class for handlers that process inline queries.
|
||||||
|
/// </summary>
|
||||||
public abstract class InlineQueryHandler() : AbstractUpdateHandler<Update>(UpdateType.InlineQuery)
|
public abstract class InlineQueryHandler() : AbstractUpdateHandler<Update>(UpdateType.InlineQuery)
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Handler container for the current <see cref="InlineQuery"/> update.
|
||||||
|
/// </summary>
|
||||||
protected IAbstractHandlerContainer<InlineQuery> QueryContainer { get; private set; } = null!;
|
protected IAbstractHandlerContainer<InlineQuery> QueryContainer { get; private set; } = null!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handler container for the current <see cref="ChosenInlineResult"/> update.
|
||||||
|
/// </summary>
|
||||||
protected IAbstractHandlerContainer<ChosenInlineResult> ChosenContainer { get; private set; } = null!;
|
protected IAbstractHandlerContainer<ChosenInlineResult> ChosenContainer { get; private set; } = null!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Incoming update of type <see cref="InlineQuery"/>.
|
||||||
|
/// </summary>
|
||||||
protected InlineQuery InputQuery { get; private set; } = null!;
|
protected InlineQuery InputQuery { get; private set; } = null!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Incoming update of type <see cref="ChosenInlineResult"/>.
|
||||||
|
/// </summary>
|
||||||
protected ChosenInlineResult InputChosen { get; private set; } = null!;
|
protected ChosenInlineResult InputChosen { get; private set; } = null!;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
public override async Task<Result> Execute(IAbstractHandlerContainer<Update> container, CancellationToken cancellation)
|
public override async Task<Result> Execute(IAbstractHandlerContainer<Update> container, CancellationToken cancellation)
|
||||||
{
|
{
|
||||||
switch (container.HandlingUpdate.Type)
|
switch (container.HandlingUpdate.Type)
|
||||||
@@ -30,14 +50,14 @@ namespace Telegrator.Handlers
|
|||||||
{
|
{
|
||||||
QueryContainer = AbstractHandlerContainer<InlineQuery>.From(container);
|
QueryContainer = AbstractHandlerContainer<InlineQuery>.From(container);
|
||||||
InputQuery = QueryContainer.ActualUpdate;
|
InputQuery = QueryContainer.ActualUpdate;
|
||||||
return await Requested(QueryContainer, cancellation);
|
return await Requested(QueryContainer, cancellation).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
case UpdateType.ChosenInlineResult:
|
case UpdateType.ChosenInlineResult:
|
||||||
{
|
{
|
||||||
ChosenContainer = AbstractHandlerContainer<ChosenInlineResult>.From(container);
|
ChosenContainer = AbstractHandlerContainer<ChosenInlineResult>.From(container);
|
||||||
InputChosen = ChosenContainer.ActualUpdate;
|
InputChosen = ChosenContainer.ActualUpdate;
|
||||||
return await Chosen(ChosenContainer, cancellation);
|
return await Chosen(ChosenContainer, cancellation).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -45,10 +65,32 @@ namespace Telegrator.Handlers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Executes handler logic if received update is <see cref="UpdateType.InlineQuery"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="container"></param>
|
||||||
|
/// <param name="cancellation"></param>
|
||||||
|
/// <returns></returns>
|
||||||
public abstract Task<Result> Requested(IAbstractHandlerContainer<InlineQuery> container, CancellationToken cancellation);
|
public abstract Task<Result> Requested(IAbstractHandlerContainer<InlineQuery> container, CancellationToken cancellation);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Executes handler logic if received update is <see cref="UpdateType.ChosenInlineResult"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="container"></param>
|
||||||
|
/// <param name="cancellation"></param>
|
||||||
|
/// <returns></returns>
|
||||||
public abstract Task<Result> Chosen(IAbstractHandlerContainer<ChosenInlineResult> container, CancellationToken cancellation);
|
public abstract Task<Result> Chosen(IAbstractHandlerContainer<ChosenInlineResult> container, CancellationToken cancellation);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Answers inline query
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="results"></param>
|
||||||
|
/// <param name="cacheTime"></param>
|
||||||
|
/// <param name="isPersonal"></param>
|
||||||
|
/// <param name="nextOffset"></param>
|
||||||
|
/// <param name="button"></param>
|
||||||
|
/// <param name="cancellationToken"></param>
|
||||||
|
/// <returns></returns>
|
||||||
protected async Task Answer(
|
protected async Task Answer(
|
||||||
IEnumerable<InlineQueryResult> results,
|
IEnumerable<InlineQueryResult> results,
|
||||||
int? cacheTime = null,
|
int? cacheTime = null,
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ namespace Telegrator.Polling
|
|||||||
|
|
||||||
if (ExecutingHandlersSemaphore != null)
|
if (ExecutingHandlersSemaphore != null)
|
||||||
{
|
{
|
||||||
await ExecutingHandlersSemaphore.WaitAsync();
|
await ExecutingHandlersSemaphore.WaitAsync().ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
@@ -82,7 +82,11 @@ namespace Telegrator.Polling
|
|||||||
|
|
||||||
using (UpdateHandlerBase instance = handlerInfo.HandlerInstance)
|
using (UpdateHandlerBase instance = handlerInfo.HandlerInstance)
|
||||||
{
|
{
|
||||||
lastResult = await instance.Execute(handlerInfo);
|
Task<Result> task = instance.Execute(handlerInfo);
|
||||||
|
HandlerEnqueued?.Invoke(handlerInfo);
|
||||||
|
|
||||||
|
await task.ConfigureAwait(false);
|
||||||
|
lastResult = task.Result;
|
||||||
ExecutingHandlersSemaphore?.Release(1);
|
ExecutingHandlersSemaphore?.Release(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -42,6 +42,12 @@ namespace Telegrator
|
|||||||
return message.Text.Substring(entity.Offset, entity.Length);
|
return message.Text.Substring(entity.Offset, entity.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checkes if sent <see cref="Message"/> contains command. Automatically cuts bot name from it
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message"></param>
|
||||||
|
/// <param name="command"></param>
|
||||||
|
/// <returns></returns>
|
||||||
public static bool IsCommand(this Message message, out string? command)
|
public static bool IsCommand(this Message message, out string? command)
|
||||||
{
|
{
|
||||||
command = null;
|
command = null;
|
||||||
@@ -52,7 +58,10 @@ namespace Telegrator
|
|||||||
if (commandEntity.Type != MessageEntityType.BotCommand)
|
if (commandEntity.Type != MessageEntityType.BotCommand)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
command = message.Text.Substring(commandEntity.Offset + 1, commandEntity.Length - 1);
|
if (commandEntity.Offset != 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
command = message.Text.Substring(1, commandEntity.Length - 1);
|
||||||
if (command.Contains('@'))
|
if (command.Contains('@'))
|
||||||
{
|
{
|
||||||
string[] split = command.Split('@');
|
string[] split = command.Split('@');
|
||||||
@@ -62,9 +71,17 @@ namespace Telegrator
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Split message text into arguments, ignoring command instance. Splits by space character
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
/// <exception cref="InvalidDataException"></exception>
|
||||||
|
/// <exception cref="ArgumentNullException"></exception>
|
||||||
|
/// <exception cref="MissingMemberException"></exception>
|
||||||
public static string[] SplitArgs(this Message message)
|
public static string[] SplitArgs(this Message message)
|
||||||
{
|
{
|
||||||
if (!message.IsCommand(out string? command))
|
if (!message.IsCommand(out _))
|
||||||
throw new InvalidDataException("Message does not contain a command");
|
throw new InvalidDataException("Message does not contain a command");
|
||||||
|
|
||||||
if (message is not { Text.Length: > 0 })
|
if (message is not { Text.Length: > 0 })
|
||||||
@@ -76,10 +93,16 @@ namespace Telegrator
|
|||||||
return message.Text.Split([' '], StringSplitOptions.RemoveEmptyEntries).Skip(1).ToArray();
|
return message.Text.Split([' '], StringSplitOptions.RemoveEmptyEntries).Skip(1).ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tries to split message text into arguments, ignoring command instance. Splits by space character. Exception-free version of <see cref="SplitArgs(Message)"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message"></param>
|
||||||
|
/// <param name="args"></param>
|
||||||
|
/// <returns></returns>
|
||||||
public static bool TrySplitArgs(this Message message, out string[]? args)
|
public static bool TrySplitArgs(this Message message, out string[]? args)
|
||||||
{
|
{
|
||||||
args = null;
|
args = null;
|
||||||
if (!message.IsCommand(out string? command))
|
if (!message.IsCommand(out _))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (message is not { Text.Length: > 0 })
|
if (message is not { Text.Length: > 0 })
|
||||||
@@ -150,21 +173,37 @@ namespace Telegrator
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static class AbstractHandlerContainerExtensions
|
public static class AbstractHandlerContainerExtensions
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Changes bot's reaction to message
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="container"></param>
|
||||||
|
/// <param name="reaction"></param>
|
||||||
|
/// <param name="isBig"></param>
|
||||||
|
/// <param name="cancellationToken"></param>
|
||||||
|
/// <returns></returns>
|
||||||
public static async Task React(
|
public static async Task React(
|
||||||
this IAbstractHandlerContainer<Message> container,
|
this IAbstractHandlerContainer<Message> container,
|
||||||
IEnumerable<ReactionType> reactions,
|
ReactionType reaction,
|
||||||
bool isBig = false,
|
bool isBig = false,
|
||||||
CancellationToken cancellationToken = default)
|
CancellationToken cancellationToken = default)
|
||||||
=> await container.Client.SetMessageReaction(
|
=> await container.Client.SetMessageReaction(
|
||||||
container.ActualUpdate.Chat,
|
container.ActualUpdate.Chat,
|
||||||
container.ActualUpdate.Id,
|
container.ActualUpdate.Id,
|
||||||
reactions, isBig, cancellationToken);
|
[reaction], isBig, cancellationToken);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Changes bot's reaction to message
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="container"></param>
|
||||||
|
/// <param name="reactions"></param>
|
||||||
|
/// <param name="isBig"></param>
|
||||||
|
/// <param name="cancellationToken"></param>
|
||||||
|
/// <returns></returns>
|
||||||
public static async Task React(
|
public static async Task React(
|
||||||
this IAbstractHandlerContainer<Message> container,
|
this IAbstractHandlerContainer<Message> container,
|
||||||
|
IEnumerable<ReactionType> reactions,
|
||||||
bool isBig = false,
|
bool isBig = false,
|
||||||
CancellationToken cancellationToken = default,
|
CancellationToken cancellationToken = default)
|
||||||
params IEnumerable<ReactionType> reactions)
|
|
||||||
=> await container.Client.SetMessageReaction(
|
=> await container.Client.SetMessageReaction(
|
||||||
container.ActualUpdate.Chat,
|
container.ActualUpdate.Chat,
|
||||||
container.ActualUpdate.Id,
|
container.ActualUpdate.Id,
|
||||||
@@ -365,6 +404,17 @@ namespace Telegrator
|
|||||||
cacheTime: cacheTime,
|
cacheTime: cacheTime,
|
||||||
cancellationToken: cancellationToken);
|
cancellationToken: cancellationToken);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Answers inline query
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="container"></param>
|
||||||
|
/// <param name="results"></param>
|
||||||
|
/// <param name="cacheTime"></param>
|
||||||
|
/// <param name="isPersonal"></param>
|
||||||
|
/// <param name="nextOffset"></param>
|
||||||
|
/// <param name="button"></param>
|
||||||
|
/// <param name="cancellationToken"></param>
|
||||||
|
/// <returns></returns>
|
||||||
public static async Task AnswerInlineQuery(
|
public static async Task AnswerInlineQuery(
|
||||||
this IAbstractHandlerContainer<InlineQuery> container,
|
this IAbstractHandlerContainer<InlineQuery> container,
|
||||||
IEnumerable<InlineQueryResult> results,
|
IEnumerable<InlineQueryResult> results,
|
||||||
|
|||||||
Reference in New Issue
Block a user