Skip to content

Instantly share code, notes, and snippets.

@MihaZupan
Last active February 23, 2019 17:24
Show Gist options
  • Save MihaZupan/5776b8bb7dcc46865837e145d5d16535 to your computer and use it in GitHub Desktop.
Save MihaZupan/5776b8bb7dcc46865837e145d5d16535 to your computer and use it in GitHub Desktop.
public static TelegramBotClient Bot;
public static async Task Main()
{
Bot = new TelegramBotClient("");
// Note: HandleExceptionAsync is optional (except on StartReceiving)
// awaitable blocking task
await Bot.ReceiveAsync(HandleUpdateAsync, HandleExceptionAsync);
// doesn't block
Bot.StartReceiving(HandleUpdateAsync, HandleExceptionAsync);
#if NETCOREAPP3_0
// calls GetUpdates after all updates are processed
await foreach (var update in Bot.YieldUpdatesAsync(HandleExceptionAsync))
{
await HandleUpdateAsync(update);
}
// keeps calling GetUpdates and enqueues updates internally, yielding them one by one
// implementation TBD
await foreach (var update in Bot.YieldQueuedUpdatesAsync(HandleExceptionAsync))
{
await HandleUpdateAsync(update);
}
#endif
}
public static async Task HandleUpdateAsync(Update update)
{
if (update.Message is Message message && message.Text is string text)
{
await Bot.SendTextMessageAsync(message.Chat, "Echo:\n" + text);
}
}
public static async Task HandleExceptionAsync(Exception exception)
{
if (exception is ApiRequestException apiRequestException)
{
Console.WriteLine(apiRequestException.ToString());
}
else
{
await Bot.SendTextMessageAsync(123, "Something went wrong:\n" + exception.ToString());
}
}
public static class TelegramBotClientPollingExtensions
{
public static void StartReceiving(
this ITelegramBotClient client,
Func<Update, Task> updateHandler,
Func<Exception, Task> exceptionHandler, // ApiRequestException, GeneralException, AS WELL AS exceptions from updateHandler - in that case stop receiving
UpdateType[]? allowedUpdates = null,
CancellationToken cancellationToken = default)
{
if (exceptionHandler == null)
throw new ArgumentNullException(nameof(exceptionHandler));
Task.Run(async () =>
{
try
{
await ReceiveAsync(client, updateHandler, exceptionHandler, allowedUpdates, cancellationToken);
}
catch (Exception ex)
{
await exceptionHandler(ex);
}
});
}
public static async Task ReceiveAsync(
this ITelegramBotClient client,
Func<Update, Task> updateHandler,
Func<Exception, Task>? exceptionHandler = null, // ApiRequestException, GeneralException
UpdateType[]? allowedUpdates = null,
CancellationToken cancellationToken = default)
{
int messageOffset = 0;
var emptyUpdates = new Update[0];
while (!cancellationToken.IsCancellationRequested)
{
int timeout = (int)client.Timeout.TotalSeconds;
var updates = emptyUpdates;
try
{
updates = await client.GetUpdatesAsync(
messageOffset,
timeout: timeout,
allowedUpdates: allowedUpdates,
cancellationToken: cancellationToken
).ConfigureAwait(false);
}
catch (OperationCanceledException)
{
// Ignore
}
catch (Exception ex)
{
if (exceptionHandler != null)
{
await exceptionHandler(ex).ConfigureAwait(false);
}
}
foreach (var update in updates)
{
await updateHandler(update).ConfigureAwait(false);
messageOffset = update.Id + 1;
}
}
}
}
#if NETCOREAPP3_0
public static class TBD_YieldExtensions
{
public static async IAsyncEnumerable<Update> YieldUpdatesAsync(
this ITelegramBotClient client,
Func<Exception, Task>? exceptionHandler = null, // ApiRequestException, GeneralException
UpdateType[]? allowedUpdates = null,
CancellationToken cancellationToken = default)
{
int messageOffset = 0;
var emptyUpdates = new Update[0];
while (!cancellationToken.IsCancellationRequested)
{
int timeout = (int)client.Timeout.TotalSeconds;
var updates = emptyUpdates;
try
{
updates = await client.GetUpdatesAsync(
messageOffset,
timeout: timeout,
allowedUpdates: allowedUpdates,
cancellationToken: cancellationToken
).ConfigureAwait(false);
}
catch (OperationCanceledException)
{
// Ignore
}
catch (Exception ex)
{
if (exceptionHandler != null)
{
await exceptionHandler(ex).ConfigureAwait(false);
}
}
foreach (var update in updates)
{
yield return update;
messageOffset = update.Id + 1;
}
}
}
public static async IAsyncEnumerable<Update> YieldQueuedUpdatesAsync(
this ITelegramBotClient client,
Func<Exception, Task>? exceptionHandler = null, // ApiRequestException, GeneralException
UpdateType[]? allowedUpdates = null,
CancellationToken cancellationToken = default)
{
yield return new Update();
}
}
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment