2

For days I've been trying to solve this problem with my Telegram Bot.

I'm trying to send the user some questions after he "/start"s the bot.

I want to capture all user answers and then send it to some user that I want to see user answers in one message.

I tried to do it by sending inline buttons and couldn't find the way to wait for the next message from the user. I tried to store the answers in a string array, and it doesn't work either.

And at the end of the question, I want to send all user answers to some userid/channel in one message with all user questions.

I use Telegram.Bot library.

Here is my code

static string gotName = "0";
static string gotAge = "0";
static string gotMessage = "0";

static string[] Forminfo = { gotName, gotAge, gotMessage };


 async  private void Bot_OnUpdate(object sender, Telegram.Bot.Args.UpdateEventArgs e)
{
    if (e.Update.Type == UpdateType.Message && e.Update.Message.Text == "/start")
    {
        var streg = new InlineKeyboardMarkup(new[]
        {
            new [] // first row
            {
                InlineKeyboardButton.WithCallbackData("Next Step","start")
            }
        });

        var update = e.Update.Message.Text;

        var strmsg = "To Start The Register please send the bot your name and click on Next Step";
        await bot.SendTextMessageAsync(e.Update.Message.Chat.Id, strmsg, ParseMode.Html, replyMarkup: streg);
        var usermsg = await bot.GetUpdatesAsync();
        Forminfo[0] = usermsg.ToString();
    }
}


async private void Bot_OnCallbackQuery(object sender, Telegram.Bot.Args.CallbackQueryEventArgs e)
{            
    var streg1 = new InlineKeyboardMarkup(new[]
    {
        new [] // first row
        {
            InlineKeyboardButton.WithCallbackData("Next","start1")
        }
    });

    if (Forminfo[0] != "0")
    {
        var startedmsg = "Hello " + Forminfo[0].ToString() + "\n" +
                "Please Send us your Age and click Next";
        try
        {
            await bot.SendTextMessageAsync(e.CallbackQuery.Message.Chat.Id, startedmsg, ParseMode.Html, replyMarkup: streg1);
        }
        catch(HttpRequestException ex)
        {
            await bot.SendTextMessageAsync(e.CallbackQuery.Message.Chat.Id, "To Many Request Please Try Later.", ParseMode.Html);
        }
    }
}
Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
tuarek
  • 69
  • 1
  • 8

1 Answers1

1

There are a couple things to fix:

  • If all you are handling inside your OnUpdate callback are messages, use OnMessage instead
  • You are using OnUpdate and then manually call GetUpdates. You can't mix multiple approaches of getting updates - the StartReceiving call already handles calling GetUpdates internally.
  • By having one string[] as the result, you are assuming only one user will use the bot at the same time. A better approach would be to use a Dictionary<userId, result>.
  • In your SendTextMessageAsync call, you don't have to set ParseMode if you are sending regular text
  • I don't see what you are using the buttons for if you're never checking whether the user clicked them

This is a code example that does what you want, but does not validate the input at all:

const long TargetChannelId = 123456;
static readonly ConcurrentDictionary<int, string[]> Answers = new ConcurrentDictionary<int, string[]>();
private static async void Bot_OnMessage(object sender, MessageEventArgs e)
{
    Message message = e.Message;
    int userId = message.From.Id;

    if (message.Type == MessageType.Text)
    {
        if (Answers.TryGetValue(userId, out string[] answers))
        {
            if (answers[0] == null)
            {
                answers[0] = message.Text;
                await Bot.SendTextMessageAsync(message.Chat, "Now send me your age");
            }
            else if (answers[1] == null)
            {
                answers[1] = message.Text;
                await Bot.SendTextMessageAsync(message.Chat, "Now send me your message");
            }
            else
            {
                Answers.TryRemove(userId, out string[] _);
                await Bot.SendTextMessageAsync(message.Chat, "Thank you, that's all I need from you");

                string answersText = $"User {answers[0]}, aged {answers[1]} sent the following message:\n{message.Text}";
                await Bot.SendTextMessageAsync(TargetChannelId, answersText);
            }
        }
        else
        {
            Answers.TryAdd(userId, new string[2]);
            await Bot.SendTextMessageAsync(message.Chat, "Please send me your name");
        }
    }
}
Miha Zupan
  • 104
  • 6
  • and if i want to multiple users to fill this form , if 2 diffrence users trying to fiil the form at the same time , ill recive each user for saprate or the form will be messy/crashed? – tuarek Aug 20 '18 at 20:01
  • @tuarek With this code snippet, virtually any amount of users can interact with the bot at the same time, without corrupting state – Miha Zupan Aug 20 '18 at 20:17