Initial commit: GM-Relay Telegram Bot
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
using Telegram.Bot;
|
||||
using Telegram.Bot.Types;
|
||||
using Telegram.Bot.Types.Enums;
|
||||
|
||||
namespace GmRelay.Bot.Infrastructure.Telegram;
|
||||
|
||||
/// <summary>
|
||||
/// Long polling loop for Telegram Bot API.
|
||||
/// Stateless — all state is in PostgreSQL. Safe to restart at any time.
|
||||
/// </summary>
|
||||
public sealed class TelegramBotService(
|
||||
ITelegramBotClient bot,
|
||||
UpdateRouter router,
|
||||
ILogger<TelegramBotService> logger) : BackgroundService
|
||||
{
|
||||
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
||||
{
|
||||
logger.LogInformation("Telegram bot polling started");
|
||||
|
||||
// Skip any pending updates from before this startup
|
||||
try
|
||||
{
|
||||
var pending = await bot.GetUpdates(offset: -1, limit: 1, cancellationToken: stoppingToken);
|
||||
if (pending.Length > 0)
|
||||
{
|
||||
logger.LogInformation("Skipped {Count} pending update(s)", pending[^1].Id);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.LogWarning(ex, "Failed to clear pending updates, continuing anyway");
|
||||
}
|
||||
|
||||
var offset = 0;
|
||||
|
||||
while (!stoppingToken.IsCancellationRequested)
|
||||
{
|
||||
try
|
||||
{
|
||||
var updates = await bot.GetUpdates(
|
||||
offset: offset,
|
||||
timeout: 30,
|
||||
allowedUpdates: [UpdateType.Message, UpdateType.CallbackQuery],
|
||||
cancellationToken: stoppingToken);
|
||||
|
||||
foreach (var update in updates)
|
||||
{
|
||||
try
|
||||
{
|
||||
await router.RouteAsync(update, stoppingToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.LogError(ex, "Error handling update {UpdateId}", update.Id);
|
||||
}
|
||||
|
||||
offset = update.Id + 1;
|
||||
}
|
||||
}
|
||||
catch (OperationCanceledException) when (stoppingToken.IsCancellationRequested)
|
||||
{
|
||||
break;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.LogError(ex, "Polling error, retrying in 5s");
|
||||
await Task.Delay(TimeSpan.FromSeconds(5), stoppingToken);
|
||||
}
|
||||
}
|
||||
|
||||
logger.LogInformation("Telegram bot polling stopped");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user