Implementing custom keyboard in PHP Telegram bot

I’m having trouble setting up a custom keyboard for my Telegram bot using PHP. When I test the API URL directly in my browser, it works fine:

https://api.telegram.org/mybottoken/sendmessage?chat_id=93119306&text=something&reply_markup={"keyboard":[["Yes","No"],["Maybe"],["1","2","3"]], "one_time_keyboard":true}

But when I try to run this URL in my PHP script, it doesn’t work. Here’s my code:

define('BOT_TOKEN', 'your_bot_token_here');
define('API_URL', 'https://api.telegram.org/bot'.BOT_TOKEN.'/');

$content = file_get_contents("php://input");
$update = json_decode($content, true);
$chatID = $update["message"]["chat"]["id"];
$chatText = $update["message"]["text"];

$reply = generateReply($chatText);

$keyboard = json_encode([
    'keyboard' => [["Agree", "Disagree"], ["Not sure"], ["A", "B", "C"]],
    'one_time_keyboard' => true
]);

$sendto = API_URL."sendmessage?chat_id=".$chatID."&text=".$reply."&reply_markup=".urlencode($keyboard);

file_get_contents($sendto);

function generateReply($text) {
    switch ($text) {
        case "/begin":
            return "Welcome to the bot!";
        case "How are you?":
            return "I'm doing great, thanks for asking!";
        default:
            return "I don't understand that command.";
    }
}

Can anyone spot where I’m going wrong? Thanks in advance for any help!

I’ve grappled with this exact issue in my PHP Telegram bot projects. Your code looks solid, but I suspect the problem lies in how you’re sending the request. Instead of using file_get_contents(), I’ve found that the Telegram Bot API responds much more reliably to cURL requests.

Here’s a snippet that’s worked wonders for me:

$ch = curl_init(API_URL . 'sendMessage');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([
    'chat_id' => $chatID,
    'text' => $reply,
    'reply_markup' => $keyboard
]));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);

This approach has consistently delivered the custom keyboard without a hitch. Give it a shot and see if it resolves your issue. If you’re still running into problems, double-check your bot token and make sure your webhook is set up correctly.

hey alex, i had similar issues. try json_encode() on the entire payload (chat_id, text, reply_markup) and send it via a POST with the proper headers (Content-Type: application/json). hope this fixes it, lmk if u need more help!

I’ve encountered similar issues with custom keyboards in PHP Telegram bots. Your approach is close, but there’s a slight modification that should resolve the problem.

Instead of using file_get_contents() with a URL, try using cURL. It gives you more control over the request and handles complex data structures better. Here’s a snippet that should work:

$ch = curl_init(API_URL . 'sendMessage');
$params = [
    'chat_id' => $chatID,
    'text' => $reply,
    'reply_markup' => $keyboard
];
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
curl_close($ch);

This method sends the keyboard as a proper JSON object, avoiding potential URL encoding issues. Give it a try and let me know if it resolves your problem.