Removed doubled filters variations for reply-chain message filtering
Instead using MessageRepliedAttribute to filter messages in reply-chain Old types renamed to new framework name
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
using Telegrator.Filters;
|
||||
|
||||
namespace Telegrator.Annotations
|
||||
{
|
||||
/// <summary>
|
||||
/// Attribute for filtering messages with reply to messages of this bot.
|
||||
/// </summary>
|
||||
public class MeRepliedAttribute()
|
||||
: MessageFilterAttribute(new MeRepliedFilter())
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Attribute for filtering messages in reply chain.
|
||||
/// </summary>
|
||||
public class MessageRepliedAttribute(int replyDepth = 1)
|
||||
: MessageFilterAttribute(new MessageRepliedFilter(replyDepth))
|
||||
{ }
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
using Telegram.Bot.Types.Enums;
|
||||
using Telegrator.Filters;
|
||||
|
||||
namespace Telegrator.Annotations
|
||||
{
|
||||
/// <summary>
|
||||
/// Attribute for filtering messages that are replies to messages containing mentions.
|
||||
/// Allows handlers to respond to messages that reply to messages with specific mentions.
|
||||
/// </summary>
|
||||
public class RepliedMentionedAttribute : MessageFilterAttribute
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the RepliedMentionedAttribute that matches replies to any mention.
|
||||
/// </summary>
|
||||
/// <param name="replyDepth">The depth of the reply chain to check (default: 1).</param>
|
||||
public RepliedMentionedAttribute(int replyDepth = 1)
|
||||
: base(new RepliedMessageHasEntityFilter(MessageEntityType.Mention, 0, null, replyDepth), new RepliedMentionedFilter(replyDepth)) { }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the RepliedMentionedAttribute that matches replies to mentions at a specific offset.
|
||||
/// </summary>
|
||||
/// <param name="offset">The offset position where the mention should occur in the replied message.</param>
|
||||
/// <param name="replyDepth">The depth of the reply chain to check (default: 1).</param>
|
||||
public RepliedMentionedAttribute(int offset, int replyDepth = 1)
|
||||
: base(new RepliedMessageHasEntityFilter(MessageEntityType.Mention, offset, null, replyDepth), new RepliedMentionedFilter(replyDepth)) { }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the RepliedMentionedAttribute that matches replies to a specific mention.
|
||||
/// </summary>
|
||||
/// <param name="mention">The specific mention text to match in the replied message.</param>
|
||||
/// <param name="replyDepth">The depth of the reply chain to check (default: 1).</param>
|
||||
public RepliedMentionedAttribute(string mention, int replyDepth = 1)
|
||||
: base(new RepliedMessageHasEntityFilter(MessageEntityType.Mention, replyDepth), new RepliedMentionedFilter(mention, replyDepth)) { }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the RepliedMentionedAttribute that matches replies to a specific mention at a specific offset.
|
||||
/// </summary>
|
||||
/// <param name="mention">The specific mention text to match in the replied message.</param>
|
||||
/// <param name="offset">The offset position where the mention should occur in the replied message.</param>
|
||||
/// <param name="replyDepth">The depth of the reply chain to check (default: 1).</param>
|
||||
public RepliedMentionedAttribute(string mention, int offset, int replyDepth = 1)
|
||||
: base(new RepliedMessageHasEntityFilter(MessageEntityType.Mention, offset, null, replyDepth), new RepliedMentionedFilter(mention, replyDepth)) { }
|
||||
}
|
||||
}
|
||||
@@ -1,102 +0,0 @@
|
||||
using Telegram.Bot.Types.Enums;
|
||||
using Telegrator.Filters;
|
||||
|
||||
namespace Telegrator.Annotations
|
||||
{
|
||||
/// <summary>
|
||||
/// Attribute for filtering messages where the replied-to message was sent in a forum chat.
|
||||
/// </summary>
|
||||
/// <param name="replyDepth">How many levels up the reply chain to check (default: 1)</param>
|
||||
public class RepliedChatIsForumAttribute(int replyDepth = 1)
|
||||
: MessageFilterAttribute(new RepliedMessageChatIsForumFilter(replyDepth))
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Attribute for filtering messages where the replied-to message was sent in a specific chat by ID.
|
||||
/// </summary>
|
||||
/// <param name="id">The chat ID to match</param>
|
||||
/// <param name="replyDepth">How many levels up the reply chain to check (default: 1)</param>
|
||||
public class RepliedChatIdAttribute(long id, int replyDepth = 1)
|
||||
: MessageFilterAttribute(new RepliedMessageChatIdFilter(id, replyDepth))
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Attribute for filtering messages where the replied-to message was sent in a chat of a specific type.
|
||||
/// </summary>
|
||||
/// <param name="type">The chat type to match</param>
|
||||
/// <param name="replyDepth">How many levels up the reply chain to check (default: 1)</param>
|
||||
public class RepliedChatTypeAttribute(ChatType type, int replyDepth = 1)
|
||||
: MessageFilterAttribute(new RepliedMessageChatTypeFilter(type, replyDepth))
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Attribute for filtering messages based on the chat title of the replied-to message.
|
||||
/// </summary>
|
||||
public class RepliedChatTitleAttribute : MessageFilterAttribute
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes the attribute to filter messages where the replied-to message is from a chat with a specific title and comparison method.
|
||||
/// </summary>
|
||||
/// <param name="title">The chat title to match</param>
|
||||
/// <param name="comparison">The string comparison method</param>
|
||||
/// <param name="replyDepth">How many levels up the reply chain to check (default: 1)</param>
|
||||
public RepliedChatTitleAttribute(string? title, StringComparison comparison, int replyDepth = 1)
|
||||
: base(new RepliedMessageChatTitleFilter(title, comparison, replyDepth)) { }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the attribute to filter messages where the replied-to message is from a chat with a specific title.
|
||||
/// </summary>
|
||||
/// <param name="title">The chat title to match</param>
|
||||
/// <param name="replyDepth">How many levels up the reply chain to check (default: 1)</param>
|
||||
public RepliedChatTitleAttribute(string? title, int replyDepth = 1)
|
||||
: base(new RepliedMessageChatTitleFilter(title, StringComparison.InvariantCulture, replyDepth)) { }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attribute for filtering messages based on the chat username of the replied-to message.
|
||||
/// </summary>
|
||||
public class RepliedChatUsernameAttribute : MessageFilterAttribute
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes the attribute to filter messages where the replied-to message is from a chat with a specific username and comparison method.
|
||||
/// </summary>
|
||||
/// <param name="userName">The chat username to match</param>
|
||||
/// <param name="comparison">The string comparison method</param>
|
||||
/// <param name="replyDepth">How many levels up the reply chain to check (default: 1)</param>
|
||||
public RepliedChatUsernameAttribute(string? userName, StringComparison comparison, int replyDepth = 1)
|
||||
: base(new RepliedMessageChatUsernameFilter(userName, comparison, replyDepth)) { }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the attribute to filter messages where the replied-to message is from a chat with a specific username.
|
||||
/// </summary>
|
||||
/// <param name="userName">The chat username to match</param>
|
||||
/// <param name="replyDepth">How many levels up the reply chain to check (default: 1)</param>
|
||||
public RepliedChatUsernameAttribute(string? userName, int replyDepth = 1)
|
||||
: base(new RepliedMessageChatUsernameFilter(userName, replyDepth)) { }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attribute for filtering messages based on the chat name of the replied-to message.
|
||||
/// </summary>
|
||||
public class RepliedChatNameAttribute : MessageFilterAttribute
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes the attribute to filter messages where the replied-to message is from a chat with specific first and last names.
|
||||
/// </summary>
|
||||
/// <param name="firstName">The first name to match</param>
|
||||
/// <param name="lastName">The last name to match (optional)</param>
|
||||
/// <param name="comparison">The string comparison method</param>
|
||||
/// <param name="replyDepth">How many levels up the reply chain to check (default: 1)</param>
|
||||
public RepliedChatNameAttribute(string? firstName, string? lastName, StringComparison comparison, int replyDepth = 1)
|
||||
: base(new RepliedMessageChatNameFilter(firstName, lastName, comparison, replyDepth)) { }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the attribute to filter messages where the replied-to message is from a chat with specific first and last names.
|
||||
/// </summary>
|
||||
/// <param name="firstName">The first name to match</param>
|
||||
/// <param name="lastName">The last name to match (optional)</param>
|
||||
/// <param name="replyDepth">How many levels up the reply chain to check (default: 1)</param>
|
||||
public RepliedChatNameAttribute(string? firstName, string? lastName, int replyDepth = 1)
|
||||
: base(new RepliedMessageChatNameFilter(firstName, lastName, StringComparison.InvariantCulture, replyDepth)) { }
|
||||
}
|
||||
}
|
||||
@@ -1,114 +0,0 @@
|
||||
using Telegram.Bot.Types.Enums;
|
||||
using Telegrator.Filters;
|
||||
|
||||
namespace Telegrator.Annotations
|
||||
{
|
||||
/// <summary>
|
||||
/// Attribute for filtering messages that are replies to other messages.
|
||||
/// </summary>
|
||||
/// <param name="replyDepth">How many levels up the reply chain to check (default: 1)</param>
|
||||
public class MessageRepliedAttribute(int replyDepth = 1)
|
||||
: MessageFilterAttribute(new MessageRepliedFilter(replyDepth))
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Attribute for filtering messages where the replied-to message contains dice throws with specific values.
|
||||
/// </summary>
|
||||
public class RepliedDiceThrowedAttribute : MessageFilterAttribute
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes the attribute to filter messages where the replied-to message contains a dice throw with a specific value.
|
||||
/// </summary>
|
||||
/// <param name="value">The dice value to match</param>
|
||||
/// <param name="replyDepth">How many levels up the reply chain to check (default: 1)</param>
|
||||
public RepliedDiceThrowedAttribute(int value, int replyDepth = 1)
|
||||
: base(new RepliedDiceThrowedFilter(value, replyDepth)) { }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the attribute to filter messages where the replied-to message contains a dice throw with a specific type and value.
|
||||
/// </summary>
|
||||
/// <param name="diceType">The type of dice</param>
|
||||
/// <param name="value">The dice value to match</param>
|
||||
/// <param name="replyDepth">How many levels up the reply chain to check (default: 1)</param>
|
||||
public RepliedDiceThrowedAttribute(DiceType diceType, int value, int replyDepth = 1)
|
||||
: base(new RepliedDiceThrowedFilter(diceType, value, replyDepth)) { }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attribute for filtering messages where the replied-to message was automatically forwarded.
|
||||
/// </summary>
|
||||
/// <param name="replyDepth">How many levels up the reply chain to check (default: 1)</param>
|
||||
public class RepliedIsAutomaticFormwardMessageAttribute(int replyDepth = 1)
|
||||
: MessageFilterAttribute(new RepliedIsAutomaticFormwardMessageFilter(replyDepth))
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Attribute for filtering messages where the replied-to message was sent while the user was offline.
|
||||
/// </summary>
|
||||
/// <param name="replyDepth">How many levels up the reply chain to check (default: 1)</param>
|
||||
public class RepliedIsFromOfflineMessageAttribute(int replyDepth = 1)
|
||||
: MessageFilterAttribute(new RepliedIsFromOfflineMessageFilter(replyDepth))
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Attribute for filtering messages where the replied-to message is a service message.
|
||||
/// </summary>
|
||||
/// <param name="replyDepth">How many levels up the reply chain to check (default: 1)</param>
|
||||
public class RepliedIsServiceMessageMessageAttribute(int replyDepth = 1)
|
||||
: MessageFilterAttribute(new RepliedIsServiceMessageMessageFilter(replyDepth))
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Attribute for filtering messages where the replied-to message is a topic message in forum chats.
|
||||
/// </summary>
|
||||
/// <param name="replyDepth">How many levels up the reply chain to check (default: 1)</param>
|
||||
public class RepliedIsTopicMessageMessageAttribut(int replyDepth = 1)
|
||||
: MessageFilterAttribute(new RepliedIsServiceMessageMessageFilter(replyDepth))
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Attribute for filtering messages based on entities in the replied-to message.
|
||||
/// </summary>
|
||||
public class RepliedMessageHasEntityAttribute : MessageFilterAttribute
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes the attribute to filter messages where the replied-to message has a specific entity type.
|
||||
/// </summary>
|
||||
/// <param name="type">The entity type to match</param>
|
||||
/// <param name="replyDepth">How many levels up the reply chain to check (default: 1)</param>
|
||||
public RepliedMessageHasEntityAttribute(MessageEntityType type, int replyDepth = 1)
|
||||
: base(new RepliedMessageHasEntityFilter(type, replyDepth)) { }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the attribute to filter messages where the replied-to message has a specific entity type at a specific position.
|
||||
/// </summary>
|
||||
/// <param name="type">The entity type to match</param>
|
||||
/// <param name="offset">The starting position of the entity</param>
|
||||
/// <param name="length">The length of the entity (optional)</param>
|
||||
/// <param name="replyDepth">How many levels up the reply chain to check (default: 1)</param>
|
||||
public RepliedMessageHasEntityAttribute(MessageEntityType type, int offset, int? length, int replyDepth = 1)
|
||||
: base(new RepliedMessageHasEntityFilter(type, offset, length, replyDepth)) { }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the attribute to filter messages where the replied-to message has a specific entity type with specific content.
|
||||
/// </summary>
|
||||
/// <param name="type">The entity type to match</param>
|
||||
/// <param name="content">The content that the entity should contain</param>
|
||||
/// <param name="stringComparison">The string comparison method</param>
|
||||
/// <param name="replyDepth">How many levels up the reply chain to check (default: 1)</param>
|
||||
public RepliedMessageHasEntityAttribute(MessageEntityType type, string content, StringComparison stringComparison = StringComparison.CurrentCulture, int replyDepth = 1)
|
||||
: base(new RepliedMessageHasEntityFilter(type, content, stringComparison, replyDepth)) { }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the attribute to filter messages where the replied-to message has a specific entity type at a specific position with specific content.
|
||||
/// </summary>
|
||||
/// <param name="type">The entity type to match</param>
|
||||
/// <param name="offset">The starting position of the entity</param>
|
||||
/// <param name="length">The length of the entity (optional)</param>
|
||||
/// <param name="content">The content that the entity should contain</param>
|
||||
/// <param name="stringComparison">The string comparison method</param>
|
||||
/// <param name="replyDepth">How many levels up the reply chain to check (default: 1)</param>
|
||||
public RepliedMessageHasEntityAttribute(MessageEntityType type, int offset, int? length, string content, StringComparison stringComparison = StringComparison.CurrentCulture, int replyDepth = 1)
|
||||
: base(new RepliedMessageHasEntityFilter(type, offset, length, content, stringComparison, replyDepth)) { }
|
||||
}
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
using Telegrator.Filters;
|
||||
|
||||
namespace Telegrator.Annotations
|
||||
{
|
||||
/// <summary>
|
||||
/// Attribute for filtering messages based on the username of the sender of the replied-to message.
|
||||
/// </summary>
|
||||
public class RepliedFromUsernameAttribute : MessageFilterAttribute
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes the attribute to filter messages where the replied-to message is from a specific username.
|
||||
/// </summary>
|
||||
/// <param name="username">The username to match</param>
|
||||
/// <param name="replyDepth">How many levels up the reply chain to check (default: 1)</param>
|
||||
public RepliedFromUsernameAttribute(string username, int replyDepth = 1)
|
||||
: base(new RepliedUsernameFilter(username, replyDepth)) { }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the attribute to filter messages where the replied-to message is from a specific username with custom comparison.
|
||||
/// </summary>
|
||||
/// <param name="username">The username to match</param>
|
||||
/// <param name="comparison">The string comparison method</param>
|
||||
/// <param name="replyDepth">How many levels up the reply chain to check (default: 1)</param>
|
||||
public RepliedFromUsernameAttribute(string username, StringComparison comparison, int replyDepth = 1)
|
||||
: base(new RepliedUsernameFilter(username, comparison, replyDepth)) { }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attribute for filtering messages based on the name of the sender of the replied-to message.
|
||||
/// </summary>
|
||||
public class RepliedFromUserAttribute : MessageFilterAttribute
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes the attribute to filter messages where the replied-to message is from a user with specific names.
|
||||
/// </summary>
|
||||
/// <param name="firstName">The first name to match</param>
|
||||
/// <param name="lastName">The last name to match (optional)</param>
|
||||
/// <param name="comparison">The string comparison method</param>
|
||||
/// <param name="replyDepth">How many levels up the reply chain to check (default: 1)</param>
|
||||
public RepliedFromUserAttribute(string firstName, string? lastName, StringComparison comparison, int replyDepth = 1)
|
||||
: base(new RepliedUserFilter(firstName, lastName, comparison, replyDepth)) { }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the attribute to filter messages where the replied-to message is from a user with specific names.
|
||||
/// </summary>
|
||||
/// <param name="firstName">The first name to match</param>
|
||||
/// <param name="lastName">The last name to match</param>
|
||||
/// <param name="replyDepth">How many levels up the reply chain to check (default: 1)</param>
|
||||
public RepliedFromUserAttribute(string firstName, string lastName, int replyDepth = 1)
|
||||
: base(new RepliedUserFilter(firstName, lastName, StringComparison.InvariantCulture, replyDepth)) { }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the attribute to filter messages where the replied-to message is from a user with a specific first name.
|
||||
/// </summary>
|
||||
/// <param name="firstName">The first name to match</param>
|
||||
/// <param name="replyDepth">How many levels up the reply chain to check (default: 1)</param>
|
||||
public RepliedFromUserAttribute(string firstName, int replyDepth = 1)
|
||||
: base(new RepliedUserFilter(firstName, null, StringComparison.InvariantCulture, replyDepth)) { }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the attribute to filter messages where the replied-to message is from a user with a specific first name and custom comparison.
|
||||
/// </summary>
|
||||
/// <param name="firstName">The first name to match</param>
|
||||
/// <param name="comparison">The string comparison method</param>
|
||||
/// <param name="replyDepth">How many levels up the reply chain to check (default: 1)</param>
|
||||
public RepliedFromUserAttribute(string firstName, StringComparison comparison, int replyDepth = 1)
|
||||
: base(new RepliedUserFilter(firstName, null, comparison, replyDepth)) { }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attribute for filtering messages based on the user ID of the sender of the replied-to message.
|
||||
/// </summary>
|
||||
/// <param name="userId">The user ID to match</param>
|
||||
/// <param name="replyDepth">How many levels up the reply chain to check (default: 1)</param>
|
||||
public class RepliedUserIdAttribute(long userId, int replyDepth = 1)
|
||||
: MessageFilterAttribute(new RepliedUserIdFilter(userId, replyDepth))
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Attribute for filtering messages where the replied-to message was sent by a bot.
|
||||
/// </summary>
|
||||
/// <param name="replyDepth">How many levels up the reply chain to check (default: 1)</param>
|
||||
public class ReplyFromBotAttribute(int replyDepth = 1)
|
||||
: MessageFilterAttribute(new ReplyFromBotFilter(replyDepth))
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Attribute for filtering messages where the replied-to message was sent by a premium user.
|
||||
/// </summary>
|
||||
/// <param name="replyDepth">How many levels up the reply chain to check (default: 1)</param>
|
||||
public class ReplyFromPremiumUserAttribute(int replyDepth = 1)
|
||||
: MessageFilterAttribute(new ReplyFromPremiumUserFilter(replyDepth))
|
||||
{ }
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
using Telegrator.Filters;
|
||||
|
||||
namespace Telegrator.Annotations
|
||||
{
|
||||
/// <summary>
|
||||
/// Attribute for filtering updates where the replied-to message's text starts with the specified content.
|
||||
/// </summary>
|
||||
/// <param name="content">The string that the replied message's text should start with</param>
|
||||
/// <param name="comparison">The string comparison type</param>
|
||||
/// <param name="replyDepth">How many levels up the reply chain to check (default: 1)</param>
|
||||
public class RepliedTextStartsWithAttribute(string content, StringComparison comparison = StringComparison.InvariantCulture, int replyDepth = 1)
|
||||
: MessageFilterAttribute(new RepliedTextStartsWithFilter(content, comparison, replyDepth))
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Attribute for filtering updates where the replied-to message's text ends with the specified content.
|
||||
/// </summary>
|
||||
/// <param name="content">The string that the replied message's text should end with</param>
|
||||
/// <param name="comparison">The string comparison type</param>
|
||||
/// <param name="replyDepth">How many levels up the reply chain to check (default: 1)</param>
|
||||
public class RepliedTextEndsWithAttribute(string content, StringComparison comparison = StringComparison.InvariantCulture, int replyDepth = 1)
|
||||
: MessageFilterAttribute(new RepliedTextEndsWithFilter(content, comparison, replyDepth))
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Attribute for filtering updates where the replied-to message's text contains the specified content.
|
||||
/// </summary>
|
||||
/// <param name="content">The string that the replied message's text should contain</param>
|
||||
/// <param name="comparison">The string comparison type</param>
|
||||
/// <param name="replyDepth">How many levels up the reply chain to check (default: 1)</param>
|
||||
public class RepliedTextContainsAttribute(string content, StringComparison comparison = StringComparison.InvariantCulture, int replyDepth = 1)
|
||||
: MessageFilterAttribute(new RepliedTextContainsFilter(content, comparison, replyDepth))
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Attribute for filtering updates where the replied-to message's text equals the specified content.
|
||||
/// </summary>
|
||||
/// <param name="content">The string that the replied message's text should equal</param>
|
||||
/// <param name="comparison">The string comparison type</param>
|
||||
/// <param name="replyDepth">How many levels up the reply chain to check (default: 1)</param>
|
||||
public class RepliedTextEqualsAttribute(string content, StringComparison comparison = StringComparison.InvariantCulture, int replyDepth = 1)
|
||||
: MessageFilterAttribute(new RepliedTextEqualsFilter(content, comparison, replyDepth))
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Attribute for filtering updates where the replied-to message contains any non-empty text.
|
||||
/// </summary>
|
||||
/// <param name="replyDepth">How many levels up the reply chain to check (default: 1)</param>
|
||||
public class RepliedHasTextAttribute(int replyDepth = 1)
|
||||
: MessageFilterAttribute(new RepliedTextNotNullOrEmptyFilter(replyDepth))
|
||||
{ }
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
using Telegrator.Filters;
|
||||
|
||||
namespace Telegrator.Annotations
|
||||
{
|
||||
/// <summary>
|
||||
/// Attribute for filtering messages with reply to messages of this bot.
|
||||
/// </summary>
|
||||
public class RepliedToMeAttribute()
|
||||
: MessageFilterAttribute(new RepliedToMeFilter())
|
||||
{ }
|
||||
}
|
||||
@@ -7,7 +7,7 @@ namespace Telegrator.Filters
|
||||
/// Filter that checks if a message contains a mention of the bot or a specific user.
|
||||
/// Requires a <see cref="MessageHasEntityFilter"/> to be applied first to identify mention entities.
|
||||
/// </summary>
|
||||
public class MentionedFilter : Filter<Message>
|
||||
public class MentionedFilter : MessageFilterBase
|
||||
{
|
||||
/// <summary>
|
||||
/// The username to check for in the mention (null means check for bot's username).
|
||||
@@ -39,14 +39,14 @@ namespace Telegrator.Filters
|
||||
/// <param name="context">The filter execution context containing the message and completed filters.</param>
|
||||
/// <returns>True if the message contains the specified mention; otherwise, false.</returns>
|
||||
/// <exception cref="ArgumentNullException">Thrown when the bot username is null and no specific mention is provided.</exception>
|
||||
public override bool CanPass(FilterExecutionContext<Message> context)
|
||||
protected override bool CanPassNext(FilterExecutionContext<Message> context)
|
||||
{
|
||||
if (context.Input.Text == null)
|
||||
if (Target.Text == null)
|
||||
return false;
|
||||
|
||||
string userName = Mention ?? context.BotInfo.User.Username ?? throw new ArgumentNullException(nameof(context), "MentionedFilter requires BotInfo to be initialized");
|
||||
MessageHasEntityFilter entityFilter = context.CompletedFilters.Get<MessageHasEntityFilter>(0);
|
||||
return entityFilter.FoundEntities.Any(ent => context.Input.Text.Substring(ent.Offset + 1, ent.Length - 1) == userName);
|
||||
return entityFilter.FoundEntities.Any(ent => Target.Text.Substring(ent.Offset + 1, ent.Length - 1) == userName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace Telegrator.Filters
|
||||
/// <summary>
|
||||
/// Base class for filters that operate on the chat of the message being processed.
|
||||
/// </summary>
|
||||
public abstract class MessageChatFilter : Filter<Message>
|
||||
public abstract class MessageChatFilter : MessageFilterBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the chat of the message being processed.
|
||||
@@ -15,18 +15,18 @@ namespace Telegrator.Filters
|
||||
public Chat Chat { get; private set; } = null!;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override bool CanPass(FilterExecutionContext<Message> context)
|
||||
protected override bool CanPassNext(FilterExecutionContext<Message> context)
|
||||
{
|
||||
Chat = context.Input.Chat;
|
||||
Chat = Target.Chat;
|
||||
return CanPassNext(context.CreateChild(Chat));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the filter passes for the given chat context.
|
||||
/// </summary>
|
||||
/// <param name="_">The filter execution context for the chat.</param>
|
||||
/// <param name="context">The filter execution context for the chat.</param>
|
||||
/// <returns>True if the filter passes; otherwise, false.</returns>
|
||||
protected abstract bool CanPassNext(FilterExecutionContext<Chat> _);
|
||||
protected abstract bool CanPassNext(FilterExecutionContext<Chat> context);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,15 +1,40 @@
|
||||
using System.Text.RegularExpressions;
|
||||
using Telegram.Bot.Types;
|
||||
using Telegram.Bot.Types.Enums;
|
||||
using Telegrator;
|
||||
using Telegrator.Filters.Components;
|
||||
|
||||
namespace Telegrator.Filters
|
||||
{
|
||||
/// <summary>
|
||||
/// Base abstract class for all filter of <see cref="Message"/> updates
|
||||
/// </summary>
|
||||
public abstract class MessageFilterBase : Filter<Message>
|
||||
{
|
||||
/// <summary>
|
||||
/// Target message for filterring
|
||||
/// </summary>
|
||||
protected Message Target { get; private set; } = null!;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override bool CanPass(FilterExecutionContext<Message> context)
|
||||
{
|
||||
MessageRepliedFilter? repliedFilter = context.CompletedFilters.Get<MessageRepliedFilter>().SingleOrDefault();
|
||||
Target = repliedFilter?.Reply ?? context.Input;
|
||||
return CanPassNext(context);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the filter can pass for the given context.
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
/// <returns></returns>
|
||||
protected abstract bool CanPassNext(FilterExecutionContext<Message> context);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filters messages by their <see cref="MessageType"/>.
|
||||
/// </summary>
|
||||
public class MessageTypeFilter : Filter<Message>
|
||||
public class MessageTypeFilter : MessageFilterBase
|
||||
{
|
||||
private readonly MessageType type;
|
||||
|
||||
@@ -20,54 +45,54 @@ namespace Telegrator.Filters
|
||||
public MessageTypeFilter(MessageType type) => this.type = type;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override bool CanPass(FilterExecutionContext<Message> context)
|
||||
=> context.Input.Type == type;
|
||||
protected override bool CanPassNext(FilterExecutionContext<Message> context)
|
||||
=> Target.Type == type;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filters messages that are automatic forwards.
|
||||
/// </summary>
|
||||
public class IsAutomaticFormwardMessageFilter : Filter<Message>
|
||||
public class IsAutomaticFormwardMessageFilter : MessageFilterBase
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public override bool CanPass(FilterExecutionContext<Message> context)
|
||||
=> context.Input.IsAutomaticForward;
|
||||
protected override bool CanPassNext(FilterExecutionContext<Message> context)
|
||||
=> Target.IsAutomaticForward;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filters messages that are sent from offline.
|
||||
/// </summary>
|
||||
public class IsFromOfflineMessageFilter : Filter<Message>
|
||||
public class IsFromOfflineMessageFilter : MessageFilterBase
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public override bool CanPass(FilterExecutionContext<Message> context)
|
||||
=> context.Input.IsFromOffline;
|
||||
protected override bool CanPassNext(FilterExecutionContext<Message> context)
|
||||
=> Target.IsFromOffline;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filters service messages (e.g., chat events).
|
||||
/// </summary>
|
||||
public class IsServiceMessageMessageFilter : Filter<Message>
|
||||
public class IsServiceMessageMessageFilter : MessageFilterBase
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public override bool CanPass(FilterExecutionContext<Message> context)
|
||||
=> context.Input.IsServiceMessage;
|
||||
protected override bool CanPassNext(FilterExecutionContext<Message> context)
|
||||
=> Target.IsServiceMessage;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filters messages that are topic messages.
|
||||
/// </summary>
|
||||
public class IsTopicMessageMessageFilter : Filter<Message>
|
||||
public class IsTopicMessageMessageFilter : MessageFilterBase
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public override bool CanPass(FilterExecutionContext<Message> context)
|
||||
=> context.Input.IsTopicMessage;
|
||||
protected override bool CanPassNext(FilterExecutionContext<Message> context)
|
||||
=> Target.IsTopicMessage;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filters messages by dice throw value and optionally by dice type.
|
||||
/// </summary>
|
||||
public class DiceThrowedFilter : Filter<Message>
|
||||
public class DiceThrowedFilter : MessageFilterBase
|
||||
{
|
||||
private readonly DiceType? Dice;
|
||||
private readonly int Value;
|
||||
@@ -89,15 +114,15 @@ namespace Telegrator.Filters
|
||||
public DiceThrowedFilter(DiceType diceType, int value) : this(value) => Dice = diceType;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override bool CanPass(FilterExecutionContext<Message> context)
|
||||
protected override bool CanPassNext(FilterExecutionContext<Message> context)
|
||||
{
|
||||
if (context.Input.Dice == null)
|
||||
if (Target.Dice == null)
|
||||
return false;
|
||||
|
||||
if (Dice != null && context.Input.Dice.Emoji != GetEmojyForDiceType(Dice))
|
||||
if (Dice != null && Target.Dice.Emoji != GetEmojyForDiceType(Dice))
|
||||
return false;
|
||||
|
||||
return context.Input.Dice.Value == Value;
|
||||
return Target.Dice.Value == Value;
|
||||
}
|
||||
|
||||
private static string? GetEmojyForDiceType(DiceType? diceType) => diceType switch
|
||||
@@ -136,7 +161,7 @@ namespace Telegrator.Filters
|
||||
/// <summary>
|
||||
/// Filters messages that contain a specific entity type, content, offset, or length.
|
||||
/// </summary>
|
||||
public class MessageHasEntityFilter : Filter<Message>
|
||||
public class MessageHasEntityFilter : MessageFilterBase
|
||||
{
|
||||
private readonly StringComparison _stringComparison = StringComparison.CurrentCulture;
|
||||
private readonly MessageEntityType? EntityType;
|
||||
@@ -202,12 +227,12 @@ namespace Telegrator.Filters
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override bool CanPass(FilterExecutionContext<Message> context)
|
||||
protected override bool CanPassNext(FilterExecutionContext<Message> context)
|
||||
{
|
||||
if (context.Input is not { Entities.Length: > 0 })
|
||||
return false;
|
||||
|
||||
FoundEntities = context.Input.Entities.Where(entity => FilterEntity(context.Input.Text, entity)).ToArray();
|
||||
FoundEntities = Target.Entities.Where(entity => FilterEntity(Target.Text, entity)).ToArray();
|
||||
return FoundEntities.Length != 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
using Telegram.Bot.Types;
|
||||
using Telegrator.Filters.Components;
|
||||
|
||||
namespace Telegrator.Filters
|
||||
{
|
||||
/// <summary>
|
||||
/// Abstract base class for filters that operate on replied messages.
|
||||
/// Provides functionality to traverse reply chains and access replied message content.
|
||||
/// </summary>
|
||||
/// <param name="replyDepth">The depth of reply chain to traverse (default: 1).</param>
|
||||
public class MessageRepliedFilter(int replyDepth = 1) : Filter<Message>
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the replied message at the specified depth in the reply chain.
|
||||
/// </summary>
|
||||
public Message Reply { get; private set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the depth of reply chain traversal.
|
||||
/// </summary>
|
||||
public int ReplyDepth { get; private set; } = replyDepth;
|
||||
|
||||
/// <summary>
|
||||
/// Determines if the message can pass through the filter by first validating
|
||||
/// the reply chain and then applying specific filter logic.
|
||||
/// </summary>
|
||||
/// <param name="context">The filter execution context containing the message.</param>
|
||||
/// <returns>True if the message passes both reply validation and specific filter criteria; otherwise, false.</returns>
|
||||
public override bool CanPass(FilterExecutionContext<Message> context)
|
||||
{
|
||||
Message reply = context.Input;
|
||||
for (int i = ReplyDepth; i > 0; i--)
|
||||
{
|
||||
if (reply.ReplyToMessage is not { Id: > 0 } replyMessage)
|
||||
return false;
|
||||
|
||||
reply = replyMessage;
|
||||
}
|
||||
|
||||
Reply = reply;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filter that checks if the replied message was sent by the bot itself.
|
||||
/// <para>( ! ): REQUIRES <see cref="MessageRepliedFilter"/> before</para>
|
||||
/// </summary>
|
||||
public class MeRepliedFilter : Filter<Message>
|
||||
{
|
||||
/// <summary>
|
||||
/// Checks if the replied message was sent by the bot.
|
||||
/// </summary>
|
||||
/// <param name="context">The filter execution context containing bot information.</param>
|
||||
/// <returns>True if the replied message was sent by the bot; otherwise, false.</returns>
|
||||
public override bool CanPass(FilterExecutionContext<Message> context)
|
||||
{
|
||||
MessageRepliedFilter repliedFilter = context.CompletedFilters.Get<MessageRepliedFilter>(0);
|
||||
return context.BotInfo.User == repliedFilter.Reply.From;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@ namespace Telegrator.Filters
|
||||
/// Abstract base class for filters that operate on message senders.
|
||||
/// Provides functionality to access and validate the user who sent the message.
|
||||
/// </summary>
|
||||
public abstract class MessageSenderFilter : Filter<Message>
|
||||
public abstract class MessageSenderFilter : MessageFilterBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the user who sent the message.
|
||||
@@ -22,20 +22,15 @@ namespace Telegrator.Filters
|
||||
/// <returns>True if the message has a valid sender; otherwise, false.</returns>
|
||||
public override bool CanPass(FilterExecutionContext<Message> context)
|
||||
{
|
||||
User = context.Input.From!;
|
||||
if (!base.CanPass(context))
|
||||
return false;
|
||||
|
||||
User = Target.From!;
|
||||
if (User is not { Id: > 0 })
|
||||
return false;
|
||||
|
||||
return CanPassNext(context);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Abstract method that must be implemented by derived classes to perform
|
||||
/// specific filtering logic on the message sender.
|
||||
/// </summary>
|
||||
/// <param name="context">The filter execution context.</param>
|
||||
/// <returns>True if the sender passes the specific filter criteria; otherwise, false.</returns>
|
||||
protected abstract bool CanPassNext(FilterExecutionContext<Message> context);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace Telegrator.Filters
|
||||
/// Abstract base class for filters that operate on message text content.
|
||||
/// Provides common functionality for extracting and validating message text.
|
||||
/// </summary>
|
||||
public abstract class MessageTextFilter : Filter<Message>
|
||||
public abstract class MessageTextFilter : MessageFilterBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the current message being processed by the filter.
|
||||
@@ -29,6 +29,9 @@ namespace Telegrator.Filters
|
||||
/// <returns>True if the message is valid and can be processed further; otherwise, false.</returns>
|
||||
public override bool CanPass(FilterExecutionContext<Message> context)
|
||||
{
|
||||
if (!base.CanPass(context))
|
||||
return false;
|
||||
|
||||
Message = context.Update.Message!;
|
||||
if (Message is not { Id: > 0 })
|
||||
return false;
|
||||
@@ -36,14 +39,6 @@ namespace Telegrator.Filters
|
||||
Text = Message.Text ?? string.Empty;
|
||||
return CanPassNext(context);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Abstract method that must be implemented by derived classes to perform
|
||||
/// specific text-based filtering logic.
|
||||
/// </summary>
|
||||
/// <param name="_">The filter execution context (unused in this context).</param>
|
||||
/// <returns>True if the text content passes the filter criteria; otherwise, false.</returns>
|
||||
protected abstract bool CanPassNext(FilterExecutionContext<Message> _);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
using Telegram.Bot.Types;
|
||||
using Telegrator.Filters.Components;
|
||||
|
||||
namespace Telegrator.Filters
|
||||
{
|
||||
/// <summary>
|
||||
/// Filter that checks if a replied message contains a mention of the bot or a specific user.
|
||||
/// Requires a <see cref="MessageHasEntityFilter"/> to be applied first to identify mention entities.
|
||||
/// </summary>
|
||||
public class RepliedMentionedFilter : RepliedMessageFilter
|
||||
{
|
||||
/// <summary>
|
||||
/// The username to check for in the mention (null means check for bot's username).
|
||||
/// </summary>
|
||||
private readonly string? Mention;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RepliedMentionedFilter"/> class that checks for bot mentions.
|
||||
/// </summary>
|
||||
/// <param name="replyDepth">The depth of reply chain to traverse (default: 1).</param>
|
||||
public RepliedMentionedFilter(int replyDepth = 1) : base(replyDepth)
|
||||
{
|
||||
Mention = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RepliedMentionedFilter"/> class that checks for specific user mentions.
|
||||
/// </summary>
|
||||
/// <param name="mention">The username to check for in the mention.</param>
|
||||
/// <param name="replyDepth">The depth of reply chain to traverse (default: 1).</param>
|
||||
public RepliedMentionedFilter(string mention, int replyDepth = 1) : base(replyDepth)
|
||||
{
|
||||
Mention = mention;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the replied message contains a mention of the specified user or bot.
|
||||
/// This filter requires a <see cref="MessageHasEntityFilter"/> to be applied first
|
||||
/// to identify mention entities in the replied message.
|
||||
/// </summary>
|
||||
/// <param name="context">The filter execution context containing the message and completed filters.</param>
|
||||
/// <returns>True if the replied message contains the specified mention; otherwise, false.</returns>
|
||||
/// <exception cref="ArgumentNullException">Thrown when the bot username is null and no specific mention is provided.</exception>
|
||||
protected override bool CanPassNext(FilterExecutionContext<Message> context)
|
||||
{
|
||||
if (Reply.Text == null)
|
||||
return false;
|
||||
|
||||
string userName = Mention ?? context.BotInfo.User.Username ?? throw new ArgumentNullException(nameof(context), "RepliedMentionedFilter requires BotInfo to be initialized");
|
||||
MessageEntity entity = context.CompletedFilters.Get<MessageHasEntityFilter>(0).FoundEntities.ElementAt(0);
|
||||
|
||||
string mention = Reply.Text.Substring(entity.Offset + 1, entity.Length - 1);
|
||||
return userName == mention;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,211 +0,0 @@
|
||||
using Telegram.Bot.Types;
|
||||
using Telegram.Bot.Types.Enums;
|
||||
using Telegrator.Filters.Components;
|
||||
|
||||
namespace Telegrator.Filters
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for filters that operate on the chat of a replied message (the message being replied to).
|
||||
/// The replyDepth parameter determines how many levels up the reply chain to search for the target message.
|
||||
/// </summary>
|
||||
public abstract class RepliedMessageChatFilter : RepliedMessageFilter
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the chat of the replied message (the message being replied to at the specified depth).
|
||||
/// </summary>
|
||||
public Chat Chat { get; private set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RepliedMessageChatFilter"/> class.
|
||||
/// </summary>
|
||||
/// <param name="replyDepth">The reply depth to search up the reply chain for the target message.</param>
|
||||
protected RepliedMessageChatFilter(int replyDepth = 1) : base(replyDepth) { }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override bool CanPass(FilterExecutionContext<Message> context)
|
||||
{
|
||||
if (!CanPassReply(context))
|
||||
return false;
|
||||
|
||||
Chat = Reply.Chat;
|
||||
return CanPassNext(context);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filters replied messages (the message being replied to at the specified depth) whose chat is a forum.
|
||||
/// </summary>
|
||||
public class RepliedMessageChatIsForumFilter : RepliedMessageChatFilter
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RepliedMessageChatIsForumFilter"/> class.
|
||||
/// </summary>
|
||||
/// <param name="replyDepth">The reply depth to search up the reply chain for the target message.</param>
|
||||
public RepliedMessageChatIsForumFilter(int replyDepth = 1)
|
||||
: base(replyDepth) { }
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override bool CanPassNext(FilterExecutionContext<Message> _)
|
||||
=> Chat.IsForum;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filters replied messages (the message being replied to at the specified depth) whose chat ID matches the specified value.
|
||||
/// </summary>
|
||||
public class RepliedMessageChatIdFilter : RepliedMessageChatFilter
|
||||
{
|
||||
private readonly long Id;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RepliedMessageChatIdFilter"/> class.
|
||||
/// </summary>
|
||||
/// <param name="id">The chat ID to match.</param>
|
||||
/// <param name="replyDepth">The reply depth to search up the reply chain for the target message.</param>
|
||||
public RepliedMessageChatIdFilter(long id, int replyDepth = 1) : base(replyDepth) => Id = id;
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override bool CanPassNext(FilterExecutionContext<Message> _)
|
||||
=> Chat.Id == Id;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filters replied messages (the message being replied to at the specified depth) whose chat type matches the specified value.
|
||||
/// </summary>
|
||||
public class RepliedMessageChatTypeFilter : RepliedMessageChatFilter
|
||||
{
|
||||
private readonly ChatType Type;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RepliedMessageChatTypeFilter"/> class.
|
||||
/// </summary>
|
||||
/// <param name="type">The chat type to match.</param>
|
||||
/// <param name="replyDepth">The reply depth to search up the reply chain for the target message.</param>
|
||||
public RepliedMessageChatTypeFilter(ChatType type, int replyDepth = 1) : base(replyDepth) => Type = type;
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override bool CanPassNext(FilterExecutionContext<Message> _)
|
||||
=> Chat.Type == Type;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filters replied messages (the message being replied to at the specified depth) whose chat title matches the specified value.
|
||||
/// </summary>
|
||||
public class RepliedMessageChatTitleFilter : RepliedMessageChatFilter
|
||||
{
|
||||
private readonly string? Title;
|
||||
private readonly StringComparison Comparison = StringComparison.InvariantCulture;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RepliedMessageChatTitleFilter"/> class.
|
||||
/// </summary>
|
||||
/// <param name="title">The chat title to match.</param>
|
||||
/// <param name="replyDepth">The reply depth to search up the reply chain for the target message.</param>
|
||||
public RepliedMessageChatTitleFilter(string? title, int replyDepth = 1) : base(replyDepth) => Title = title;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RepliedMessageChatTitleFilter"/> class with a specific string comparison.
|
||||
/// </summary>
|
||||
/// <param name="title">The chat title to match.</param>
|
||||
/// <param name="comparison">The string comparison to use.</param>
|
||||
/// <param name="replyDepth">The reply depth to search up the reply chain for the target message.</param>
|
||||
public RepliedMessageChatTitleFilter(string? title, StringComparison comparison, int replyDepth = 1)
|
||||
: this(title, replyDepth) => Comparison = comparison;
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override bool CanPassNext(FilterExecutionContext<Message> _)
|
||||
{
|
||||
if (Chat.Title == null)
|
||||
return false;
|
||||
return Chat.Title.Equals(Title, Comparison);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filters replied messages (the message being replied to at the specified depth) whose chat username matches the specified value.
|
||||
/// </summary>
|
||||
public class RepliedMessageChatUsernameFilter : RepliedMessageChatFilter
|
||||
{
|
||||
private readonly string? UserName;
|
||||
private readonly StringComparison Comparison = StringComparison.InvariantCulture;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RepliedMessageChatUsernameFilter"/> class.
|
||||
/// </summary>
|
||||
/// <param name="userName">The chat username to match.</param>
|
||||
/// <param name="replyDepth">The reply depth to search up the reply chain for the target message.</param>
|
||||
public RepliedMessageChatUsernameFilter(string? userName, int replyDepth = 1) : base(replyDepth) => UserName = userName;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RepliedMessageChatUsernameFilter"/> class with a specific string comparison.
|
||||
/// </summary>
|
||||
/// <param name="userName">The chat username to match.</param>
|
||||
/// <param name="comparison">The string comparison to use.</param>
|
||||
/// <param name="replyDepth">The reply depth to search up the reply chain for the target message.</param>
|
||||
public RepliedMessageChatUsernameFilter(string? userName, StringComparison comparison, int replyDepth = 1)
|
||||
: this(userName, replyDepth) => Comparison = comparison;
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override bool CanPassNext(FilterExecutionContext<Message> _)
|
||||
{
|
||||
if (Chat.Username == null)
|
||||
return false;
|
||||
return Chat.Username.Equals(UserName, Comparison);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filters replied messages (the message being replied to at the specified depth) whose chat first and/or last name matches the specified values.
|
||||
/// </summary>
|
||||
public class RepliedMessageChatNameFilter : RepliedMessageChatFilter
|
||||
{
|
||||
private readonly string? FirstName;
|
||||
private readonly string? LastName;
|
||||
private readonly StringComparison Comparison = StringComparison.InvariantCulture;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RepliedMessageChatNameFilter"/> class.
|
||||
/// </summary>
|
||||
/// <param name="firstName">The chat first name to match.</param>
|
||||
/// <param name="lastName">The chat last name to match.</param>
|
||||
/// <param name="replyDepth">The reply depth to search up the reply chain for the target message.</param>
|
||||
public RepliedMessageChatNameFilter(string? firstName, string? lastName, int replyDepth = 1) : base(replyDepth)
|
||||
{
|
||||
FirstName = firstName;
|
||||
LastName = lastName;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RepliedMessageChatNameFilter"/> class with a specific string comparison.
|
||||
/// </summary>
|
||||
/// <param name="firstName">The chat first name to match.</param>
|
||||
/// <param name="lastName">The chat last name to match.</param>
|
||||
/// <param name="comparison">The string comparison to use.</param>
|
||||
/// <param name="replyDepth">The reply depth to search up the reply chain for the target message.</param>
|
||||
public RepliedMessageChatNameFilter(string? firstName, string? lastName, StringComparison comparison, int replyDepth = 1)
|
||||
: this(firstName, lastName, replyDepth) => Comparison = comparison;
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override bool CanPassNext(FilterExecutionContext<Message> _)
|
||||
{
|
||||
if (LastName != null)
|
||||
{
|
||||
if (Chat.LastName == null)
|
||||
return false;
|
||||
|
||||
if (Chat.LastName.Equals(LastName, Comparison))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (FirstName != null)
|
||||
{
|
||||
if (Chat.FirstName == null)
|
||||
return false;
|
||||
|
||||
if (Chat.FirstName.Equals(FirstName, Comparison))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,383 +0,0 @@
|
||||
using Telegram.Bot.Types;
|
||||
using Telegram.Bot.Types.Enums;
|
||||
using Telegrator;
|
||||
using Telegrator.Filters.Components;
|
||||
|
||||
namespace Telegrator.Filters
|
||||
{
|
||||
/// <summary>
|
||||
/// Abstract base class for filters that operate on replied messages.
|
||||
/// Provides functionality to traverse reply chains and access replied message content.
|
||||
/// </summary>
|
||||
/// <param name="replyDepth">The depth of reply chain to traverse (default: 1).</param>
|
||||
public abstract class RepliedMessageFilter(int replyDepth = 1) : Filter<Message>
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the replied message at the specified depth in the reply chain.
|
||||
/// </summary>
|
||||
public Message Reply { get; private set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the depth of reply chain traversal.
|
||||
/// </summary>
|
||||
public int ReplyDepth { get; private set; } = replyDepth;
|
||||
|
||||
/// <summary>
|
||||
/// Validates that the message has a valid reply chain at the specified depth.
|
||||
/// </summary>
|
||||
/// <param name="context">The filter execution context containing the message.</param>
|
||||
/// <returns>True if the reply chain is valid at the specified depth; otherwise, false.</returns>
|
||||
protected bool CanPassReply(FilterExecutionContext<Message> context)
|
||||
{
|
||||
Message reply = context.Input;
|
||||
for (int i = ReplyDepth; i > 0; i--)
|
||||
{
|
||||
if (reply.ReplyToMessage is not { Id: > 0 } replyMessage)
|
||||
return false;
|
||||
|
||||
reply = replyMessage;
|
||||
}
|
||||
|
||||
Reply = reply;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if the message can pass through the filter by first validating
|
||||
/// the reply chain and then applying specific filter logic.
|
||||
/// </summary>
|
||||
/// <param name="context">The filter execution context containing the message.</param>
|
||||
/// <returns>True if the message passes both reply validation and specific filter criteria; otherwise, false.</returns>
|
||||
public override bool CanPass(FilterExecutionContext<Message> context)
|
||||
{
|
||||
if (!CanPassReply(context))
|
||||
return false;
|
||||
|
||||
return CanPassNext(context);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Abstract method that must be implemented by derived classes to perform
|
||||
/// specific filtering logic on the replied message.
|
||||
/// </summary>
|
||||
/// <param name="context">The filter execution context.</param>
|
||||
/// <returns>True if the replied message passes the specific filter criteria; otherwise, false.</returns>
|
||||
protected abstract bool CanPassNext(FilterExecutionContext<Message> context);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filter that checks if a message is a reply to another message at the specified depth.
|
||||
/// </summary>
|
||||
/// <param name="replyDepth">The depth of reply chain to traverse (default: 1).</param>
|
||||
public class MessageRepliedFilter(int replyDepth = 1) : RepliedMessageFilter(replyDepth)
|
||||
{
|
||||
/// <summary>
|
||||
/// Always returns true if the reply chain is valid at the specified depth.
|
||||
/// </summary>
|
||||
/// <param name="context">The filter execution context (unused).</param>
|
||||
/// <returns>True if the reply chain is valid; otherwise, false.</returns>
|
||||
protected override bool CanPassNext(FilterExecutionContext<Message> context)
|
||||
=> true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filter that checks if the replied message was sent by the bot itself.
|
||||
/// </summary>
|
||||
/// <param name="replyDepth">The depth of reply chain to traverse (default: 1).</param>
|
||||
public class MeRepliedFilter(int replyDepth = 1) : RepliedMessageFilter(replyDepth)
|
||||
{
|
||||
/// <summary>
|
||||
/// Checks if the replied message was sent by the bot.
|
||||
/// </summary>
|
||||
/// <param name="context">The filter execution context containing bot information.</param>
|
||||
/// <returns>True if the replied message was sent by the bot; otherwise, false.</returns>
|
||||
protected override bool CanPassNext(FilterExecutionContext<Message> context)
|
||||
=> context.BotInfo.User == Reply.From;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filter that checks if the replied message has non-empty text content.
|
||||
/// </summary>
|
||||
/// <param name="replyDepth">The depth of reply chain to traverse (default: 1).</param>
|
||||
public class RepliedTextNotNullOrEmptyFilter(int replyDepth = 1) : RepliedMessageFilter(replyDepth)
|
||||
{
|
||||
/// <summary>
|
||||
/// Checks if the replied message text is not null or empty.
|
||||
/// </summary>
|
||||
/// <param name="_">The filter execution context (unused).</param>
|
||||
/// <returns>True if the replied message has non-empty text; otherwise, false.</returns>
|
||||
protected override bool CanPassNext(FilterExecutionContext<Message> _)
|
||||
=> !string.IsNullOrEmpty(Reply.Text);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filter that checks if the replied message is of a specific type.
|
||||
/// </summary>
|
||||
/// <param name="type">The message type to check for.</param>
|
||||
/// <param name="replyDepth">The depth of reply chain to traverse (default: 1).</param>
|
||||
public class RepliedMessageTypeFilter(MessageType type, int replyDepth = 1) : RepliedMessageFilter(replyDepth)
|
||||
{
|
||||
/// <summary>
|
||||
/// Checks if the replied message is of the specified type.
|
||||
/// </summary>
|
||||
/// <param name="_">The filter execution context (unused).</param>
|
||||
/// <returns>True if the replied message is of the specified type; otherwise, false.</returns>
|
||||
protected override bool CanPassNext(FilterExecutionContext<Message> _)
|
||||
=> Reply.Type == type;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filter that checks if the replied message is an automatic forward.
|
||||
/// </summary>
|
||||
/// <param name="replyDepth">The depth of reply chain to traverse (default: 1).</param>
|
||||
public class RepliedIsAutomaticFormwardMessageFilter(int replyDepth = 1) : RepliedMessageFilter(replyDepth)
|
||||
{
|
||||
/// <summary>
|
||||
/// Checks if the replied message is an automatic forward.
|
||||
/// </summary>
|
||||
/// <param name="_">The filter execution context (unused).</param>
|
||||
/// <returns>True if the replied message is an automatic forward; otherwise, false.</returns>
|
||||
protected override bool CanPassNext(FilterExecutionContext<Message> _)
|
||||
=> Reply.IsAutomaticForward;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filter that checks if the replied message is from an offline user.
|
||||
/// </summary>
|
||||
/// <param name="replyDepth">The depth of reply chain to traverse (default: 1).</param>
|
||||
public class RepliedIsFromOfflineMessageFilter(int replyDepth = 1) : RepliedMessageFilter(replyDepth)
|
||||
{
|
||||
/// <summary>
|
||||
/// Checks if the replied message is from an offline user.
|
||||
/// </summary>
|
||||
/// <param name="_">The filter execution context (unused).</param>
|
||||
/// <returns>True if the replied message is from an offline user; otherwise, false.</returns>
|
||||
protected override bool CanPassNext(FilterExecutionContext<Message> _)
|
||||
=> Reply.IsFromOffline;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filter that checks if the replied message is a service message.
|
||||
/// </summary>
|
||||
/// <param name="replyDepth">The depth of reply chain to traverse (default: 1).</param>
|
||||
public class RepliedIsServiceMessageMessageFilter(int replyDepth = 1) : RepliedMessageFilter(replyDepth)
|
||||
{
|
||||
/// <summary>
|
||||
/// Checks if the replied message is a service message.
|
||||
/// </summary>
|
||||
/// <param name="_">The filter execution context (unused).</param>
|
||||
/// <returns>True if the replied message is a service message; otherwise, false.</returns>
|
||||
protected override bool CanPassNext(FilterExecutionContext<Message> _)
|
||||
=> Reply.IsServiceMessage;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filter that checks if the replied message is a topic message.
|
||||
/// </summary>
|
||||
/// <param name="replyDepth">The depth of reply chain to traverse (default: 1).</param>
|
||||
public class RepliedIsTopicMessageMessageFilter(int replyDepth = 1) : RepliedMessageFilter(replyDepth)
|
||||
{
|
||||
/// <summary>
|
||||
/// Checks if the replied message is a topic message.
|
||||
/// </summary>
|
||||
/// <param name="_">The filter execution context (unused).</param>
|
||||
/// <returns>True if the replied message is a topic message; otherwise, false.</returns>
|
||||
protected override bool CanPassNext(FilterExecutionContext<Message> _)
|
||||
=> Reply.IsTopicMessage;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filter that checks if the replied message contains a dice with a specific value.
|
||||
/// </summary>
|
||||
/// <param name="value">The dice value to check for.</param>
|
||||
/// <param name="replyDepth">The depth of reply chain to traverse (default: 1).</param>
|
||||
public class RepliedDiceThrowedFilter(int value, int replyDepth = 1) : RepliedMessageFilter(replyDepth)
|
||||
{
|
||||
/// <summary>
|
||||
/// The dice type to check for (optional).
|
||||
/// </summary>
|
||||
private readonly DiceType? Dice = null;
|
||||
|
||||
/// <summary>
|
||||
/// The dice value to check for.
|
||||
/// </summary>
|
||||
private readonly int Value = value;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RepliedDiceThrowedFilter"/> class with a specific dice type and value.
|
||||
/// </summary>
|
||||
/// <param name="diceType">The dice type to check for.</param>
|
||||
/// <param name="value">The dice value to check for.</param>
|
||||
/// <param name="replyDepth">The depth of reply chain to traverse (default: 1).</param>
|
||||
public RepliedDiceThrowedFilter(DiceType diceType, int value, int replyDepth = 1)
|
||||
: this(value, replyDepth) => Dice = diceType;
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the replied message contains a dice with the specified value and optionally the specified type.
|
||||
/// </summary>
|
||||
/// <param name="context">The filter execution context containing the message.</param>
|
||||
/// <returns>True if the replied message contains a dice with the specified criteria; otherwise, false.</returns>
|
||||
protected override bool CanPassNext(FilterExecutionContext<Message> context)
|
||||
{
|
||||
if (context.Input.Dice == null)
|
||||
return false;
|
||||
|
||||
if (Dice != null && context.Input.Dice.Emoji != GetEmojyForDiceType(Dice))
|
||||
return false;
|
||||
|
||||
return context.Input.Dice.Value == Value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the emoji representation for a specific dice type.
|
||||
/// </summary>
|
||||
/// <param name="diceType">The dice type to get the emoji for.</param>
|
||||
/// <returns>The emoji string for the dice type, or null if not found.</returns>
|
||||
private static string? GetEmojyForDiceType(DiceType? diceType) => diceType switch
|
||||
{
|
||||
DiceType.Dice => "🎲",
|
||||
DiceType.Darts => "🎯",
|
||||
DiceType.Bowling => "🎳",
|
||||
DiceType.Basketball => "🏀",
|
||||
DiceType.Football => "⚽",
|
||||
DiceType.Casino => "🎰",
|
||||
_ => null
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filter that checks if the replied message contains specific message entities.
|
||||
/// </summary>
|
||||
/// <param name="replyDepth">The depth of reply chain to traverse (default: 1).</param>
|
||||
public class RepliedMessageHasEntityFilter(int replyDepth = 1) : RepliedMessageFilter(replyDepth)
|
||||
{
|
||||
/// <summary>
|
||||
/// The string comparison type to use for content matching.
|
||||
/// </summary>
|
||||
private readonly StringComparison _stringComparison = StringComparison.CurrentCulture;
|
||||
|
||||
/// <summary>
|
||||
/// The entity type to filter by (optional).
|
||||
/// </summary>
|
||||
private readonly MessageEntityType? EntityType;
|
||||
|
||||
/// <summary>
|
||||
/// The content to match in the entity (optional).
|
||||
/// </summary>
|
||||
private readonly string? Content;
|
||||
|
||||
/// <summary>
|
||||
/// The offset position to check (optional).
|
||||
/// </summary>
|
||||
private readonly int? Offset;
|
||||
|
||||
/// <summary>
|
||||
/// The length to check (optional).
|
||||
/// </summary>
|
||||
private readonly int? Length;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the found entities that match the filter criteria.
|
||||
/// </summary>
|
||||
public MessageEntity[]? FoundEntities { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RepliedMessageHasEntityFilter"/> class with a specific entity type.
|
||||
/// </summary>
|
||||
/// <param name="type">The entity type to filter by.</param>
|
||||
/// <param name="replyDepth">The depth of reply chain to traverse (default: 1).</param>
|
||||
public RepliedMessageHasEntityFilter(MessageEntityType type, int replyDepth = 1) : this(replyDepth)
|
||||
{
|
||||
EntityType = type;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RepliedMessageHasEntityFilter"/> class with position criteria.
|
||||
/// </summary>
|
||||
/// <param name="type">The entity type to filter by.</param>
|
||||
/// <param name="offset">The offset position to check.</param>
|
||||
/// <param name="length">The length to check (optional).</param>
|
||||
/// <param name="replyDepth">The depth of reply chain to traverse (default: 1).</param>
|
||||
public RepliedMessageHasEntityFilter(MessageEntityType type, int offset, int? length, int replyDepth = 1) : this(replyDepth)
|
||||
{
|
||||
EntityType = type;
|
||||
Offset = offset;
|
||||
Length = length;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RepliedMessageHasEntityFilter"/> class with content criteria.
|
||||
/// </summary>
|
||||
/// <param name="type">The entity type to filter by.</param>
|
||||
/// <param name="content">The content to match in the entity.</param>
|
||||
/// <param name="stringComparison">The string comparison type to use.</param>
|
||||
/// <param name="replyDepth">The depth of reply chain to traverse (default: 1).</param>
|
||||
public RepliedMessageHasEntityFilter(MessageEntityType type, string content, StringComparison stringComparison = StringComparison.CurrentCulture, int replyDepth = 1) : this(replyDepth)
|
||||
{
|
||||
EntityType = type;
|
||||
Content = content;
|
||||
_stringComparison = stringComparison;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RepliedMessageHasEntityFilter"/> class with all criteria.
|
||||
/// </summary>
|
||||
/// <param name="type">The entity type to filter by.</param>
|
||||
/// <param name="offset">The offset position to check.</param>
|
||||
/// <param name="length">The length to check (optional).</param>
|
||||
/// <param name="content">The content to match in the entity.</param>
|
||||
/// <param name="stringComparison">The string comparison type to use.</param>
|
||||
/// <param name="replyDepth">The depth of reply chain to traverse (default: 1).</param>
|
||||
public RepliedMessageHasEntityFilter(MessageEntityType type, int offset, int? length, string content, StringComparison stringComparison = StringComparison.CurrentCulture, int replyDepth = 1) : this(replyDepth)
|
||||
{
|
||||
EntityType = type;
|
||||
Offset = offset;
|
||||
Length = length;
|
||||
Content = content;
|
||||
_stringComparison = stringComparison;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the replied message contains entities that match the specified criteria.
|
||||
/// </summary>
|
||||
/// <param name="context">The filter execution context containing the message.</param>
|
||||
/// <returns>True if matching entities are found; otherwise, false.</returns>
|
||||
protected override bool CanPassNext(FilterExecutionContext<Message> context)
|
||||
{
|
||||
if (context.Input is not { Entities.Length: > 0 })
|
||||
return false;
|
||||
|
||||
FoundEntities = context.Input.Entities.Where(entity => FilterEntity(context.Input.Text, entity)).ToArray();
|
||||
return FoundEntities.Length != 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filters an entity based on the specified criteria.
|
||||
/// </summary>
|
||||
/// <param name="text">The message text containing the entity.</param>
|
||||
/// <param name="entity">The entity to filter.</param>
|
||||
/// <returns>True if the entity matches all specified criteria; otherwise, false.</returns>
|
||||
private bool FilterEntity(string? text, MessageEntity entity)
|
||||
{
|
||||
if (EntityType != null && entity.Type != EntityType)
|
||||
return false;
|
||||
|
||||
if (Offset != null && entity.Offset != Offset)
|
||||
return false;
|
||||
|
||||
if (Length != null && entity.Length != Length)
|
||||
return false;
|
||||
|
||||
if (Content != null)
|
||||
{
|
||||
if (text is not { Length: > 0 })
|
||||
return false;
|
||||
|
||||
if (!text.Substring(entity.Offset, entity.Length).Equals(Content, _stringComparison))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,192 +0,0 @@
|
||||
using Telegram.Bot.Types;
|
||||
using Telegrator.Filters.Components;
|
||||
|
||||
namespace Telegrator.Filters
|
||||
{
|
||||
/// <summary>
|
||||
/// Abstract base class for filters that operate on the sender of replied messages.
|
||||
/// Provides functionality to access and validate the user who sent the replied message.
|
||||
/// </summary>
|
||||
/// <param name="replyDepth">The depth of reply chain to traverse (default: 1).</param>
|
||||
public abstract class RepliedMessageSenderFilter(int replyDepth = 1) : RepliedMessageFilter(replyDepth)
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the user who sent the replied message.
|
||||
/// </summary>
|
||||
public User User { get; private set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Determines if the message can pass through the filter by validating the reply chain
|
||||
/// and ensuring the replied message has a valid sender.
|
||||
/// </summary>
|
||||
/// <param name="context">The filter execution context containing the message.</param>
|
||||
/// <returns>True if the reply chain is valid and has a sender; otherwise, false.</returns>
|
||||
public override bool CanPass(FilterExecutionContext<Message> context)
|
||||
{
|
||||
if (!CanPassReply(context))
|
||||
return false;
|
||||
|
||||
if (Reply.From is not { Id: > 0 } from)
|
||||
return false;
|
||||
|
||||
User = from;
|
||||
return CanPassNext(context);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filter that checks if the replied message sender has a specific username.
|
||||
/// </summary>
|
||||
/// <param name="username">The username to check for.</param>
|
||||
/// <param name="replyDepth">The depth of reply chain to traverse (default: 1).</param>
|
||||
public class RepliedUsernameFilter(string username, int replyDepth = 1) : RepliedMessageSenderFilter(replyDepth)
|
||||
{
|
||||
/// <summary>
|
||||
/// The username to check for.
|
||||
/// </summary>
|
||||
private readonly string _username = username;
|
||||
|
||||
/// <summary>
|
||||
/// The string comparison type to use for username matching.
|
||||
/// </summary>
|
||||
private readonly StringComparison _comparison = StringComparison.InvariantCulture;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RepliedUsernameFilter"/> class with custom string comparison.
|
||||
/// </summary>
|
||||
/// <param name="username">The username to check for.</param>
|
||||
/// <param name="comparison">The string comparison type to use.</param>
|
||||
/// <param name="replyDepth">The depth of reply chain to traverse (default: 1).</param>
|
||||
public RepliedUsernameFilter(string username, StringComparison comparison, int replyDepth = 1)
|
||||
: this(username, replyDepth) => _comparison = comparison;
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the replied message sender has the specified username.
|
||||
/// </summary>
|
||||
/// <param name="context">The filter execution context (unused).</param>
|
||||
/// <returns>True if the sender has the specified username; otherwise, false.</returns>
|
||||
protected override bool CanPassNext(FilterExecutionContext<Message> context)
|
||||
=> User.Username != null && User.Username.Equals(_username, _comparison);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filter that checks if the replied message sender has specific first and/or last name.
|
||||
/// </summary>
|
||||
/// <param name="firstName">The first name to check for.</param>
|
||||
/// <param name="lastName">The last name to check for (optional).</param>
|
||||
/// <param name="comparison">The string comparison type to use.</param>
|
||||
/// <param name="replyDepth">The depth of reply chain to traverse (default: 1).</param>
|
||||
public class RepliedUserFilter(string firstName, string? lastName, StringComparison comparison, int replyDepth = 1) : RepliedMessageSenderFilter(replyDepth)
|
||||
{
|
||||
/// <summary>
|
||||
/// The first name to check for.
|
||||
/// </summary>
|
||||
private readonly string _firstName = firstName;
|
||||
|
||||
/// <summary>
|
||||
/// The last name to check for (optional).
|
||||
/// </summary>
|
||||
private readonly string? _lastName = lastName;
|
||||
|
||||
/// <summary>
|
||||
/// The string comparison type to use for name matching.
|
||||
/// </summary>
|
||||
private readonly StringComparison _comparison = comparison;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RepliedUserFilter"/> class with first and last name.
|
||||
/// </summary>
|
||||
/// <param name="firstName">The first name to check for.</param>
|
||||
/// <param name="lastName">The last name to check for.</param>
|
||||
/// <param name="replyDepth">The depth of reply chain to traverse (default: 1).</param>
|
||||
public RepliedUserFilter(string firstName, string lastName, int replyDepth = 1)
|
||||
: this(firstName, lastName, StringComparison.InvariantCulture, replyDepth) { }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RepliedUserFilter"/> class with first name only.
|
||||
/// </summary>
|
||||
/// <param name="firstName">The first name to check for.</param>
|
||||
/// <param name="replyDepth">The depth of reply chain to traverse (default: 1).</param>
|
||||
public RepliedUserFilter(string firstName, int replyDepth = 1)
|
||||
: this(firstName, null, StringComparison.InvariantCulture, replyDepth) { }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RepliedUserFilter"/> class with first name and custom comparison.
|
||||
/// </summary>
|
||||
/// <param name="firstName">The first name to check for.</param>
|
||||
/// <param name="comparison">The string comparison type to use.</param>
|
||||
/// <param name="replyDepth">The depth of reply chain to traverse (default: 1).</param>
|
||||
public RepliedUserFilter(string firstName, StringComparison comparison, int replyDepth = 1)
|
||||
: this(firstName, null, comparison, replyDepth) { }
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the replied message sender has the specified first and/or last name.
|
||||
/// </summary>
|
||||
/// <param name="context">The filter execution context (unused).</param>
|
||||
/// <returns>True if the sender has the specified name(s); otherwise, false.</returns>
|
||||
protected override bool CanPassNext(FilterExecutionContext<Message> context)
|
||||
{
|
||||
if (User.LastName != null)
|
||||
{
|
||||
if (_lastName == null)
|
||||
return false;
|
||||
|
||||
if (!_firstName.Equals(User.LastName, _comparison))
|
||||
return false;
|
||||
}
|
||||
|
||||
return User.FirstName.Equals(_firstName, _comparison);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filter that checks if the replied message sender has a specific user ID.
|
||||
/// </summary>
|
||||
/// <param name="userId">The user ID to check for.</param>
|
||||
/// <param name="replyDepth">The depth of reply chain to traverse (default: 1).</param>
|
||||
public class RepliedUserIdFilter(long userId, int replyDepth = 1) : RepliedMessageSenderFilter(replyDepth)
|
||||
{
|
||||
/// <summary>
|
||||
/// The user ID to check for.
|
||||
/// </summary>
|
||||
private readonly long _userId = userId;
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the replied message sender has the specified user ID.
|
||||
/// </summary>
|
||||
/// <param name="_">The filter execution context (unused).</param>
|
||||
/// <returns>True if the sender has the specified user ID; otherwise, false.</returns>
|
||||
protected override bool CanPassNext(FilterExecutionContext<Message> _)
|
||||
=> User.Id == _userId;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filter that checks if the replied message was sent by a bot.
|
||||
/// </summary>
|
||||
/// <param name="replyDepth">The depth of reply chain to traverse (default: 1).</param>
|
||||
public class ReplyFromBotFilter(int replyDepth = 1) : RepliedMessageSenderFilter(replyDepth)
|
||||
{
|
||||
/// <summary>
|
||||
/// Checks if the replied message was sent by a bot.
|
||||
/// </summary>
|
||||
/// <param name="_">The filter execution context (unused).</param>
|
||||
/// <returns>True if the replied message was sent by a bot; otherwise, false.</returns>
|
||||
protected override bool CanPassNext(FilterExecutionContext<Message> _)
|
||||
=> User.IsBot;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filter that checks if the replied message was sent by a premium user.
|
||||
/// </summary>
|
||||
/// <param name="replyDepth">The depth of reply chain to traverse (default: 1).</param>
|
||||
public class ReplyFromPremiumUserFilter(int replyDepth = 1) : RepliedMessageSenderFilter(replyDepth)
|
||||
{
|
||||
/// <summary>
|
||||
/// Checks if the replied message was sent by a premium user.
|
||||
/// </summary>
|
||||
/// <param name="_">The filter execution context (unused).</param>
|
||||
/// <returns>True if the replied message was sent by a premium user; otherwise, false.</returns>
|
||||
protected override bool CanPassNext(FilterExecutionContext<Message> _)
|
||||
=> User.IsPremium;
|
||||
}
|
||||
}
|
||||
@@ -1,123 +0,0 @@
|
||||
using Telegram.Bot.Types;
|
||||
using Telegrator.Filters.Components;
|
||||
|
||||
namespace Telegrator.Filters
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for filters that operate on the text of a replied message (the message being replied to).
|
||||
/// The replyDepth parameter determines how many levels up the reply chain to search for the target message.
|
||||
/// </summary>
|
||||
public abstract class RepliedMessageTextFilters : RepliedMessageFilter
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the text of the replied message (the message being replied to at the specified depth).
|
||||
/// </summary>
|
||||
public string Text { get; private set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// The content to match in the replied message.
|
||||
/// </summary>
|
||||
protected readonly string Content;
|
||||
|
||||
/// <summary>
|
||||
/// The string comparison to use for matching.
|
||||
/// </summary>
|
||||
protected readonly StringComparison Comparison;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RepliedMessageTextFilters"/> class.
|
||||
/// </summary>
|
||||
/// <param name="content">The content to match.</param>
|
||||
/// <param name="comparison">The string comparison to use.</param>
|
||||
/// <param name="replyDepth">The reply depth to search up the reply chain for the target message.</param>
|
||||
protected RepliedMessageTextFilters(string content, StringComparison comparison = StringComparison.InvariantCulture, int replyDepth = 1)
|
||||
: base(replyDepth)
|
||||
{
|
||||
Content = content;
|
||||
Comparison = comparison;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override bool CanPass(FilterExecutionContext<Message> context)
|
||||
{
|
||||
Text = Reply.Text ?? string.Empty;
|
||||
return CanPassNext(context);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filters replied messages (the message being replied to at the specified depth) whose text starts with the specified content.
|
||||
/// </summary>
|
||||
public class RepliedTextStartsWithFilter : RepliedMessageTextFilters
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RepliedTextStartsWithFilter"/> class.
|
||||
/// </summary>
|
||||
/// <param name="content">The content to match.</param>
|
||||
/// <param name="comparison">The string comparison to use.</param>
|
||||
/// <param name="replyDepth">The reply depth to search up the reply chain for the target message.</param>
|
||||
public RepliedTextStartsWithFilter(string content, StringComparison comparison = StringComparison.InvariantCulture, int replyDepth = 1)
|
||||
: base(content, comparison, replyDepth) { }
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override bool CanPassNext(FilterExecutionContext<Message> _)
|
||||
=> Text.StartsWith(Content, Comparison);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filters replied messages (the message being replied to at the specified depth) whose text ends with the specified content.
|
||||
/// </summary>
|
||||
public class RepliedTextEndsWithFilter : RepliedMessageTextFilters
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RepliedTextEndsWithFilter"/> class.
|
||||
/// </summary>
|
||||
/// <param name="content">The content to match.</param>
|
||||
/// <param name="comparison">The string comparison to use.</param>
|
||||
/// <param name="replyDepth">The reply depth to search up the reply chain for the target message.</param>
|
||||
public RepliedTextEndsWithFilter(string content, StringComparison comparison = StringComparison.InvariantCulture, int replyDepth = 1)
|
||||
: base(content, comparison, replyDepth) { }
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override bool CanPassNext(FilterExecutionContext<Message> _)
|
||||
=> Text.EndsWith(Content, Comparison);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filters replied messages (the message being replied to at the specified depth) whose text contains the specified content.
|
||||
/// </summary>
|
||||
public class RepliedTextContainsFilter : RepliedMessageTextFilters
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RepliedTextContainsFilter"/> class.
|
||||
/// </summary>
|
||||
/// <param name="content">The content to match.</param>
|
||||
/// <param name="comparison">The string comparison to use.</param>
|
||||
/// <param name="replyDepth">The reply depth to search up the reply chain for the target message.</param>
|
||||
public RepliedTextContainsFilter(string content, StringComparison comparison = StringComparison.InvariantCulture, int replyDepth = 1)
|
||||
: base(content, comparison, replyDepth) { }
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override bool CanPassNext(FilterExecutionContext<Message> _)
|
||||
=> Text.IndexOf(Content, Comparison) >= 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filters replied messages (the message being replied to at the specified depth) whose text equals the specified content.
|
||||
/// </summary>
|
||||
public class RepliedTextEqualsFilter : RepliedMessageTextFilters
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RepliedTextEqualsFilter"/> class.
|
||||
/// </summary>
|
||||
/// <param name="content">The content to match.</param>
|
||||
/// <param name="comparison">The string comparison to use.</param>
|
||||
/// <param name="replyDepth">The reply depth to search up the reply chain for the target message.</param>
|
||||
public RepliedTextEqualsFilter(string content, StringComparison comparison = StringComparison.InvariantCulture, int replyDepth = 1)
|
||||
: base(content, comparison, replyDepth) { }
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override bool CanPassNext(FilterExecutionContext<Message> _)
|
||||
=> Text.Equals(Content, Comparison);
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
using Telegram.Bot.Types;
|
||||
using Telegrator.Filters.Components;
|
||||
|
||||
namespace Telegrator.Filters
|
||||
{
|
||||
public class RepliedToMeFilter : RepliedMessageFilter
|
||||
{
|
||||
protected override bool CanPassNext(FilterExecutionContext<Message> context)
|
||||
{
|
||||
if (Reply.From == null)
|
||||
return false;
|
||||
|
||||
return Reply.From.Id == (context.BotInfo?.User.Id ?? throw new ArgumentNullException(nameof(context), "MentionedFilter requires BotInfo to be initialized"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@ namespace Telegrator
|
||||
/// Interface for reactive Telegram bot implementations.
|
||||
/// Defines the core properties and capabilities of a reactive bot.
|
||||
/// </summary>
|
||||
public interface IReactiveTelegramBot
|
||||
public interface ITelegratorBot
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the update router for handling incoming updates.
|
||||
@@ -11,7 +11,7 @@ namespace Telegrator
|
||||
/// Main client class for the Telegrator library.
|
||||
/// Extends TelegramBotClient with reactive capabilities for handling updates.
|
||||
/// </summary>
|
||||
public class TelegratorClient : TelegramBotClient, IReactiveTelegramBot, ICollectingProvider
|
||||
public class TelegratorClient : TelegramBotClient, ITelegratorBot, ICollectingProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// The update router for handling incoming updates.
|
||||
|
||||
Reference in New Issue
Block a user