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->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 发布请求应包括:
所以,我尝试发送不带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机器人消息到钉钉平台
无效的 webhook url 在 Telegram bot 中指定错误