mirror of
https://github.com/yawaflua/Telegram.Net.git
synced 2025-12-08 19:49:30 +02:00
Create project
This commit is contained in:
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
bin/
|
||||||
|
obj/
|
||||||
|
/packages/
|
||||||
|
riderModule.iml
|
||||||
|
/_ReSharper.Caches/
|
||||||
14
Examples/Telegram.Examples/Program.cs
Normal file
14
Examples/Telegram.Examples/Program.cs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
using Microsoft.Extensions.Hosting;
|
||||||
|
using Telegram.Net;
|
||||||
|
|
||||||
|
var webHost = Host.CreateDefaultBuilder()
|
||||||
|
.ConfigureServices(k =>
|
||||||
|
{
|
||||||
|
k.ConnectTelegram(new("YOUR-TOKEN")
|
||||||
|
{
|
||||||
|
errorHandler = async (client, exception, ctx) =>
|
||||||
|
{
|
||||||
|
await Console.Out.WriteLineAsync(exception.Message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
15
Examples/Telegram.Examples/Telegram.Examples.csproj
Normal file
15
Examples/Telegram.Examples/Telegram.Examples.csproj
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.3" />
|
||||||
|
<ProjectReference Include="..\..\Telegram.Net\Telegram.Net.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
40
Examples/Telegram.Examples/UpdatePolling/Update.cs
Normal file
40
Examples/Telegram.Examples/UpdatePolling/Update.cs
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
using Telegram.Bot;
|
||||||
|
using Telegram.Bot.Types;
|
||||||
|
using Telegram.Net.Attributes;
|
||||||
|
using Telegram.Net.Interfaces;
|
||||||
|
|
||||||
|
namespace Telegram.Examples.UpdatePolling;
|
||||||
|
|
||||||
|
public class Update : IUpdatePollingSerivce
|
||||||
|
{
|
||||||
|
[Update]
|
||||||
|
public async Task UpdateExample(ITelegramBotClient client, Bot.Types.Update update, CancellationToken ctx)
|
||||||
|
{
|
||||||
|
if (update.Poll != null)
|
||||||
|
{
|
||||||
|
Console.WriteLine(update.Poll.IsClosed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Callback("act-")]
|
||||||
|
public async Task CallbackExample(ITelegramBotClient client, CallbackQuery query, CancellationToken ctx)
|
||||||
|
{
|
||||||
|
Console.WriteLine(query.Message!.Text);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Command("/start")]
|
||||||
|
public async Task StartCommand(ITelegramBotClient client, Message message, CancellationToken ctx)
|
||||||
|
{
|
||||||
|
if (message.Text!.Contains(" ") && message.Text.Split(" ")[1] == "test")
|
||||||
|
await client.SendMessage(message.From!.Id, "Hello, I`m example bot. And this - command with subparam", cancellationToken: ctx);
|
||||||
|
else
|
||||||
|
await client.SendMessage(message.From!.Id, "Hello, I`m example bot.", cancellationToken: ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
[EditMessage]
|
||||||
|
public async Task EditMessageExmaple(ITelegramBotClient client, Message message, CancellationToken ctx)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"new message text: {message.Text}");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
90
README.md
Normal file
90
README.md
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
# Telegram Bot Attribute Handlers
|
||||||
|
|
||||||
|
This project provides a set of C# attributes to facilitate the handling of different types of Telegram bot updates using reflection.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
- **Inline Query Handling** (`InlineAttribute`)
|
||||||
|
- **Edited Message Handling** (`EditMessageAttribute`)
|
||||||
|
- **Command Handling** (`CommandHandlerAttribute`)
|
||||||
|
- **Callback Query Handling** (`CallbackAttribute`)
|
||||||
|
- **PreCheckout Query Handling** (`PreCheckoutAttribute`)
|
||||||
|
- **General Update Handling** (`UpdateAttribute`)
|
||||||
|
- **Auto-generate telegram client**
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
Ensure you have the required dependencies installed:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
dotnet add package Telegram.Bot
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
### Inline Query Handling
|
||||||
|
Use the `InlineAttribute` to register a method as an inline query handler.
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
[Inline("example_query")]
|
||||||
|
public static async Task HandleInlineQuery(ITelegramBotClient bot, InlineQuery query, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
// Handle inline query
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Edited Message Handling
|
||||||
|
Use the `EditMessageAttribute` to register a method as a handler for edited messages.
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
[EditMessage]
|
||||||
|
public static async Task HandleEditedMessage(ITelegramBotClient bot, Message message, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
// Handle edited message
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Command Handling
|
||||||
|
Use the `CommandHandlerAttribute` to register a method as a command handler.
|
||||||
|
You can provide only begin of command text. Like, `/start act-`
|
||||||
|
```csharp
|
||||||
|
[CommandHandler("/start")]
|
||||||
|
public static async Task StartCommand(ITelegramBotClient bot, Message message, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
// Handle start command
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Callback Query Handling
|
||||||
|
Use the `CallbackAttribute` to register a method as a callback query handler.
|
||||||
|
You can provide only begin of callback data text
|
||||||
|
```csharp
|
||||||
|
[Callback("button_click")]
|
||||||
|
public static async Task HandleCallbackQuery(ITelegramBotClient bot, CallbackQuery query, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
// Handle callback query
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### PreCheckout Query Handling
|
||||||
|
Use the `PreCheckoutAttribute` to register a method as a pre-checkout query handler.
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
[PreCheckout]
|
||||||
|
public static async Task HandlePreCheckoutQuery(ITelegramBotClient bot, PreCheckoutQuery query, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
// Handle pre-checkout query
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### General Update Handling
|
||||||
|
Use the `UpdateAttribute` to register a method as a generic update handler.
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
[Update]
|
||||||
|
public static async Task HandleUpdate(ITelegramBotClient bot, Update update, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
// Handle general update
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## License
|
||||||
|
This project is open-source and available under the MIT License.
|
||||||
22
Telegram.Net.sln
Normal file
22
Telegram.Net.sln
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Telegram.Net", "Telegram.Net\Telegram.Net.csproj", "{137609A1-3482-465E-9B76-7E3F78FFC906}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Telegram.Examples", "Examples\Telegram.Examples\Telegram.Examples.csproj", "{073E66F2-F82E-4378-B390-C2364DFDC491}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{137609A1-3482-465E-9B76-7E3F78FFC906}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{137609A1-3482-465E-9B76-7E3F78FFC906}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{137609A1-3482-465E-9B76-7E3F78FFC906}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{137609A1-3482-465E-9B76-7E3F78FFC906}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{073E66F2-F82E-4378-B390-C2364DFDC491}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{073E66F2-F82E-4378-B390-C2364DFDC491}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{073E66F2-F82E-4378-B390-C2364DFDC491}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{073E66F2-F82E-4378-B390-C2364DFDC491}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
59
Telegram.Net/Attributes/CallbackAttribute.cs
Normal file
59
Telegram.Net/Attributes/CallbackAttribute.cs
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using Telegram.Bot;
|
||||||
|
using Telegram.Bot.Types;
|
||||||
|
using Telegram.Net.Interfaces;
|
||||||
|
using Telegram.Net.Services;
|
||||||
|
|
||||||
|
namespace Telegram.Net.Attributes;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Attribute for registering callback query handlers in a Telegram bot.
|
||||||
|
/// </summary>
|
||||||
|
[AttributeUsage(AttributeTargets.Method)]
|
||||||
|
public class CallbackAttribute : Attribute
|
||||||
|
{
|
||||||
|
public bool IsReusable => true;
|
||||||
|
public string QueryId { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="CallbackAttribute"/> class,
|
||||||
|
/// registering methods marked with this attribute as callback query handlers.
|
||||||
|
/// <code>
|
||||||
|
/// [Callback("auth-")] // You can use id like with StartsWith
|
||||||
|
/// public async Task PreCheckout(ITelegramBotClient client, CallbackQuery callback, CancellationToken ctx){
|
||||||
|
/// Console.WriteLine(callback.Data);
|
||||||
|
/// }
|
||||||
|
/// </code>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="queryId">The unique identifier for the callback query.</param>
|
||||||
|
public CallbackAttribute(string queryId)
|
||||||
|
{
|
||||||
|
this.QueryId = queryId;
|
||||||
|
|
||||||
|
var methods = typeof(IUpdatePollingSerivce).GetMethods()
|
||||||
|
.Where(m => m.GetCustomAttribute(this.GetType()) != null);
|
||||||
|
|
||||||
|
foreach (var method in methods)
|
||||||
|
{
|
||||||
|
if (IsValidHandlerMethod(method))
|
||||||
|
{
|
||||||
|
var attr = method.GetCustomAttribute<CallbackAttribute>();
|
||||||
|
var handler = (Func<ITelegramBotClient, CallbackQuery, CancellationToken, Task>)
|
||||||
|
Delegate.CreateDelegate(typeof(Func<ITelegramBotClient, CallbackQuery, CancellationToken, Task>), null,
|
||||||
|
method);
|
||||||
|
|
||||||
|
TelegramHostedService.CallbackQueryHandler.Add(attr!.QueryId, handler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool IsValidHandlerMethod(MethodInfo method)
|
||||||
|
{
|
||||||
|
var parameters = method.GetParameters();
|
||||||
|
return method.ReturnType == typeof(Task) &&
|
||||||
|
parameters.Length == 3 &&
|
||||||
|
parameters[0].ParameterType == typeof(ITelegramBotClient) &&
|
||||||
|
parameters[1].ParameterType == typeof(CallbackQuery) &&
|
||||||
|
parameters[2].ParameterType == typeof(CancellationToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
59
Telegram.Net/Attributes/CommandAttribute.cs
Normal file
59
Telegram.Net/Attributes/CommandAttribute.cs
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using Telegram.Bot;
|
||||||
|
using Telegram.Bot.Types;
|
||||||
|
using Telegram.Net.Interfaces;
|
||||||
|
using Telegram.Net.Services;
|
||||||
|
|
||||||
|
namespace Telegram.Net.Attributes;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Attribute for registering command handlers in a Telegram bot.
|
||||||
|
/// </summary>
|
||||||
|
[AttributeUsage(AttributeTargets.Method)]
|
||||||
|
public class CommandAttribute : Attribute
|
||||||
|
{
|
||||||
|
public bool IsReusable => true;
|
||||||
|
public string Command { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="CommandAttribute"/> class,
|
||||||
|
/// registering methods marked with this attribute as command handlers.
|
||||||
|
/// <code>
|
||||||
|
/// [Command("/start")] // You can use it like with StartsWith
|
||||||
|
/// public async Task Start(ITelegramBotClient client, Message message, CancellationToken ctx){
|
||||||
|
/// Console.WriteLine(message.Text);
|
||||||
|
/// }
|
||||||
|
/// </code>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="command">The command to be handled.</param>
|
||||||
|
public CommandAttribute(string command)
|
||||||
|
{
|
||||||
|
Command = command;
|
||||||
|
|
||||||
|
var methods = typeof(IUpdatePollingSerivce).GetMethods()
|
||||||
|
.Where(m => m.GetCustomAttribute(this.GetType()) != null);
|
||||||
|
|
||||||
|
foreach (var method in methods)
|
||||||
|
{
|
||||||
|
if (IsValidHandlerMethod(method))
|
||||||
|
{
|
||||||
|
var attr = method.GetCustomAttribute<CommandAttribute>();
|
||||||
|
var handler = (Func<ITelegramBotClient, Message, CancellationToken, Task>)
|
||||||
|
Delegate.CreateDelegate(typeof(Func<ITelegramBotClient, Message, CancellationToken, Task>), null,
|
||||||
|
method);
|
||||||
|
|
||||||
|
TelegramHostedService.CommandHandler.Add(attr!.Command, handler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool IsValidHandlerMethod(MethodInfo method)
|
||||||
|
{
|
||||||
|
var parameters = method.GetParameters();
|
||||||
|
return method.ReturnType == typeof(Task) &&
|
||||||
|
parameters.Length == 3 &&
|
||||||
|
parameters[0].ParameterType == typeof(ITelegramBotClient) &&
|
||||||
|
parameters[1].ParameterType == typeof(Message) &&
|
||||||
|
parameters[2].ParameterType == typeof(CancellationToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
54
Telegram.Net/Attributes/EditMessageAttribute.cs
Normal file
54
Telegram.Net/Attributes/EditMessageAttribute.cs
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using Telegram.Bot;
|
||||||
|
using Telegram.Bot.Types;
|
||||||
|
using Telegram.Net.Interfaces;
|
||||||
|
using Telegram.Net.Services;
|
||||||
|
|
||||||
|
namespace Telegram.Net.Attributes;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Attribute for registering handlers for edited messages in a Telegram bot.
|
||||||
|
/// </summary>
|
||||||
|
[AttributeUsage(AttributeTargets.Method)]
|
||||||
|
public class EditMessageAttribute : Attribute
|
||||||
|
{
|
||||||
|
public bool IsReusable => true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="EditMessageAttribute"/> class,
|
||||||
|
/// registering methods marked with this attribute as handlers for edited messages.
|
||||||
|
/// <code>
|
||||||
|
/// [EditMessage]
|
||||||
|
/// public async Task EditMessage(ITelegramBotClient client, Message message, CancellationToken ctx){
|
||||||
|
/// Console.WriteLine(message.Id);
|
||||||
|
/// }
|
||||||
|
/// </code>
|
||||||
|
/// </summary>
|
||||||
|
public EditMessageAttribute()
|
||||||
|
{
|
||||||
|
var methods = typeof(IUpdatePollingSerivce).GetMethods()
|
||||||
|
.Where(m => m.GetCustomAttribute(this.GetType()) != null);
|
||||||
|
|
||||||
|
foreach (var method in methods)
|
||||||
|
{
|
||||||
|
if (IsValidHandlerMethod(method))
|
||||||
|
{
|
||||||
|
var handler = (Func<ITelegramBotClient, Message, CancellationToken, Task>)
|
||||||
|
Delegate.CreateDelegate(typeof(Func<ITelegramBotClient, Message, CancellationToken, Task>), null,
|
||||||
|
method);
|
||||||
|
|
||||||
|
TelegramHostedService.EditedMessageHandler.Add(handler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool IsValidHandlerMethod(MethodInfo method)
|
||||||
|
{
|
||||||
|
var parameters = method.GetParameters();
|
||||||
|
return method.ReturnType == typeof(Task) &&
|
||||||
|
parameters.Length == 3 &&
|
||||||
|
parameters[0].ParameterType == typeof(ITelegramBotClient) &&
|
||||||
|
parameters[1].ParameterType == typeof(Message) &&
|
||||||
|
parameters[2].ParameterType == typeof(CancellationToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
60
Telegram.Net/Attributes/InlineAttribute.cs
Normal file
60
Telegram.Net/Attributes/InlineAttribute.cs
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using Telegram.Bot;
|
||||||
|
using Telegram.Bot.Types;
|
||||||
|
using Telegram.Net.Interfaces;
|
||||||
|
using Telegram.Net.Services;
|
||||||
|
|
||||||
|
namespace Telegram.Net.Attributes;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Attribute for registering inline query handlers in a Telegram bot.
|
||||||
|
/// </summary>
|
||||||
|
[AttributeUsage(AttributeTargets.Method)]
|
||||||
|
public class InlineAttribute : Attribute
|
||||||
|
{
|
||||||
|
public bool IsReusable => true;
|
||||||
|
public string InlineId { get; }
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="InlineAttribute"/> class,
|
||||||
|
/// registering methods marked with this attribute as inline query handlers.
|
||||||
|
/// <code>
|
||||||
|
/// [Inline("InlineId")] // You can use it like with StartsWith
|
||||||
|
/// public async Task Inline(ITelegramBotClient client, InlineQuery inline, CancellationToken ctx){
|
||||||
|
/// Console.WriteLine(inline.From.Id);
|
||||||
|
/// }
|
||||||
|
/// </code>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="inlineId">Unique identifier for the inline query.</param>
|
||||||
|
public InlineAttribute(string inlineId)
|
||||||
|
{
|
||||||
|
this.InlineId = inlineId;
|
||||||
|
var methods = typeof(IUpdatePollingSerivce).GetMethods()
|
||||||
|
.Where(m => m.GetCustomAttribute(this.GetType()) != null);
|
||||||
|
|
||||||
|
foreach (var method in methods)
|
||||||
|
{
|
||||||
|
if (IsValidHandlerMethod(method))
|
||||||
|
{
|
||||||
|
var attr = method.GetCustomAttribute<InlineAttribute>();
|
||||||
|
var handler = (Func<ITelegramBotClient, InlineQuery, CancellationToken, Task>)
|
||||||
|
Delegate.CreateDelegate(typeof(Func<ITelegramBotClient, InlineQuery, CancellationToken, Task>), null,
|
||||||
|
method);
|
||||||
|
|
||||||
|
TelegramHostedService.InlineHandler.Add(attr!.InlineId, handler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool IsValidHandlerMethod(MethodInfo method)
|
||||||
|
{
|
||||||
|
var parameters = method.GetParameters();
|
||||||
|
return method.ReturnType == typeof(Task) &&
|
||||||
|
parameters.Length == 3 &&
|
||||||
|
parameters[0].ParameterType == typeof(ITelegramBotClient) &&
|
||||||
|
parameters[1].ParameterType == typeof(InlineQuery) &&
|
||||||
|
parameters[2].ParameterType == typeof(CancellationToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
50
Telegram.Net/Attributes/PreCheckoutAttribute.cs
Normal file
50
Telegram.Net/Attributes/PreCheckoutAttribute.cs
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using Telegram.Bot;
|
||||||
|
using Telegram.Bot.Types;
|
||||||
|
using Telegram.Bot.Types.Payments;
|
||||||
|
using Telegram.Net.Interfaces;
|
||||||
|
using Telegram.Net.Services;
|
||||||
|
|
||||||
|
namespace Telegram.Net.Attributes;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Attribute for pre checkout handler. Using:
|
||||||
|
/// <code>
|
||||||
|
/// [PreCheckout]
|
||||||
|
/// public async Task PreCheckout(ITelegramBotClient client, PreCheckoutQuery preCheckout, CancellationToken ctx){
|
||||||
|
/// Console.WriteLine(preCheckout.Id);
|
||||||
|
/// }
|
||||||
|
/// </code>
|
||||||
|
/// </summary>
|
||||||
|
[AttributeUsage(AttributeTargets.Method)]
|
||||||
|
public class PreCheckoutAttribute : Attribute
|
||||||
|
{
|
||||||
|
public bool IsReusable => true;
|
||||||
|
public PreCheckoutAttribute()
|
||||||
|
{
|
||||||
|
var methods = typeof(IUpdatePollingSerivce).GetMethods()
|
||||||
|
.Where(m => m.GetCustomAttribute(this.GetType()) != null);
|
||||||
|
|
||||||
|
foreach (var method in methods)
|
||||||
|
{
|
||||||
|
if (IsValidHandlerMethod(method))
|
||||||
|
{
|
||||||
|
var handler = (Func<ITelegramBotClient, PreCheckoutQuery, CancellationToken, Task>)
|
||||||
|
Delegate.CreateDelegate(typeof(Func<ITelegramBotClient, PreCheckoutQuery, CancellationToken, Task>), null,
|
||||||
|
method);
|
||||||
|
|
||||||
|
TelegramHostedService.PreCheckoutHandler = (handler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool IsValidHandlerMethod(MethodInfo method)
|
||||||
|
{
|
||||||
|
var parameters = method.GetParameters();
|
||||||
|
return method.ReturnType == typeof(Task) &&
|
||||||
|
parameters.Length == 3 &&
|
||||||
|
parameters[0].ParameterType == typeof(ITelegramBotClient) &&
|
||||||
|
parameters[1].ParameterType == typeof(PreCheckoutQuery) &&
|
||||||
|
parameters[2].ParameterType == typeof(CancellationToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
49
Telegram.Net/Attributes/UpdateAttribute.cs
Normal file
49
Telegram.Net/Attributes/UpdateAttribute.cs
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using Telegram.Bot;
|
||||||
|
using Telegram.Bot.Types;
|
||||||
|
using Telegram.Net.Interfaces;
|
||||||
|
using Telegram.Net.Services;
|
||||||
|
|
||||||
|
namespace Telegram.Net.Attributes;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Attribute for default update handler. Using:
|
||||||
|
/// <code>
|
||||||
|
/// [Update]
|
||||||
|
/// public async Task UpdateHandler(ITelegramBotClient client, Update update, CancellationToken ctx){
|
||||||
|
/// Console.WriteLine(Update.Message?.Text);
|
||||||
|
/// }
|
||||||
|
/// </code>
|
||||||
|
/// </summary>
|
||||||
|
[AttributeUsage(AttributeTargets.Method)]
|
||||||
|
public class UpdateAttribute : Attribute
|
||||||
|
{
|
||||||
|
public bool IsReusable => true;
|
||||||
|
public UpdateAttribute()
|
||||||
|
{
|
||||||
|
var methods = typeof(IUpdatePollingSerivce).GetMethods()
|
||||||
|
.Where(m => m.GetCustomAttribute(this.GetType()) != null);
|
||||||
|
|
||||||
|
foreach (var method in methods)
|
||||||
|
{
|
||||||
|
if (IsValidHandlerMethod(method))
|
||||||
|
{
|
||||||
|
var handler = (Func<ITelegramBotClient, Update, CancellationToken, Task>)
|
||||||
|
Delegate.CreateDelegate(typeof(Func<ITelegramBotClient, Update, CancellationToken, Task>), null,
|
||||||
|
method);
|
||||||
|
|
||||||
|
TelegramHostedService.DefaultUpdateHandler.Add(handler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool IsValidHandlerMethod(MethodInfo method)
|
||||||
|
{
|
||||||
|
var parameters = method.GetParameters();
|
||||||
|
return method.ReturnType == typeof(Task) &&
|
||||||
|
parameters.Length == 3 &&
|
||||||
|
parameters[0].ParameterType == typeof(ITelegramBotClient) &&
|
||||||
|
parameters[1].ParameterType == typeof(Update) &&
|
||||||
|
parameters[2].ParameterType == typeof(CancellationToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
20
Telegram.Net/Interfaces/ITelegramBotConfig.cs
Normal file
20
Telegram.Net/Interfaces/ITelegramBotConfig.cs
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
using Telegram.Bot;
|
||||||
|
using Telegram.Bot.Polling;
|
||||||
|
|
||||||
|
namespace Telegram.Net.Interfaces;
|
||||||
|
|
||||||
|
public interface ITelegramBotConfig
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Token of telegram bot. You can take it from @BotFather
|
||||||
|
/// </summary>
|
||||||
|
public string Token { internal get; init; }
|
||||||
|
/// <summary>
|
||||||
|
/// Custom error handler for bot. You can add custom logger or anything.
|
||||||
|
/// </summary>
|
||||||
|
public Func<ITelegramBotClient, Exception, CancellationToken, Task>? errorHandler { get; init; }
|
||||||
|
/// <summary>
|
||||||
|
/// Custom receiver options
|
||||||
|
/// </summary>
|
||||||
|
public ReceiverOptions? ReceiverOptions { get; init; }
|
||||||
|
}
|
||||||
9
Telegram.Net/Interfaces/IUpdatePollingSerivce.cs
Normal file
9
Telegram.Net/Interfaces/IUpdatePollingSerivce.cs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
namespace Telegram.Net.Interfaces;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// You should implement this interface in all your classes with update polling logic
|
||||||
|
/// </summary>
|
||||||
|
public interface IUpdatePollingSerivce
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
17
Telegram.Net/Models/TelegramBotConfig.cs
Normal file
17
Telegram.Net/Models/TelegramBotConfig.cs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
using Telegram.Bot;
|
||||||
|
using Telegram.Bot.Polling;
|
||||||
|
using Telegram.Net.Interfaces;
|
||||||
|
|
||||||
|
namespace Telegram.Net.Models;
|
||||||
|
|
||||||
|
public class TelegramBotConfig : ITelegramBotConfig
|
||||||
|
{
|
||||||
|
public TelegramBotConfig(string token)
|
||||||
|
{
|
||||||
|
Token = token;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Token { get; init; }
|
||||||
|
public Func<ITelegramBotClient, Exception, CancellationToken, Task>? errorHandler { get; init; }
|
||||||
|
public ReceiverOptions? ReceiverOptions { get; init; }
|
||||||
|
}
|
||||||
14
Telegram.Net/ServiceBindings.cs
Normal file
14
Telegram.Net/ServiceBindings.cs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Telegram.Net.Models;
|
||||||
|
using Telegram.Net.Services;
|
||||||
|
|
||||||
|
namespace Telegram.Net;
|
||||||
|
|
||||||
|
public static class ServiceBindings
|
||||||
|
{
|
||||||
|
public static IServiceCollection ConnectTelegram(this IServiceCollection isc, TelegramBotConfig config)
|
||||||
|
{
|
||||||
|
isc.AddHostedService<TelegramHostedService>(k => new(config));
|
||||||
|
return isc;
|
||||||
|
}
|
||||||
|
}
|
||||||
68
Telegram.Net/Services/TelegramHostedService.cs
Normal file
68
Telegram.Net/Services/TelegramHostedService.cs
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using Microsoft.Extensions.Hosting;
|
||||||
|
using Telegram.Bot;
|
||||||
|
using Telegram.Bot.Types;
|
||||||
|
using Telegram.Bot.Types.Payments;
|
||||||
|
using Telegram.Net.Interfaces;
|
||||||
|
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously
|
||||||
|
|
||||||
|
namespace Telegram.Net.Services;
|
||||||
|
|
||||||
|
public class TelegramHostedService : IHostedService
|
||||||
|
{
|
||||||
|
private TelegramBotClient Client { get; }
|
||||||
|
private ITelegramBotConfig Config { get; }
|
||||||
|
internal static Dictionary<string, Func<ITelegramBotClient, Message, CancellationToken, Task>> CommandHandler { get; } = new();
|
||||||
|
internal static List<Func<ITelegramBotClient, Message, CancellationToken, Task>> EditedMessageHandler { get; } = new();
|
||||||
|
internal static Dictionary<string, Func<ITelegramBotClient, CallbackQuery,CancellationToken, Task>> CallbackQueryHandler { get; } = new();
|
||||||
|
internal static Dictionary<string, Func<ITelegramBotClient, InlineQuery ,CancellationToken, Task>> InlineHandler { get; } = new();
|
||||||
|
internal static Func<ITelegramBotClient, PreCheckoutQuery,CancellationToken, Task>? PreCheckoutHandler { get; set; }
|
||||||
|
internal static List<Func<ITelegramBotClient, Update, CancellationToken, Task>> DefaultUpdateHandler { get; } = new();
|
||||||
|
|
||||||
|
public TelegramHostedService(ITelegramBotConfig config)
|
||||||
|
{
|
||||||
|
Client = new TelegramBotClient(config.Token);
|
||||||
|
Config = config;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[SuppressMessage("ReSharper", "AsyncVoidLambda")]
|
||||||
|
public async Task StartAsync(CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
Client.StartReceiving(
|
||||||
|
async (client, update, ctx) =>
|
||||||
|
{
|
||||||
|
switch (update)
|
||||||
|
{
|
||||||
|
case { Message: { } message }:
|
||||||
|
await CommandHandler.FirstOrDefault(k => message.Text!.StartsWith(k.Key)).Value(client, message, cancellationToken);
|
||||||
|
break;
|
||||||
|
case { EditedMessage: { } message }:
|
||||||
|
EditedMessageHandler.ForEach(async k => await k(client, message, cancellationToken));
|
||||||
|
break;
|
||||||
|
case { CallbackQuery: { } callbackQuery }:
|
||||||
|
await CallbackQueryHandler.FirstOrDefault(k => callbackQuery.Data!.StartsWith(k.Key)).Value(client, callbackQuery, cancellationToken);
|
||||||
|
break;
|
||||||
|
case { InlineQuery: { } inlineQuery }:
|
||||||
|
await InlineHandler.FirstOrDefault(k => inlineQuery.Id.StartsWith(k.Key)).Value(client, inlineQuery, cancellationToken);
|
||||||
|
break;
|
||||||
|
case {PreCheckoutQuery: { } preCheckoutQuery}:
|
||||||
|
if (PreCheckoutHandler != null)
|
||||||
|
await PreCheckoutHandler(client, preCheckoutQuery, cancellationToken);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
DefaultUpdateHandler.ForEach(async k => await k(client, update, ctx));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
Config.errorHandler ?? ((_, _, _) => Task.CompletedTask),
|
||||||
|
Config.ReceiverOptions,
|
||||||
|
cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task StopAsync(CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
await Client.DropPendingUpdates(cancellationToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
14
Telegram.Net/Telegram.Net.csproj
Normal file
14
Telegram.Net/Telegram.Net.csproj
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="9.0.3" />
|
||||||
|
<PackageReference Include="Telegram.Bot" Version="22.4.4" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
Reference in New Issue
Block a user