Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't wait for user input #470

Closed
wiscount opened this issue Jul 18, 2023 · 1 comment
Closed

Can't wait for user input #470

wiscount opened this issue Jul 18, 2023 · 1 comment

Comments

@wiscount
Copy link

In earlier versions (v17) waiting input from user was possible with this method.

 public static async Task<string> WaitForReplyAsync(this TelegramBotClient botClient, long chatId, TimeSpan? timeout = null)
        {
            if (timeout == null)
                timeout = TimeSpan.FromSeconds(30);
            var tcs = new TaskCompletionSource<string>();

            void OnMessageReceived(object sender, MessageEventArgs e)
            {
                if (e.Message.Chat.Id == chatId && e.Message.Type == MessageType.Text)
                {
                    botClient.OnMessage -= OnMessageReceived;
                    tcs.TrySetResult(e.Message.Text);
                    // Remove message from chat
                    GLB.bot.DeleteMessageAsync(chatId, e.Message.MessageId);
                }
            }

            botClient.OnMessage += OnMessageReceived;

            var timeoutTask = Task.Delay(timeout.Value);
            var completedTask = await Task.WhenAny(tcs.Task, timeoutTask);

            if (completedTask == timeoutTask)
            {
                botClient.OnMessage -= OnMessageReceived;
                return null;
            }

            return await tcs.Task;
        }

I also made WaitForKeyboard event that waits for markup event.

  public static async Task<string> WaitForKeyboard(this TelegramBotClient client, long chatId)
        {

            var tcs = new TaskCompletionSource<string>();

            void OnCallbackQueryReceived(object sender, CallbackQueryEventArgs e)
            {
                if (e.CallbackQuery.Message.Chat.Id == chatId)
                {
                    client.OnCallbackQuery -= OnCallbackQueryReceived;
                    tcs.TrySetResult(e.CallbackQuery.Data);
                }
            }

            client.OnCallbackQuery += OnCallbackQueryReceived;

            var timeoutTask = Task.Delay(TimeSpan.FromSeconds(30));
            var completedTask = await Task.WhenAny(tcs.Task, timeoutTask);

            if (completedTask == timeoutTask)
            {
                client.OnCallbackQuery -= OnCallbackQueryReceived;
                return null;
            }

            return await tcs.Task;
        }

It basically binds new handler to OnMessage event and filtering the sender.id to know whether message sent from correct user.

In new versions there are no OnMessage event, the only event we can use is OnApiResponseReceived which is pretty useless and non-sense (useless thing ever) binding extra handler to this event won't work as handler won't contain anything related about message/chat.

@karb0f0s
Copy link
Member

I believe that what you described is generally known as a "callback hell". This kind of application logic often results in bugs and leaks due to incorrect use of events.
In general, you should use a state machine pattern to keep track for the conversation.
Alternatively, you can use one of the frameworks, based on Telegram.Bot library.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants