Telegram Bot custom keyboard in C#
Asked Answered
R

4

10

I tried to create message with custom keyboard. So I send request with

reply_markup = {"keyboard":[["1"],["2"]],"resize_keyboard":"True","one_time_keyboard":"True"}

But, it does not work.

I tried all of Content-Types:

  1. application/x-www-form-urlencoded (create message with default keyboard)
  2. application/json (create message with default keyboard)
  3. multipart/form-data (does not work at all, inspite of this Post)

I also tried to send message by 2 different ways. What's the wrong with this code?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Net;

namespace DutyReminder
{
class Program
{
    static void Main(string[] args)
    {

        string message = "message";
        string message1 = "message1";
        string botid = "165749848:AAGtjn42bajF-WxdKosTF07sLwJPYlqiDZE";
        string chatid = "38651047";

        Sender.send("", "https://api.telegram.org/bot" + botid + "/sendmessage?chat_id=" + chatid + "&text=" + message + "&reply_markup={\"keyboard\":[[\"1\"],[\"2\"]],\"resize_keyboard\":\"True\",\"one_time_keyboard\":\"True\"}");
        Sender.HttpPost("https://api.telegram.org/bot" + botid + "/sendmessage?chat_id=" + chatid + "&text=" + message1 + "&reply_markup={\"keyboard\":[[\"1\"],[\"2\"]],\"resize_keyboard\":\"True\",\"one_time_keyboard\":\"True\"}", "");

    }
}

static class Sender
{
    static public void send(string message, string url)
    {
        // Create a request using a URL that can receive a post. 
        WebRequest request = WebRequest.Create(url);
        // Set the Method property of the request to POST.
        request.Method = "POST";
        // Create POST data and convert it to a byte array.
        //string postData = "{\"value1\":\"" + message + "\"}";
        string postData = message;
        byte[] byteArray = Encoding.UTF8.GetBytes(postData);
        // Set the ContentType property of the WebRequest.
        request.ContentType = "application/x-www-form-urlencoded";
        // Set the ContentLength property of the WebRequest.
        //  request.ContentLength = byteArray.Length;
        // Get the request stream.
        Stream dataStream = request.GetRequestStream();
        // Write the data to the request stream.
        dataStream.Write(byteArray, 0, byteArray.Length);
        // Close the Stream object.
        dataStream.Close();
        // Get the response.
        WebResponse response = request.GetResponse();
        // Display the status.
        Console.WriteLine(((HttpWebResponse)response).StatusDescription);
        // Get the stream containing content returned by the server.
        dataStream = response.GetResponseStream();
        // Open the stream using a StreamReader for easy access.
        StreamReader reader = new StreamReader(dataStream);
        // Read the content.
        string responseFromServer = reader.ReadToEnd();
        // Display the content.
        Console.WriteLine(responseFromServer);
        // Clean up the streams.
        reader.Close();
        dataStream.Close();
        response.Close();
    }


    static public string HttpPost(string URI, string Parameters)
    {
        System.Net.WebRequest req = System.Net.WebRequest.Create(URI);
      //  req.Proxy = new System.Net.WebProxy(ProxyString, true);
        //Add these, as we're doing a POST
        req.ContentType = "application/x-www-form-urlencoded";
        req.Method = "POST";
        //We need to count how many bytes we're sending. Post'ed Faked Forms should be name=value&
        byte[] bytes = System.Text.Encoding.ASCII.GetBytes(Parameters);
        req.ContentLength = bytes.Length;
        System.IO.Stream os = req.GetRequestStream();
        os.Write(bytes, 0, bytes.Length); //Push it out there
        os.Close();
        System.Net.WebResponse resp = req.GetResponse();
        if (resp == null) return null;
        System.IO.StreamReader sr = new System.IO.StreamReader(resp.GetResponseStream());
        return sr.ReadToEnd().Trim();
    }

}
}
Rotenone answered 20/1, 2016 at 12:5 Comment(5)
What error do you get? May be you should add try-catch-Blocks to your code to get a detailed error message.Kropotkin
There are no errors, but there is no custom keyboard also f6.s.qip.ru/echeMYh9.png Is seems that telegram ignore reply_markup parameter.Rotenone
So what response do you get? I think, the first question is, is there a communication problem or a command problem.Kropotkin
I get response: {"ok":true,"result":{"message_id":65,"from":{"id":165749848,"first_name":"Duty","username":"DutyBot"},"chat":{"id":38651047,"first_name":"\u0413\u0440\u0438\u0448\u0430","type":"private"},"date":1453290235,"text":"message1"}} If is will use request.ContentType = "multipart/form-data" as recomended here there will be no message sended and i will recieve nothing.Rotenone
I found out the solution fof the problem. I should use "resize_keyboard\":\"true\" instead of resize_keyboard\":\"True\".Rotenone
A
9

Use the following instead of URI message sending:

var bot = new Api("YourApiToken");
.
.
.

var rmu = new ReplyKeyboardMarkup();

rmu.Keyboard =
    new string[][]
    {
        new string[] {"1-1", "1-2"},
        new string[] {"2"},
        new string[] {"3-1", "3-2" , "3-3" }
    };

await bot.SendTextMessage(update.Message.Chat.Id, msg, false, 0, rmu);


UPDATED
With the newer version of API:

var bot = new Api("YourApiToken");
.
.
.

var rkm = new ReplyKeyboardMarkup();

rkm.Keyboard = 
    new KeyboardButton[][]
    {
        new KeyboardButton[]
        {
            new KeyboardButton("1-1"),
            new KeyboardButton("1-2")
        },

        new KeyboardButton[]
        {
            new KeyboardButton("2")
        },

        new KeyboardButton[]
        {
            new KeyboardButton("3-1"),
            new KeyboardButton("3-2"),
            new KeyboardButton("3-3")
        }
    };

await bot.SendTextMessage(update.Message.Chat.Id, msg, false, false, 0, rkm );
Armpit answered 26/5, 2016 at 13:27 Comment(2)
@Grisha, Just in Nuget Type Install-Package Telegram.BotArmpit
@SiyavashHamdi : #39885461Gendarmerie
E
3

You can dynamicly create keyboard.

var rkm = new ReplyKeyboardMarkup();
var rows = new List<KeyboardButton[]>();
var cols = new List<KeyboardButton>();
for (var Index = 1; Index < 17; Index++)
{
    cols.Add(new KeyboardButton("" + Index));
    if (Index%4 != 0) continue;
    rows.Add(cols.ToArray());
    cols = new List<KeyboardButton>();
}
rkm.Keyboard = rows.ToArray();


await botClient.SendTextMessageAsync(
    message.Chat.Id,
    "Choose",
    replyMarkup: rkm);

enter image description here

Eolithic answered 19/3, 2018 at 13:39 Comment(0)
C
0

I did it my way :)

public static class KeyboardHelper
{
        public static ReplyKeyboardMarkup GetKeyboard(List<string> keys)
        {
            var rkm = new ReplyKeyboardMarkup();
            var rows = new List<KeyboardButton[]>();
            var cols = new List<KeyboardButton>();
            foreach (var t in keys)
            {
                cols.Add(new KeyboardButton(t));
                rows.Add(cols.ToArray());
                cols = new List<KeyboardButton>();
            }
            rkm.Keyboard = rows.ToArray();
            return rkm;
        }
}
Chemise answered 20/3, 2019 at 11:38 Comment(0)
C
0
List<string> items = new List<string>();

items.Add("A");
items.Add("B");
items.Add("C");
items.Add("D");
items.Add("E");                               
                                  

var rkm = new ReplyKeyboardMarkup();
var rows = new List<KeyboardButton[]>();
var cols = new List<KeyboardButton>();   
for (var Index = 1; Index < items.Count+1; Index++)
{
   cols.Add(new KeyboardButton("" + items[Index-1]));
   if (Index % 4 != 0) continue;
   rows.Add(cols.ToArray());
   cols = new List<KeyboardButton>();

}
    
if (cols.Count > 0) {rows.Add(cols.ToArray());}

rkm.Keyboard = rows.ToArray();
await Bot.SendTextMessageAsync(message.Chat.Id,"Choose",replyMarkup: rkm);
Cyril answered 9/12, 2020 at 1:35 Comment(1)
While this might answer the question, if possible you should edit your answer to include an explanation of how this code block answers the question. This helps to provide context and makes your answer much more useful for future readers.Gates

© 2022 - 2024 — McMap. All rights reserved.