コード例 #1
0
 /// <summary>
 /// Informs a user that some of the Telegram Passport elements they provided contains errors. The user will
 /// not be able to re-submit their Passport to you until the errors are fixed (the contents of the field for
 /// which you returned the error must change). Returns True on success.
 /// Use this if the data submitted by the user doesn't satisfy the standards your service requires for
 /// any reason. For example, if a birthday date seems invalid, a submitted document is blurry, a scan shows
 /// evidence of tampering, etc. Supply some details in the error message to make sure the user knows how to
 /// correct the issues.
 /// </summary>
 /// <param name="botClient">Instance of bot client</param>
 /// <param name="userId">User identifier</param>
 /// <param name="errors">Descriptions of the errors</param>
 /// <param name="cancellationToken">The cancellation token to cancel operation.</param>
 /// <see href="https://core.telegram.org/bots/api#setpassportdataerrors"/>
 public static Task SetPassportDataErrorsAsync(
     this ITelegramBotClient botClient,
     int userId,
     IEnumerable <PassportElementError> errors,
     CancellationToken cancellationToken = default
     ) =>
 botClient.MakeRequestAsync(new SetPassportDataErrorsRequest(userId, errors), cancellationToken);
コード例 #2
0
        private async Task <Update[]> GetUpdatesAsync(IEnumerable <UpdateType> allowedUpdates, int offset, CancellationToken cancellation = default)
        {
            var timeout = (int)_client.Timeout.TotalSeconds;

            return(await _client.MakeRequestAsync(new GetUpdatesRequest
            {
                Offset = offset,
                Timeout = timeout,
                AllowedUpdates = allowedUpdates,
            }, cancellation));
        }
        /// <summary>
        /// Starts receiving <see cref="Update"/>s on the ThreadPool, invoking <see cref="IUpdateHandler.HandleUpdate(ITelegramBotClient, Update, CancellationToken)"/> for each.
        /// <para>This method will block if awaited. GetUpdates will be called AFTER the <see cref="IUpdateHandler.HandleUpdate(ITelegramBotClient, Update, CancellationToken)"/> returns</para>
        /// </summary>
        /// <param name="botClient">The <see cref="ITelegramBotClient"/> used for making GetUpdates calls</param>
        /// <param name="updateHandler">The <see cref="IUpdateHandler"/> used for processing <see cref="Update"/>s</param>
        /// <param name="cancellationToken">The <see cref="CancellationToken"/> with which you can stop receiving</param>
        /// <returns></returns>
        public static async Task ReceiveAsync(
            this ITelegramBotClient botClient,
            IUpdateHandler updateHandler,
            CancellationToken cancellationToken = default)
        {
            if (botClient == null)
            {
                throw new ArgumentNullException(nameof(botClient));
            }

            if (updateHandler == null)
            {
                throw new ArgumentNullException(nameof(updateHandler));
            }

            UpdateType[]? allowedUpdates = updateHandler.AllowedUpdates;
            int messageOffset = 0;
            var emptyUpdates  = new Update[] { };

            while (!cancellationToken.IsCancellationRequested)
            {
                int timeout = (int)botClient.Timeout.TotalSeconds;
                var updates = emptyUpdates;
                try
                {
                    updates = await botClient.MakeRequestAsync(new GetUpdatesRequest()
                    {
                        Offset         = messageOffset,
                        Timeout        = timeout,
                        AllowedUpdates = allowedUpdates,
                    }, cancellationToken).ConfigureAwait(false);
                }
                catch (OperationCanceledException)
                {
                    // Ignore
                }
                catch (Exception ex)
                {
                    await updateHandler.HandleError(botClient, ex, cancellationToken)
                    .ConfigureAwait(false);
                }

                foreach (var update in updates)
                {
                    await updateHandler.HandleUpdate(botClient, update, cancellationToken)
                    .ConfigureAwait(false);

                    messageOffset = update.Id + 1;
                }
            }
        }
コード例 #4
0
 /// <summary>Send a request to the Bot API with retry policy in case if the request being timed out</summary>
 /// <typeparam name="TResponse">Type of expected result in the response object</typeparam>
 /// <param name="client">Bot client instance</param>
 /// <param name="request">API request object</param>
 /// <param name="cancellationToken"></param>
 /// <returns>Result of the API request</returns>
 public static Task <TResponse> MakeRequestWithRetryAsync <TResponse>(
     this ITelegramBotClient client,
     IRequest <TResponse> request,
     CancellationToken cancellationToken = default
     ) =>
 Policy
 .Handle <ApiRequestException>(exception => exception.Message == "Request timed out")
 .WaitAndRetryAsync(
     new[]
 {
     TimeSpan.FromSeconds(10),
     TimeSpan.FromSeconds(25),
     TimeSpan.FromSeconds(30),
 }
     )
 .ExecuteAsync(_ => client.MakeRequestAsync(request, cancellationToken), cancellationToken);
コード例 #5
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="client"></param>
 /// <param name="inlineMessageId"></param>
 /// <param name="text"></param>
 /// <param name="parseMode"></param>
 /// <param name="disableWebPagePreview"></param>
 /// <param name="replyMarkup"></param>
 /// <param name="entities"></param>
 /// <param name="cancellationToken"></param>
 /// <returns></returns>
 public static Task EditMessageTextV2Async(
     this ITelegramBotClient client,
     string inlineMessageId,
     string text,
     ParseMode parseMode                 = default,
     bool disableWebPagePreview          = default,
     InlineKeyboardMarkup replyMarkup    = default,
     MessageEntity[] entities            = default,
     CancellationToken cancellationToken = default
     ) =>
 client.MakeRequestAsync(new SbEditInlineMessageTextRequest(inlineMessageId, text)
 {
     DisableWebPagePreview = disableWebPagePreview,
     ReplyMarkup           = replyMarkup,
     ParseMode             = parseMode,
     Entities = entities
 }, cancellationToken);
コード例 #6
0
    /// <summary>
    /// Will attempt to throw the last update using offset set to -1.
    /// </summary>
    /// <param name="botClient"></param>
    /// <param name="cancellationToken"></param>
    /// <returns>
    /// Update ID of the last <see cref="Update"/> increased by 1 if there were any
    /// </returns>
    internal static async Task <int> ThrowOutPendingUpdatesAsync(
        this ITelegramBotClient botClient,
        CancellationToken cancellationToken = default)
    {
        var request = new GetUpdatesRequest
        {
            Limit          = 1,
            Offset         = -1,
            Timeout        = 0,
            AllowedUpdates = Array.Empty <UpdateType>(),
        };
        var updates = await botClient.MakeRequestAsync(request : request, cancellationToken : cancellationToken)
                      .ConfigureAwait(false);

#if NETCOREAPP3_1_OR_GREATER
        if (updates.Length > 0)
        {
            return(updates[^ 1].Id + 1);
        /// <summary>
        /// Yields <see cref="Update"/>s as they are received (or inside <see cref="PendingUpdates"/>).
        /// <para>GetUpdates will be called AFTER all the <see cref="Update"/>s are processed</para>
        /// </summary>
        /// <returns>An <see cref="IAsyncEnumerable{T}"/> of <see cref="Update"/></returns>
        public async IAsyncEnumerable <Update> YieldUpdatesAsync()
        {
            // Access to YieldUpdatesAsync is not thread-safe!

            while (!_cancellationToken.IsCancellationRequested)
            {
                while (_updateIndex < _updateArray.Length)
                {
                    // It is vital that we increment before yielding
                    _updateIndex++;
                    yield return(_updateArray[_updateIndex - 1]);
                }

                _updateArray = EmptyUpdates;
                _updateIndex = 0;

                while (!_cancellationToken.IsCancellationRequested && _updateArray.Length == 0)
                {
                    int timeout = (int)BotClient.Timeout.TotalSeconds;
                    try
                    {
                        _updateArray = await BotClient.MakeRequestAsync(new GetUpdatesRequest()
                        {
                            Offset         = _messageOffset,
                            Timeout        = timeout,
                            AllowedUpdates = _allowedUpdates,
                        }, _cancellationToken).ConfigureAwait(false);
                    }
                    catch (OperationCanceledException)
                    {
                        // Ignore
                    }
                    catch (Exception ex)
                    {
                        if (errorHandler != null)
                        {
                            await errorHandler(ex, _cancellationToken).ConfigureAwait(false);
                        }
                    }
                }

                if (_updateArray.Length > 0)
                {
                    _messageOffset = _updateArray[^ 1].Id + 1;
コード例 #8
0
 /// <summary>
 /// Use this method to send text messages. On success, the sent Description is returned.
 /// </summary>
 /// <param name="chatId"><see cref="ChatId"/> for the target chat</param>
 /// <param name="text">Text of the message to be sent</param>
 /// <param name="parseMode">Change, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your bot's message.</param>
 /// <param name="disableWebPagePreview">Disables link previews for links in this message</param>
 /// <param name="disableNotification">Sends the message silently. iOS users will not receive a notification, Android users will receive a notification with no sound.</param>
 /// <param name="replyToMessageId">If the message is a reply, ID of the original message</param>
 /// <param name="replyMarkup">Additional interface options. A JSON-serialized object for a custom reply keyboard, instructions to hide keyboard or to force a reply from the user.</param>
 /// <param name="entities">Optional. For text messages, special entities like usernames, URLs, bot commands, etc. that appear in the text.</param>
 /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
 /// <returns>On success, the sent Description is returned.</returns>
 /// <see href="https://core.telegram.org/bots/api#sendmessage"/>
 public static Task <Message> SendTextMessageV2Async(
     this ITelegramBotClient client,
     ChatId chatId,
     string text,
     ParseMode parseMode                 = default,
     bool disableWebPagePreview          = default,
     bool disableNotification            = default,
     int replyToMessageId                = default,
     IReplyMarkup replyMarkup            = default,
     MessageEntity[] entities            = default,
     CancellationToken cancellationToken = default
     ) =>
 client.MakeRequestAsync(new SbSendMessageRequest(chatId, text)
 {
     ParseMode             = parseMode,
     DisableWebPagePreview = disableWebPagePreview,
     DisableNotification   = disableNotification,
     ReplyToMessageId      = replyToMessageId,
     ReplyMarkup           = replyMarkup,
     Entities = entities
 }, cancellationToken);
コード例 #9
0
        private void StartReceivingInternal(
            UpdateType[]?allowedUpdates = default,
            Func <Exception, CancellationToken, Task>?errorHandler = default,
            CancellationToken cancellationToken = default)
        {
            Debug.Assert(IsReceiving);
            Task.Run(async() =>
            {
                try
                {
                    while (!cancellationToken.IsCancellationRequested)
                    {
                        int timeout = (int)BotClient.Timeout.TotalSeconds;
                        var updates = EmptyUpdates;
                        try
                        {
                            updates = await BotClient.MakeRequestAsync(new GetUpdatesRequest()
                            {
                                Offset         = _messageOffset,
                                Timeout        = timeout,
                                AllowedUpdates = allowedUpdates,
                            }, cancellationToken).ConfigureAwait(false);
                        }
                        catch (OperationCanceledException)
                        {
                            // Ignore
                        }
                        catch (Exception ex)
                        {
                            if (errorHandler != null)
                            {
                                await errorHandler(ex, cancellationToken).ConfigureAwait(false);
                            }
                        }

                        if (updates.Length > 0)
                        {
                            Interlocked.Add(ref _pendingUpdates, updates.Length);
                            _messageOffset = updates[^ 1].Id + 1;
    /// <inheritdoc />
    public async Task ReceiveAsync(
        IUpdateHandler updateHandler,
        CancellationToken cancellationToken = default)
    {
        if (updateHandler is null)
        {
            throw new ArgumentNullException(nameof(updateHandler));
        }

        var allowedUpdates = _receiverOptions?.AllowedUpdates;
        var limit          = _receiverOptions?.Limit ?? default;
        var messageOffset  = _receiverOptions?.Offset ?? 0;
        var emptyUpdates   = EmptyUpdates;

        if (_receiverOptions?.ThrowPendingUpdates is true)
        {
            try
            {
                messageOffset = await _botClient.ThrowOutPendingUpdatesAsync(
                    cancellationToken : cancellationToken
                    );
            }
            catch (OperationCanceledException)
            {
                // ignored
            }
        }

        while (!cancellationToken.IsCancellationRequested)
        {
            var timeout = (int)_botClient.Timeout.TotalSeconds;
            var updates = emptyUpdates;
            try
            {
                var request = new GetUpdatesRequest
                {
                    Limit          = limit,
                    Offset         = messageOffset,
                    Timeout        = timeout,
                    AllowedUpdates = allowedUpdates,
                };
                updates = await _botClient.MakeRequestAsync(
                    request : request,
                    cancellationToken :
                    cancellationToken
                    ).ConfigureAwait(false);
            }
            catch (OperationCanceledException)
            {
                // Ignore
            }
            catch (Exception exception)
            {
                try
                {
                    await updateHandler.HandleErrorAsync(
                        botClient : _botClient,
                        exception : exception,
                        cancellationToken : cancellationToken
                        ).ConfigureAwait(false);
                }
                catch (OperationCanceledException)
                {
                    // ignored
                }
            }

            foreach (var update in updates)
            {
                try
                {
                    await updateHandler.HandleUpdateAsync(
                        botClient : _botClient,
                        update : update,
                        cancellationToken : cancellationToken
                        ).ConfigureAwait(false);

                    messageOffset = update.Id + 1;
                }
                catch (OperationCanceledException)
                {
                    // ignored
                }
            }
        }
    }
コード例 #11
0
 public Task <TResponse> MakeRequest <TResponse>(IRequest <TResponse> request, CancellationToken cancellationToken = default)
 {
     return(_botClient.MakeRequestAsync(request, cancellationToken));
 }