Telegram Bot 收到“错误请求:消息文本为空”

Posted

技术标签:

【中文标题】Telegram Bot 收到“错误请求:消息文本为空”【英文标题】:Telegram Bot gets "Bad Request: message text is empty" 【发布时间】:2018-07-25 14:31:27 【问题描述】:

当我的 Telegram 机器人向 Telegram 服务器发送 sendMessage 时,它​​会收到错误消息:

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

问题出现在今天早上,在此之前我的机器人工作了一整年都没有错误。 GetUpdates 命令和以前一样运行良好。我使用 GET HTTP 方法发送逗号:

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

附加了 UTF-8 编码的数据:

"chat_id":123456789,"text":"any text"

有人遇到过吗?

【问题讨论】:

您的机器人卡在发送空消息的某个状态。不知何故,它不会处理同一 URL 上的任何其他请求,直到该状态发生更改。您是否正在打印一个可能为空的列表?就像我在我的待办事项列表机器人中所做的那样。您可以考虑逐段运行代码,直到找到空的消息打印段。 使用 POST 请求而不是 GET 为我解决了这个问题 【参考方案1】:

就我而言,我使用curl_setopt($this-&gt;curl, CURLOPT_POSTFIELDS, json_encode($fields)); 通过sendMessage 方法发布此json:


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

问题在于,在将字段传递给 curl_setopt 方法时,我正在对整个 php 数组进行编码,所以我只通过编码作为我的 json 一部分的 reply_markup 数组来解决它。

【讨论】:

【参考方案2】:

好吧,我用 C 语言编写了包装器,以通过 SSL 与电报机器人 api 进行通信。所以现在我可以清楚地回答有关电报 API 规范的问题了。

问题一

首先,如果我们谈论的是原始查询,我们需要记住规范。 默认情况下,HTTP/HTTPS 发布请求应包括:

    [space] 您的 POST 正文数据的长度>

所以,我尝试发送不带Content-Length 的原始查询,但我遇到了与您相同的错误。这是第一个问题。

问题二

默认情况下,如果您尝试使用 sendMessage 方法发送无效请求 - 电报机器人 api 将响应与您相同的错误。所以,是的,这是一个非常棘手的调试错误...... 如果您尝试发送原始查询,请确保您的 JSON 数据被很好地序列化并且没有像屏蔽这样的错误。

总结

请求:

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"

第二个反斜杠如果屏蔽。

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;

【讨论】:

【参考方案3】:

如果问题仍然存在,请尝试修改您的 curl 请求。对我来说添加标题 'Content-Type: application/json'-d '"chat_id":12309832,"text":"any text"' 已修复问题

【讨论】:

对我来说它只是标题。 -d ... 是什么东西? 如果您使用 POST,-d 包含 JSON 格式的数据。您可以使用 GET 并将所有数据放入 URL。【参考方案4】:

通过模拟表单发送消息的另一种方式:

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

【讨论】:

这对我有帮助,而在 GET 请求中添加标头却没有,谢谢。【参考方案5】:

我也遇到了这个错误。 我只在“低级”Node https 中使用了sendMessage() 方法:

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();

对于 ASCII 文本没问题,但是对于一些非 ASCII 文本我得到了:

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

错误:

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

在我的情况下,内容长度是用无效长度 'Content-Length': data.length 计算的(对 Telegram 无效?...),所以我注释掉这个标题,现在它适用于 UTF-8

  headers: 
    'Content-Type': 'application/json',
    //'Content-Length': data.length
  

【讨论】:

以上是关于Telegram Bot 收到“错误请求:消息文本为空”的主要内容,如果未能解决你的问题,请参考以下文章

使用python-telegram-bot模块转发telegram机器人消息到钉钉平台

Telegram Bot webhook 真的很慢

Telegram Bot 文件下载突然响应 403

无效的 webhook url 在 Telegram bot 中指定错误

我的 Telegram Bot 无法读取另一个 Telegram Bot 发送的消息

在函数内获取变量更新(Telegram bot、Python3、python-telegram-bot 库、多处理)