31

When my Telegram bot sends sendMessage to Telegram server it gets the error message:

{"ok":false,"error_code":400,"description":"Bad Request: message text is empty"}

The problem appeared this morning, before that my bot worked a whole year without errors. GetUpdates command works well as before. I use GET HTTP method to send commads:

https://api.telegram.org/bot<MyToken>/sendMessage

with UTF-8-encoded data attached:

{"chat_id":123456789,"text":"any text"}

Has anyone encountered this?

Kryvich
  • 421
  • 1
  • 4
  • 7
  • Using POST request instead of GET solved the issue for me – Aditya Nov 15 '20 at 05:24
  • Your bot is stuck to some state where it is sending an empty message. Somehow it will not process any other request on the same URL until that state is changed. Are you printing a list which has the possibility of being empty ?, as I did in my to-do list bot. You can consider running segments of your code one by one till you find the empty message printing segment. – Mantahan Srivastava Dec 14 '18 at 14:49

6 Answers6

20

If the issue still persists, try to modify your curl request. For me adding header 'Content-Type: application/json' and -d '{"chat_id":12309832,"text":"any text"}' fixed issue

Drey
  • 369
  • 3
  • 10
9

Another way to send a message by emulating a form :

curl -s -X POST https://api.telegram.org/bot{apitoken}/sendMessage \ -F chat_id='-1234567890' -F text='test message'

ededed
  • 339
  • 3
  • 7
1

Well, i wrote wrapper on C language to communicate via SSL with telegram bot api. SO now I can clearly answer questions about telegram API spec.

Problem number one

First of all if we are talking about raw queries we need to remember about specifications.
By default HTTP/HTTPS post requests should consists of:

  1. <METHOD>[space]<PATH with only valid chars> <\r\n>
  2. <HOST valid regexed\r\n>
  3. <Content-type valid regexed><\r\n>
  4. <Content-Length with length of your POST body data><\r\n>
  5. <\r\n before body>
  6. <body>

So, i tried to send raw queries with out Content-Length and i had error same as yours. That's the first problem.

Problem number two

By default if you trying to send non valid request with sendMessage method - telegram bot api will response with error same as yours. So, yeah, that's pretty tricky error to debug...
If you trying to send raw query, be sure that your JSON data is serialized nicely and there is no errors like shielding.

Summarizing

Request:

POST /bot<token>/sendMessage HTTP/1.1
Host: api.telegram.org:443
Connection: close
Content-Type: application/json
Content-Length: 36

{"chat_id":<integer>, "text":"test \\lol"}

Second backslash if shielding.

Code on C

sprintf(reqeustCtx.request,
            "POST /bot%s/%s HTTP/1.1\r\n"
            "Host: %s\r\n"
            "Connection: close\r\n"
            "Content-Type: application/json\r\n"
            "Content-Length: %d\r\n"
            "\r\n"
            "%s\r\n", bot_token, bot_method,
            reqeustCtx.res_addr, strlen(body), body);
    BIO_puts(bio, reqeustCtx.request);
    BIO_flush(bio);

    memset(reqeustCtx.response, '\0', BUFFSIZE);
    read_bytes = BIO_read(bio, reqeustCtx.response, BUFFSIZE);
    if (read_bytes <= 0) {
        printf("No response");
        exit(-1);
    }

    cert_free(cert_store, ssl_ctx, ca_cert_bio);
    // free memory //
    reqeustCtx.method(reqeustCtx.res_addr, reqeustCtx.request,
                      reqeustCtx.current_work_dir, reqeustCtx.current_cert);

    /* json response, need to parse */
    return reqeustCtx.response;
r1v3n
  • 432
  • 4
  • 9
0

I got this error too. I used sendMessage() method only with "low-level" Node https:

const https = require('https');

const data = JSON.stringify({
  chat_id: config.telegram.chatId,
  text: 'some ASCII text'),
});

const options = {
  hostname: 'api.telegram.org',
  port: 443,
  path: `/bot${config.telegram.botToken}/sendMessage`,
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Content-Length': data.length
  }
};

const req = https.request(options, (res) => {
  let chunks = [];
  res.on('data', chunk => chunks.push(chunk));
  res.on('end', () => {
    const resBody = Buffer.concat(chunks).toString('utf8');
    if (res.statusCode === 200) {
      console.log(`Message sent`);
    } else {
      console.error(`${res.statusCode} ${res.statusMessage} ${res.headers['content-type']}
${resBody}`)
    }
  });
});

req.on('error', (error) => {
  reject(error)
});

req.write(data);
req.end();

And for ASCII text it was ok, however for some non-ASCII text I got:

const data = JSON.stringify({
  chat_id: config.telegram.chatId,
  text: 'Привет Мир!'),
});

Error:

400 Bad Request application/json
{"ok":false,"error_code":400,"description":"Bad Request: message text is empty"}

In my case content length was calculated with invalid length 'Content-Length': data.length (invalid for Telegram?...), so I comment out this header and now it works for UTF-8!

  headers: {
    'Content-Type': 'application/json',
    //'Content-Length': data.length
  }
Alexey Vol
  • 1,723
  • 1
  • 16
  • 20
0

In my case, I was using curl_setopt($this->curl, CURLOPT_POSTFIELDS, json_encode($fields)); to post this json via sendMessage method:

{
   "chat_id":000000000,
   "text":"Choose one of the following options: ",
   "reply_to_message_id":292,
   "reply_markup":{
      "keyboard":[
         [
             "Enable",
             "Disable"
         ]
      ]
   }
}

The problem was that when passing fields to the curl_setopt method, I was encoding the whole php array so I solved it by just encoding the reply_markup array which was a part of my json.

0

Try to put "Message" object with chat_id & text to HttpEntity in your restTemplate service, like below:

public MessageDto sendMessage(Message message) {

    return restTemeplate.exchange(
            "https://api.telegram.org/bot{token}/sendMessage",
            HttpMethod.POST,
            new HttpEntity<>(message, HttpHeaders.EMPTY),
            MessageDto.class
    ).getBody();
}