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:
@@ -39,8 +39,11 @@ Telegrator is a next-generation framework for building Telegram bots in C#, insp
|
|||||||
### 1. Installation
|
### 1. Installation
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
# Coming soon: will be available via NuGet
|
# .NET CLI
|
||||||
# dotnet add package Telegrator
|
dotnet add package Telegrator
|
||||||
|
|
||||||
|
# NuGet CLI
|
||||||
|
NuGet\Install-Package Telegrator
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2. Minimal Bot Example
|
### 2. Minimal Bot Example
|
||||||
@@ -59,7 +62,7 @@ public class HelloHandler : MessageHandler
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Registration and launch:
|
// Registration and launch:
|
||||||
var bot = new ReactiveClient("<YOUR_BOT_TOKEN>");
|
var bot = new TelegratorClient("<YOUR_BOT_TOKEN>");
|
||||||
bot.Handlers.AddHandler<HelloHandler>();
|
bot.Handlers.AddHandler<HelloHandler>();
|
||||||
bot.StartReceiving();
|
bot.StartReceiving();
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ namespace Telegrator.Hosting.Components
|
|||||||
/// Interface for Telegram bot hosts.
|
/// Interface for Telegram bot hosts.
|
||||||
/// Combines host application capabilities with reactive Telegram bot functionality.
|
/// Combines host application capabilities with reactive Telegram bot functionality.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface ITelegramBotHost : IHost, IReactiveTelegramBot
|
public interface ITelegramBotHost : IHost, ITelegratorBot
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,3 +6,4 @@
|
|||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
[assembly: SuppressMessage("Style", "IDE0290")]
|
[assembly: SuppressMessage("Style", "IDE0290")]
|
||||||
|
[assembly: SuppressMessage("Style", "IDE0090")]
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ namespace Telegrator.Hosting
|
|||||||
//hostApplicationBuilder.Services.AddSingleton<IHost>(this);
|
//hostApplicationBuilder.Services.AddSingleton<IHost>(this);
|
||||||
|
|
||||||
hostApplicationBuilder.Services.AddSingleton<ITelegramBotHost>(this);
|
hostApplicationBuilder.Services.AddSingleton<ITelegramBotHost>(this);
|
||||||
hostApplicationBuilder.Services.AddSingleton<IReactiveTelegramBot>(this);
|
hostApplicationBuilder.Services.AddSingleton<ITelegratorBot>(this);
|
||||||
hostApplicationBuilder.Services.AddSingleton<IHandlersCollection>(handlers);
|
hostApplicationBuilder.Services.AddSingleton<IHandlersCollection>(handlers);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,6 @@
|
|||||||
<PackageProjectUrl></PackageProjectUrl>
|
<PackageProjectUrl></PackageProjectUrl>
|
||||||
<Title>Telegrator : Telegram.Bot mediator framework</Title>
|
<Title>Telegrator : Telegram.Bot mediator framework</Title>
|
||||||
<PackageIcon>telegrator_nuget.png</PackageIcon>
|
<PackageIcon>telegrator_nuget.png</PackageIcon>
|
||||||
<PackageReadmeFile>README.md</PackageReadmeFile>
|
|
||||||
<RepositoryUrl>https://github.com/Rikitav/Telegrator</RepositoryUrl>
|
<RepositoryUrl>https://github.com/Rikitav/Telegrator</RepositoryUrl>
|
||||||
<PackageTags>telegram;bot;mediator;attributes;aspect;hosting;host;framework;easy;simple;handlers</PackageTags>
|
<PackageTags>telegram;bot;mediator;attributes;aspect;hosting;host;framework;easy;simple;handlers</PackageTags>
|
||||||
<EnableNETAnalyzers>True</EnableNETAnalyzers>
|
<EnableNETAnalyzers>True</EnableNETAnalyzers>
|
||||||
|
|||||||
@@ -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.
|
/// 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.
|
/// Requires a <see cref="MessageHasEntityFilter"/> to be applied first to identify mention entities.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class MentionedFilter : Filter<Message>
|
public class MentionedFilter : MessageFilterBase
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The username to check for in the mention (null means check for bot's username).
|
/// 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>
|
/// <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>
|
/// <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>
|
/// <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;
|
return false;
|
||||||
|
|
||||||
string userName = Mention ?? context.BotInfo.User.Username ?? throw new ArgumentNullException(nameof(context), "MentionedFilter requires BotInfo to be initialized");
|
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);
|
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>
|
/// <summary>
|
||||||
/// Base class for filters that operate on the chat of the message being processed.
|
/// Base class for filters that operate on the chat of the message being processed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class MessageChatFilter : Filter<Message>
|
public abstract class MessageChatFilter : MessageFilterBase
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the chat of the message being processed.
|
/// Gets the chat of the message being processed.
|
||||||
@@ -15,18 +15,18 @@ namespace Telegrator.Filters
|
|||||||
public Chat Chat { get; private set; } = null!;
|
public Chat Chat { get; private set; } = null!;
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <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));
|
return CanPassNext(context.CreateChild(Chat));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines whether the filter passes for the given chat context.
|
/// Determines whether the filter passes for the given chat context.
|
||||||
/// </summary>
|
/// </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>
|
/// <returns>True if the filter passes; otherwise, false.</returns>
|
||||||
protected abstract bool CanPassNext(FilterExecutionContext<Chat> _);
|
protected abstract bool CanPassNext(FilterExecutionContext<Chat> context);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -1,15 +1,40 @@
|
|||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using Telegram.Bot.Types;
|
using Telegram.Bot.Types;
|
||||||
using Telegram.Bot.Types.Enums;
|
using Telegram.Bot.Types.Enums;
|
||||||
using Telegrator;
|
|
||||||
using Telegrator.Filters.Components;
|
using Telegrator.Filters.Components;
|
||||||
|
|
||||||
namespace Telegrator.Filters
|
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>
|
/// <summary>
|
||||||
/// Filters messages by their <see cref="MessageType"/>.
|
/// Filters messages by their <see cref="MessageType"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class MessageTypeFilter : Filter<Message>
|
public class MessageTypeFilter : MessageFilterBase
|
||||||
{
|
{
|
||||||
private readonly MessageType type;
|
private readonly MessageType type;
|
||||||
|
|
||||||
@@ -20,54 +45,54 @@ namespace Telegrator.Filters
|
|||||||
public MessageTypeFilter(MessageType type) => this.type = type;
|
public MessageTypeFilter(MessageType type) => this.type = type;
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public override bool CanPass(FilterExecutionContext<Message> context)
|
protected override bool CanPassNext(FilterExecutionContext<Message> context)
|
||||||
=> context.Input.Type == type;
|
=> Target.Type == type;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Filters messages that are automatic forwards.
|
/// Filters messages that are automatic forwards.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class IsAutomaticFormwardMessageFilter : Filter<Message>
|
public class IsAutomaticFormwardMessageFilter : MessageFilterBase
|
||||||
{
|
{
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public override bool CanPass(FilterExecutionContext<Message> context)
|
protected override bool CanPassNext(FilterExecutionContext<Message> context)
|
||||||
=> context.Input.IsAutomaticForward;
|
=> Target.IsAutomaticForward;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Filters messages that are sent from offline.
|
/// Filters messages that are sent from offline.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class IsFromOfflineMessageFilter : Filter<Message>
|
public class IsFromOfflineMessageFilter : MessageFilterBase
|
||||||
{
|
{
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public override bool CanPass(FilterExecutionContext<Message> context)
|
protected override bool CanPassNext(FilterExecutionContext<Message> context)
|
||||||
=> context.Input.IsFromOffline;
|
=> Target.IsFromOffline;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Filters service messages (e.g., chat events).
|
/// Filters service messages (e.g., chat events).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class IsServiceMessageMessageFilter : Filter<Message>
|
public class IsServiceMessageMessageFilter : MessageFilterBase
|
||||||
{
|
{
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public override bool CanPass(FilterExecutionContext<Message> context)
|
protected override bool CanPassNext(FilterExecutionContext<Message> context)
|
||||||
=> context.Input.IsServiceMessage;
|
=> Target.IsServiceMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Filters messages that are topic messages.
|
/// Filters messages that are topic messages.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class IsTopicMessageMessageFilter : Filter<Message>
|
public class IsTopicMessageMessageFilter : MessageFilterBase
|
||||||
{
|
{
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public override bool CanPass(FilterExecutionContext<Message> context)
|
protected override bool CanPassNext(FilterExecutionContext<Message> context)
|
||||||
=> context.Input.IsTopicMessage;
|
=> Target.IsTopicMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Filters messages by dice throw value and optionally by dice type.
|
/// Filters messages by dice throw value and optionally by dice type.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class DiceThrowedFilter : Filter<Message>
|
public class DiceThrowedFilter : MessageFilterBase
|
||||||
{
|
{
|
||||||
private readonly DiceType? Dice;
|
private readonly DiceType? Dice;
|
||||||
private readonly int Value;
|
private readonly int Value;
|
||||||
@@ -89,15 +114,15 @@ namespace Telegrator.Filters
|
|||||||
public DiceThrowedFilter(DiceType diceType, int value) : this(value) => Dice = diceType;
|
public DiceThrowedFilter(DiceType diceType, int value) : this(value) => Dice = diceType;
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <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;
|
return false;
|
||||||
|
|
||||||
if (Dice != null && context.Input.Dice.Emoji != GetEmojyForDiceType(Dice))
|
if (Dice != null && Target.Dice.Emoji != GetEmojyForDiceType(Dice))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return context.Input.Dice.Value == Value;
|
return Target.Dice.Value == Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string? GetEmojyForDiceType(DiceType? diceType) => diceType switch
|
private static string? GetEmojyForDiceType(DiceType? diceType) => diceType switch
|
||||||
@@ -136,7 +161,7 @@ namespace Telegrator.Filters
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Filters messages that contain a specific entity type, content, offset, or length.
|
/// Filters messages that contain a specific entity type, content, offset, or length.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class MessageHasEntityFilter : Filter<Message>
|
public class MessageHasEntityFilter : MessageFilterBase
|
||||||
{
|
{
|
||||||
private readonly StringComparison _stringComparison = StringComparison.CurrentCulture;
|
private readonly StringComparison _stringComparison = StringComparison.CurrentCulture;
|
||||||
private readonly MessageEntityType? EntityType;
|
private readonly MessageEntityType? EntityType;
|
||||||
@@ -202,12 +227,12 @@ namespace Telegrator.Filters
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public override bool CanPass(FilterExecutionContext<Message> context)
|
protected override bool CanPassNext(FilterExecutionContext<Message> context)
|
||||||
{
|
{
|
||||||
if (context.Input is not { Entities.Length: > 0 })
|
if (context.Input is not { Entities.Length: > 0 })
|
||||||
return false;
|
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;
|
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.
|
/// Abstract base class for filters that operate on message senders.
|
||||||
/// Provides functionality to access and validate the user who sent the message.
|
/// Provides functionality to access and validate the user who sent the message.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class MessageSenderFilter : Filter<Message>
|
public abstract class MessageSenderFilter : MessageFilterBase
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the user who sent the message.
|
/// 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>
|
/// <returns>True if the message has a valid sender; otherwise, false.</returns>
|
||||||
public override bool CanPass(FilterExecutionContext<Message> context)
|
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 })
|
if (User is not { Id: > 0 })
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return CanPassNext(context);
|
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>
|
/// <summary>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ namespace Telegrator.Filters
|
|||||||
/// Abstract base class for filters that operate on message text content.
|
/// Abstract base class for filters that operate on message text content.
|
||||||
/// Provides common functionality for extracting and validating message text.
|
/// Provides common functionality for extracting and validating message text.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class MessageTextFilter : Filter<Message>
|
public abstract class MessageTextFilter : MessageFilterBase
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the current message being processed by the filter.
|
/// 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>
|
/// <returns>True if the message is valid and can be processed further; otherwise, false.</returns>
|
||||||
public override bool CanPass(FilterExecutionContext<Message> context)
|
public override bool CanPass(FilterExecutionContext<Message> context)
|
||||||
{
|
{
|
||||||
|
if (!base.CanPass(context))
|
||||||
|
return false;
|
||||||
|
|
||||||
Message = context.Update.Message!;
|
Message = context.Update.Message!;
|
||||||
if (Message is not { Id: > 0 })
|
if (Message is not { Id: > 0 })
|
||||||
return false;
|
return false;
|
||||||
@@ -36,14 +39,6 @@ namespace Telegrator.Filters
|
|||||||
Text = Message.Text ?? string.Empty;
|
Text = Message.Text ?? string.Empty;
|
||||||
return CanPassNext(context);
|
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>
|
/// <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.
|
/// Interface for reactive Telegram bot implementations.
|
||||||
/// Defines the core properties and capabilities of a reactive bot.
|
/// Defines the core properties and capabilities of a reactive bot.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IReactiveTelegramBot
|
public interface ITelegratorBot
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the update router for handling incoming updates.
|
/// Gets the update router for handling incoming updates.
|
||||||
@@ -11,7 +11,7 @@ namespace Telegrator
|
|||||||
/// Main client class for the Telegrator library.
|
/// Main client class for the Telegrator library.
|
||||||
/// Extends TelegramBotClient with reactive capabilities for handling updates.
|
/// Extends TelegramBotClient with reactive capabilities for handling updates.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class TelegratorClient : TelegramBotClient, IReactiveTelegramBot, ICollectingProvider
|
public class TelegratorClient : TelegramBotClient, ITelegratorBot, ICollectingProvider
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The update router for handling incoming updates.
|
/// The update router for handling incoming updates.
|
||||||
|
|||||||
Reference in New Issue
Block a user