Coder Social home page Coder Social logo

telegrambots / telegram.bot.extensions.polling Goto Github PK

View Code? Open in Web Editor NEW
45.0 11.0 12.0 156 KB

Provides ITelegramBotClient extensions for polling updates

License: MIT License

C# 100.00%
telegram telegram-bot telegram-bot-api update-polling

telegram.bot.extensions.polling's Introduction

โš ๏ธ This package is no longer maintained since all it's functionality has been merged into Telegram.Bot starting from v18.


Telegram.Bot.Extensions.Polling

Provides ITelegramBotClient extensions for polling updates.

Usage

using System;
using System.Threading;
using Telegram.Bot;
using Telegram.Bot.Exceptions;
using Telegram.Bot.Types;
using Telegram.Bot.Extensions.Polling;

async Task HandleUpdateAsync(ITelegramBotClient botClient, Update update, CancellationToken cancellationToken)
{
    if (update.Message is Message message)
    {
        await botClient.SendTextMessageAsync(message.Chat, "Hello");
    }
}

async Task HandleErrorAsync(ITelegramBotClient botClient, Exception exception, CancellationToken cancellationToken)
{
    if (exception is ApiRequestException apiRequestException)
    {
        await botClient.SendTextMessageAsync(123, apiRequestException.ToString());
    }
}

ITelegramBotClient bot = new TelegramBotClient("<token>");

You have two ways of starting to receive updates

  1. StartReceiving does not block the caller thread. Receiving is done on the ThreadPool.

    using System.Threading;
    using Telegram.Bot.Extensions.Polling;
    
    var cts = new CancellationTokenSource();
    var cancellationToken = cts.Token;
    var receiverOptions = new ReceiverOptions
    {
        AllowedUpdates = {} // receive all update types
    };
    bot.StartReceiving(
        HandleUpdateAsync,
        HandleErrorAsync,
        receiverOptions,
        cancellationToken
    );
  2. Awaiting ReceiveAsync will block until cancellation in triggered (both methods accept a CancellationToken)

    using System.Threading;
    using Telegram.Bot.Extensions.Polling;
    
    var cts = new CancellationTokenSource();
    var cancellationToken = cts.Token;
    
    var receiverOptions = new ReceiverOptions
    {
        AllowedUpdates = {} // receive all update types
    };
    
    try
    {
        await bot.ReceiveAsync(
            HandleUpdateAsync,
            HandleErrorAsync,
            receiverOptions,
            cancellationToken
        );
    }
    catch (OperationCancelledException exception)
    {
    }

Trigger cancellation by calling cts.Cancel() somewhere to stop receiving update in both methods.


In case you want to throw out all pending updates on start there is an option ReceiveOptions.ThrowPendingUpdates. If set to true ReceiveOptions.Offset property will be ignored even if it's set to non-null value and all implemented update receivers will attempt to throw out all pending updates before starting to call your handlers. In that case ReceiveOptions.AllowedUpdates property should be set to desired values otherwise it will be effectively set to allow all updates.

Example

using System.Threading;
using Telegram.Bot.Extensions.Polling;
using Telegram.Bot.Types.Enums;

var cts = new CancellationTokenSource();
var cancellationToken = cts.Token;

var receiverOptions = new ReceiverOptions
{
    AllowedUpdates = new { UpdateType.Message, UpdateType.CallbackQuery }
    ThrowPendingUpdates = true
};

try
{
    await bot.ReceiveAsync(
        HandleUpdateAsync,
        HandleErrorAsync,
        receiverOptions,
        cancellationToken
   );
}
catch (OperationCancelledException exception)
{
}

Update streams

With .Net Core 3.1+ comes support for an IAsyncEnumerable<Update> to stream Updates as they are received.

There are two implementations:

  • BlockingUpdateReceiver blocks execution on every new getUpdates request
  • QueuedUpdateReceiver enqueues updates in an internal queue in a background process to make Update interation faster so you don't have to wait on getUpdates requests to finish

Example:

using Telegram.Bot;
using Telegram.Bot.Types;
using Telegram.Bot.Extensions.Polling;

var bot = new TelegramBotClient("<token>");
var receiverOptions = new ReceiverOptions
{
    AllowedUpdates = {} // receive all update types
};
var updateReceiver = new QueuedUpdateReceiver(bot, receiverOptions);

// to cancel
var cts = new CancellationTokenSource();

try
{
    await foreach (Update update in updateReceiver.WithCancellation(cts.Token))
   {
       if (update.Message is Message message)
       {
           await bot.SendTextMessageAsync(
               message.Chat,
               $"Still have to process {updateReceiver.PendingUpdates} updates"
           );
       }
   }
}
catch (OperationCanceledException exception)
{
}

telegram.bot.extensions.polling's People

Contributors

karb0f0s avatar mihazupan avatar peterbozso avatar tuscen avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

telegram.bot.extensions.polling's Issues

Add client parameter to IUpdateHandler

I think it's a good idea to add ITelegramBotClient as the first parameter in IUpdateHandler.HandleUpdate. This way you don't need to capture a reference to the client with DefaultUpdateHandler.

It will break the interface, but it's fine since the library is still effectively in preview.

Update Streams are not supported in QueuedUpdateReceiver

CS8411
Asynchronous foreach statement cannot operate on variables of type 'QueuedUpdateReceiver'
because 'QueuedUpdateReceiver' does not contain a suitable public instance or extension definition 
for 'GetAsyncEnumerator'

I get this error when I try to use update streams as shown in an example in README.md

My project runs .NET 5, package version is latest atm (0.2.0)

Handling Concurrency Conflicts

Hi everyone. I have one problem with Handling Concurrency Conflicts.
I have two project and they work parallel but i have that error:

Microsoft.EntityFrameworkCore.DbUpdateConcurrencyException: Database operation expected to affect 1 row(s) but actually affected 0 row(s). Data may have been modified or deleted since entities were loaded.

How can i solve this problem?

ReceiverOptions parameter name mismatch

Add cancellation token to YieldUpdatesAsync

Current implementation doesn't allow the following common pattern:

await foreach (var update in receiver.YieldUpdatesAsync().WithCancellation(cancellationToken))
{
    // ... 
}

To allow this to work YieldUpdatesAsync needs to have cancellation token as a parameter with an attribute:

public interface IYieldingUpdateReceiver
{
    int PendingUpdates { get; }
    IAsyncEnumerable<Update> YieldUpdatesAsync([EnumeratorCancellation] CancellationToken cancellationToken = default);
}

This will allow uniform cancellation support in IYieldingUpdateReceiver implementations instead of ad-hoc params in different implementations.

what is ReceiveOptions?

Hey,

maybe it will be obvious, but just following your Readme compile tells me that ReceiveOptions does not exist in the current context without any resolution. Can you please advise?

Connection to database

I have a problem when I try connect to database with telegramBot:

System.ObjectDisposedException: Cannot access a disposed context instance. A common cause of this error is disposing a context instance that was resolved from dependency injection and then later trying to use the same context instance elsewhere in your application. This may occur if you are calling 'Dispose' on the context instance, or wrapping it in a using statement. If you are using dependency injection, you should let the dependency injection container take care of disposing context instances.
Object name: 'ApplicationContext'.

ThrowOutPendingUpdatesAsync should have 0 timeout

ThrowOutPendingUpdatesAsync should have 0 timeout to receive and skip only existing updates. Now it'll wait for a few seconds if there are no pending updates and could skip new updates:

var timeout = (int) botClient.Timeout.TotalSeconds;
var request = new GetUpdatesRequest
{
Limit = 1,
Offset = -1,
Timeout = timeout,
AllowedUpdates = Array.Empty<UpdateType>(),
};
var updates = await botClient.MakeRequestAsync(request: request, cancellationToken: cancellationToken)
.ConfigureAwait(false);

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.