mirror of
https://github.com/yawaflua/Telegram-Bot-Template.git
synced 2025-12-09 03:49:30 +02:00
Add readme and template base
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
namespace TG_Bot_Template.Controllers
|
namespace $safeprojectname$.Controllers
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Example controller
|
/// Example controller
|
||||||
|
|||||||
@@ -8,17 +8,16 @@ EXPOSE 80
|
|||||||
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
|
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
|
||||||
ARG BUILD_CONFIGURATION=Release
|
ARG BUILD_CONFIGURATION=Release
|
||||||
WORKDIR /src
|
WORKDIR /src
|
||||||
COPY ["TG-Bot-Template.csproj", "."]
|
|
||||||
RUN dotnet restore "./TG-Bot-Template.csproj"
|
|
||||||
COPY . .
|
COPY . .
|
||||||
|
RUN dotnet restore
|
||||||
WORKDIR "/src/."
|
WORKDIR "/src/."
|
||||||
RUN dotnet build "./TG-Bot-Template.csproj" -c $BUILD_CONFIGURATION -o /app/build
|
RUN dotnet build -c $BUILD_CONFIGURATION -o /app/build
|
||||||
|
|
||||||
FROM build AS publish
|
FROM build AS publish
|
||||||
ARG BUILD_CONFIGURATION=Release
|
ARG BUILD_CONFIGURATION=Release
|
||||||
RUN dotnet publish "./TG-Bot-Template.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
|
RUN dotnet publish -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
|
||||||
|
|
||||||
FROM base AS final
|
FROM base AS final
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY --from=publish /app/publish .
|
COPY --from=publish /app/publish .
|
||||||
ENTRYPOINT ["dotnet", "TG-Bot-Template.dll"]
|
ENTRYPOINT ["dotnet", "$safeprojectname$"]
|
||||||
35
MyTemplate.vstemplate
Normal file
35
MyTemplate.vstemplate
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
<VSTemplate Version="3.0.0" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005" Type="Project">
|
||||||
|
<TemplateData>
|
||||||
|
<Name>Telegram.Bit</Name>
|
||||||
|
<Description>Template of new ASP .NET 8 Telegram bot project</Description>
|
||||||
|
<ProjectType>CSharp</ProjectType>
|
||||||
|
<ProjectSubType>
|
||||||
|
</ProjectSubType>
|
||||||
|
<SortOrder>1000</SortOrder>
|
||||||
|
<CreateNewFolder>true</CreateNewFolder>
|
||||||
|
<DefaultName>Telegram.Bot</DefaultName>
|
||||||
|
<ProvideDefaultName>true</ProvideDefaultName>
|
||||||
|
<LocationField>Enabled</LocationField>
|
||||||
|
<EnableLocationBrowseButton>true</EnableLocationBrowseButton>
|
||||||
|
<CreateInPlace>true</CreateInPlace>
|
||||||
|
<Icon>__TemplateIcon.ico</Icon>
|
||||||
|
</TemplateData>
|
||||||
|
<TemplateContent>
|
||||||
|
<Project TargetFileName="TG-Bot-Template.csproj" File="TG-Bot-Template.csproj" ReplaceParameters="true">
|
||||||
|
<Folder Name="Properties" TargetFolderName="Properties">
|
||||||
|
<ProjectItem ReplaceParameters="true" TargetFileName="launchSettings.json">launchSettings.json</ProjectItem>
|
||||||
|
</Folder>
|
||||||
|
<Folder Name=".vs" TargetFolderName=".vs" />
|
||||||
|
<Folder Name="Controllers" TargetFolderName="Controllers">
|
||||||
|
<ProjectItem ReplaceParameters="true" TargetFileName="ExampleController.cs">ExampleController.cs</ProjectItem>
|
||||||
|
</Folder>
|
||||||
|
<ProjectItem ReplaceParameters="true" TargetFileName="appsettings.json">appsettings.json</ProjectItem>
|
||||||
|
<ProjectItem ReplaceParameters="true" TargetFileName="appsettings.Development.json">appsettings.Development.json</ProjectItem>
|
||||||
|
<ProjectItem ReplaceParameters="true" TargetFileName="Dockerfile">Dockerfile</ProjectItem>
|
||||||
|
<ProjectItem ReplaceParameters="false" TargetFileName=".dockerignore">.dockerignore</ProjectItem>
|
||||||
|
<ProjectItem ReplaceParameters="true" TargetFileName="Program.cs">Program.cs</ProjectItem>
|
||||||
|
<ProjectItem ReplaceParameters="true" TargetFileName="Startup.cs">Startup.cs</ProjectItem>
|
||||||
|
<ProjectItem ReplaceParameters="true" TargetFileName="TelegramBotService.cs">TelegramBotService.cs</ProjectItem>
|
||||||
|
</Project>
|
||||||
|
</TemplateContent>
|
||||||
|
</VSTemplate>
|
||||||
34
Program.cs
34
Program.cs
@@ -1,25 +1,23 @@
|
|||||||
|
namespace $safeprojectname$
|
||||||
using Microsoft.AspNetCore;
|
|
||||||
|
|
||||||
namespace TG_Bot_Template
|
|
||||||
{
|
{
|
||||||
public class Program
|
public class Program
|
||||||
|
{
|
||||||
|
public static void Main()
|
||||||
{
|
{
|
||||||
public static void Main()
|
CreateHostBuilder()
|
||||||
|
.Build()
|
||||||
|
.Run();
|
||||||
|
}
|
||||||
|
private static IHostBuilder CreateHostBuilder()
|
||||||
|
{
|
||||||
|
return Host.CreateDefaultBuilder()
|
||||||
|
.ConfigureWebHostDefaults(webHost =>
|
||||||
{
|
{
|
||||||
CreateHostBuilder()
|
webHost.UseStartup<Startup>();
|
||||||
.Build()
|
webHost.UseStaticWebAssets();
|
||||||
.Run();
|
webHost.UseKestrel(kestrelOptions => { kestrelOptions.ListenAnyIP(80); });
|
||||||
}
|
});
|
||||||
private static IHostBuilder CreateHostBuilder()
|
|
||||||
{
|
|
||||||
return Host.CreateDefaultBuilder()
|
|
||||||
.ConfigureWebHostDefaults(webHost => {
|
|
||||||
webHost.UseStartup<Startup>();
|
|
||||||
webHost.UseStaticWebAssets();
|
|
||||||
webHost.UseKestrel(kestrelOptions => { kestrelOptions.ListenAnyIP(80); });
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|||||||
45
README.md
Normal file
45
README.md
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
# Template for Telegram BOT project
|
||||||
|
## About it
|
||||||
|
This is a template for VS 2023 Community/Enterprice for creating project with Telegram Bot service and base settings.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Used stack:
|
||||||
|
- .NET 8 Sdk Web
|
||||||
|
- ASP
|
||||||
|
- Swagger UI with commas setup
|
||||||
|
- Telegram.Bots (For .NET)
|
||||||
|
|
||||||
|
# Use as template
|
||||||
|
For start used this project as a template, u should to download it.
|
||||||
|
After that, open it with Visual Studio, press "Project" -> "Export Template".
|
||||||
|
In window u need to select "Project export"(For exporting exactly Project) and press "Next".
|
||||||
|
In next window u can edit template name, description and icon.
|
||||||
|
After pressing "Finish" button, you can create project with this template.
|
||||||
|
|
||||||
|
### OR
|
||||||
|
|
||||||
|
Another way to use this project as a template: ZIP to folder with VS.
|
||||||
|
Download this project and compress it to .zip file with any name. After that, go to this destination:
|
||||||
|
```bash
|
||||||
|
C:\Users\{{YOUR_USERNAME}}\AppData\Roaming\Microsoft\VisualStudio\{{VS_VERSION}}\
|
||||||
|
```
|
||||||
|
Create folder with this name: `ProjectTemplatesCache` and pull zipped project to created folder.
|
||||||
|
After reloading VS you can create new project with this template.
|
||||||
|
|
||||||
|
# Use as base for project
|
||||||
|
Its very simple to use, just download it and in file `appsettings.json` change in
|
||||||
|
"tg-token" (`"tg-token": "TOKEN"`) variable from TOKEN to your Bot`s token from [@BotFather](https://t.me/BotFather).
|
||||||
|
|
||||||
|
After that, change press RMB on project and select "Sync Namespaces". If you need to use Dockerfile, change from "$safeprojectname$" to your project name in last stroke
|
||||||
|
|
||||||
|
# appsettings.json
|
||||||
|
|
||||||
|
Your appsettings.json file must be looked like this:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"tg-token": "123456:AaBbCcDd"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
or any with this variable
|
||||||
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
using Microsoft.AspNetCore.Hosting.Server;
|
using Microsoft.AspNetCore.Hosting.Server;
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace TG_Bot_Template
|
namespace $safeprojectname$
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Startup class for ASP.NET with setting and configuration
|
/// Startup class for ASP.NET with setting and configuration
|
||||||
|
|||||||
@@ -1,141 +1,139 @@
|
|||||||
using System;
|
using Telegram.Bot;
|
||||||
using Telegram.Bot.Types;
|
|
||||||
using Telegram.Bot;
|
|
||||||
using Telegram.Bot.Polling;
|
using Telegram.Bot.Polling;
|
||||||
|
using Telegram.Bot.Types;
|
||||||
using Telegram.Bot.Types.Enums;
|
using Telegram.Bot.Types.Enums;
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using Telegram.Bot.Types.InlineQueryResults;
|
using Telegram.Bot.Types.InlineQueryResults;
|
||||||
|
|
||||||
namespace TG_Bot_Template
|
namespace $safeprojectname$
|
||||||
{
|
{
|
||||||
public class TelegramBotService(IConfiguration conf, ILogger<TelegramBotService> logger) : TelegramBotClient(conf.GetValue<string>("tg-token")), IHostedService
|
public class TelegramBotService(IConfiguration conf, ILogger<TelegramBotService> logger) : TelegramBotClient(conf.GetValue<string>("tg-token")), IHostedService
|
||||||
|
{
|
||||||
|
private static Dictionary<long, string> _userStates = new Dictionary<long, string>();
|
||||||
|
|
||||||
|
// For add any property, u should to add it in StartAsync func, like this:
|
||||||
|
// _PROPERTY_NAME = PROPERTY_NAME_FROM_CLASS
|
||||||
|
|
||||||
|
private static ILogger<TelegramBotService> _logger { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
private static async Task MainHandler(ITelegramBotClient botClient, Update update, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
private static Dictionary<long, string> _userStates = new Dictionary<long, string>();
|
_logger.Log(
|
||||||
|
LogLevel.Information,
|
||||||
// For add any property, u should to add it in StartAsync func, like this:
|
$"Received an update: {update.Type}, Caller ID: {update.Message?.From?.Id ?? update.CallbackQuery?.From.Id ?? update.InlineQuery?.From.Id}"
|
||||||
// _PROPERTY_NAME = PROPERTY_NAME_FROM_CLASS
|
|
||||||
|
|
||||||
private static ILogger<TelegramBotService> _logger { get; set; }
|
|
||||||
|
|
||||||
|
|
||||||
private static async Task MainHandler(ITelegramBotClient botClient, Update update, CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
_logger.Log(
|
|
||||||
LogLevel.Information,
|
|
||||||
$"Received an update: {update.Type}, Caller ID: {update.Message?.From?.Id ?? update.CallbackQuery?.From.Id ?? update.InlineQuery?.From.Id}"
|
|
||||||
);
|
|
||||||
var handler = update switch
|
|
||||||
{
|
|
||||||
|
|
||||||
{ Message: { } message } => HandleUpdateAsync(botClient, message),
|
|
||||||
//{ EditedMessage: { } message } => BotOnMessageReceived(message, cancellationToken),
|
|
||||||
{ CallbackQuery: { } callbackQuery } => QueryUpdateHandler(botClient, callbackQuery),
|
|
||||||
{ InlineQuery: { } inlineQuery } => InlineUpdateHandler(botClient, inlineQuery),
|
|
||||||
//{ ChosenInlineResult: { } chosenInlineResult } => BotOnChosenInlineResultReceived(chosenInlineResult, cancellationToken),
|
|
||||||
_ => Task.CompletedTask
|
|
||||||
};
|
|
||||||
|
|
||||||
await handler;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
private static async Task HandleUpdateAsync(ITelegramBotClient botClient, Message message)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
string messageText = message.Text ?? message.Caption;
|
|
||||||
switch (messageText)
|
|
||||||
{
|
|
||||||
case "/start":
|
|
||||||
await botClient.SendTextMessageAsync(message.From.Id, "Start");
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_logger.LogError($"{ex.Message}");
|
|
||||||
_logger.LogError($"Stack: {ex.StackTrace}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static async Task QueryUpdateHandler(ITelegramBotClient botClient, CallbackQuery callbackQuery)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
string queryData = callbackQuery.Data;
|
|
||||||
switch (queryData)
|
|
||||||
{
|
|
||||||
case "test":
|
|
||||||
await botClient.AnswerCallbackQueryAsync(callbackQuery.Id, "Tested");
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_logger.LogError($"{ex.Message}");
|
|
||||||
_logger.LogError($"Stack: {ex.StackTrace}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static async Task InlineUpdateHandler(ITelegramBotClient botClient, InlineQuery inlineQuery)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
string inlineData = inlineQuery.Query;
|
|
||||||
switch (inlineData)
|
|
||||||
{
|
|
||||||
case "test":
|
|
||||||
await botClient.AnswerInlineQueryAsync(inlineQuery.Id, new InlineQueryResult[] { });
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_logger.LogError($"{ex.Message}");
|
|
||||||
_logger.LogError($"Stack: {ex.StackTrace}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public async Task StartAsync(CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
logger.Log(LogLevel.Information, $"Starting build {this.GetType().Name}");
|
|
||||||
// StartReceiving does not block the caller thread. Receiving is done on the ThreadPool.
|
|
||||||
ReceiverOptions receiverOptions = new()
|
|
||||||
{
|
|
||||||
AllowedUpdates = [UpdateType.Message, UpdateType.CallbackQuery, UpdateType.InlineQuery] // receive all update types except ChatMember related updates
|
|
||||||
};
|
|
||||||
|
|
||||||
_logger = logger;
|
|
||||||
|
|
||||||
this.StartReceiving(
|
|
||||||
updateHandler: MainHandler,
|
|
||||||
pollingErrorHandler: (k, ex, ctx) => {
|
|
||||||
Console.WriteLine(ex.Message);
|
|
||||||
|
|
||||||
return Task.CompletedTask;
|
|
||||||
},
|
|
||||||
receiverOptions: receiverOptions,
|
|
||||||
cancellationToken: cancellationToken
|
|
||||||
);
|
);
|
||||||
var me = await this.GetMeAsync(cancellationToken: cancellationToken);
|
var handler = update switch
|
||||||
logger.Log(LogLevel.Information, $"Start listening bot @{me.Username}");
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task StopAsync(CancellationToken cancellationToken)
|
|
||||||
{
|
{
|
||||||
logger.Log(LogLevel.Information, $"Stopping service");
|
|
||||||
await this.LogOutAsync(cancellationToken);
|
{ Message: { } message } => HandleUpdateAsync(botClient, message),
|
||||||
}
|
//{ EditedMessage: { } message } => BotOnMessageReceived(message, cancellationToken),
|
||||||
|
{ CallbackQuery: { } callbackQuery } => QueryUpdateHandler(botClient, callbackQuery),
|
||||||
|
{ InlineQuery: { } inlineQuery } => InlineUpdateHandler(botClient, inlineQuery),
|
||||||
|
//{ ChosenInlineResult: { } chosenInlineResult } => BotOnChosenInlineResultReceived(chosenInlineResult, cancellationToken),
|
||||||
|
_ => Task.CompletedTask
|
||||||
|
};
|
||||||
|
|
||||||
|
await handler;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
private static async Task HandleUpdateAsync(ITelegramBotClient botClient, Message message)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string messageText = message.Text ?? message.Caption;
|
||||||
|
switch (messageText)
|
||||||
|
{
|
||||||
|
case "/start":
|
||||||
|
await botClient.SendTextMessageAsync(message.From.Id, "Start");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError($"{ex.Message}");
|
||||||
|
_logger.LogError($"Stack: {ex.StackTrace}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task QueryUpdateHandler(ITelegramBotClient botClient, CallbackQuery callbackQuery)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string queryData = callbackQuery.Data;
|
||||||
|
switch (queryData)
|
||||||
|
{
|
||||||
|
case "test":
|
||||||
|
await botClient.AnswerCallbackQueryAsync(callbackQuery.Id, "Tested");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError($"{ex.Message}");
|
||||||
|
_logger.LogError($"Stack: {ex.StackTrace}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task InlineUpdateHandler(ITelegramBotClient botClient, InlineQuery inlineQuery)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string inlineData = inlineQuery.Query;
|
||||||
|
switch (inlineData)
|
||||||
|
{
|
||||||
|
case "test":
|
||||||
|
await botClient.AnswerInlineQueryAsync(inlineQuery.Id, new InlineQueryResult[] { });
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError($"{ex.Message}");
|
||||||
|
_logger.LogError($"Stack: {ex.StackTrace}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public async Task StartAsync(CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
logger.Log(LogLevel.Information, $"Starting build {this.GetType().Name}");
|
||||||
|
// StartReceiving does not block the caller thread. Receiving is done on the ThreadPool.
|
||||||
|
ReceiverOptions receiverOptions = new()
|
||||||
|
{
|
||||||
|
AllowedUpdates = [UpdateType.Message, UpdateType.CallbackQuery, UpdateType.InlineQuery] // receive all update types except ChatMember related updates
|
||||||
|
};
|
||||||
|
|
||||||
|
_logger = logger;
|
||||||
|
|
||||||
|
this.StartReceiving(
|
||||||
|
updateHandler: MainHandler,
|
||||||
|
pollingErrorHandler: (k, ex, ctx) =>
|
||||||
|
{
|
||||||
|
logger.LogError(ex.StackTrace);
|
||||||
|
|
||||||
|
return Task.CompletedTask;
|
||||||
|
},
|
||||||
|
receiverOptions: receiverOptions,
|
||||||
|
cancellationToken: cancellationToken
|
||||||
|
);
|
||||||
|
var me = await this.GetMeAsync(cancellationToken: cancellationToken);
|
||||||
|
logger.Log(LogLevel.Information, $"Start listening bot @{me.Username}");
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task StopAsync(CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
logger.Log(LogLevel.Information, $"Stopping service");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
__TemplateIcon.ico
Normal file
BIN
__TemplateIcon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 43 KiB |
Reference in New Issue
Block a user