将 Qt 中的 setWebhook 用于 Telegram 机器人
Using setWebhook from Qt for a Telegram bot
我正在使用 Qt c++ 开发 Telegram 机器人,但在尝试设置 Webhook 时遇到问题。
SSL 服务器
首先,我使用QTcpServer 和QSslSocket 创建了一个ssl 服务器。关于这个的一些解释可以在 QSslSocket doc. Also, i generated a self-signed certificate as Telegram doc explains here 中找到,使用命令:
openssl req -newkey rsa:2048 -sha256 -nodes -keyout YOURPRIVATE.key -x509 -days 365 -out YOURPUBLIC.pem -subj "/C=US/ST=New York/L=Brooklyn/O=Example Brooklyn Company/CN=YOURDOMAIN.EXAMPLE"
结果是一对文件,一个 private.key 文件和一个 public.pem 文件。所以,我在 QSslSockets 中使用它们来保护连接。
其结果是一个能够侦听和接受连接的 ssl 服务器。当我使用浏览器连接到我的 ssl 服务器时,我收到关于使用 self-signed 证书的警告(我认为这是正常的),但可以连接到服务器。从服务器,我能够读取浏览器发送的数据。所以,我觉得服务器端还是不错的。
请求setWebhook
为了执行 setWebhook API method, i use QHttpMultipart 的请求,class 创建 MIME Multipart 请求。 API 方法需要联系 Url 和 public 证书。因此,我使用此代码生成 url 参数:
QList<QHttpPart> parameters;
QHttpPart urlPart;
urlPart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("text/plain"));
urlPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"url\""));
urlPart.setBody(_url.toLatin1());
parameters.append(urlPart);
以及生成证书参数的代码:
QHttpPart filePath;
filePath.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"certificate\""));
QFile *file = new QFile(_filePath);
file->open(QIODevice::ReadOnly);
filePath.setBodyDevice(file);
file->setParent(this);
parameters.append(filePath);
我收到了正确的回复,消息是 "the webhook was set"。但是,当 Telegram 连接到我的 ssl 服务器时,ssl 握手没有以正确的方式完成(既没有发出 encrypted() 也没有发出 sslError() 信号)。我认为问题是我上传 public 证书的方式。如您所见,对于文件 QHttpPart,我没有设置 content-type header 因为我不知道要使用什么值。我不知道这是否是问题所在。我对 url 使用 "text/plain",但不知道证书文件使用什么。
所以,我不知道我的问题是什么。甚至,我不确定它是否可能是文件上传。使用自签名证书不是问题,因为文档表明这是一种有效的方式。任何帮助将不胜感激。
提前致谢。
终于找到问题了,是content-type。我删除了第一个参数的内容类型,即 urlPart。并且还将内容类型添加到文件路径,作为值 "application/x-x509-ca-cert"。它现在就像一个魅力。
我正在使用 Qt c++ 开发 Telegram 机器人,但在尝试设置 Webhook 时遇到问题。
SSL 服务器
首先,我使用QTcpServer 和QSslSocket 创建了一个ssl 服务器。关于这个的一些解释可以在 QSslSocket doc. Also, i generated a self-signed certificate as Telegram doc explains here 中找到,使用命令:
openssl req -newkey rsa:2048 -sha256 -nodes -keyout YOURPRIVATE.key -x509 -days 365 -out YOURPUBLIC.pem -subj "/C=US/ST=New York/L=Brooklyn/O=Example Brooklyn Company/CN=YOURDOMAIN.EXAMPLE"
结果是一对文件,一个 private.key 文件和一个 public.pem 文件。所以,我在 QSslSockets 中使用它们来保护连接。
其结果是一个能够侦听和接受连接的 ssl 服务器。当我使用浏览器连接到我的 ssl 服务器时,我收到关于使用 self-signed 证书的警告(我认为这是正常的),但可以连接到服务器。从服务器,我能够读取浏览器发送的数据。所以,我觉得服务器端还是不错的。
请求setWebhook
为了执行 setWebhook API method, i use QHttpMultipart 的请求,class 创建 MIME Multipart 请求。 API 方法需要联系 Url 和 public 证书。因此,我使用此代码生成 url 参数:
QList<QHttpPart> parameters;
QHttpPart urlPart;
urlPart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("text/plain"));
urlPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"url\""));
urlPart.setBody(_url.toLatin1());
parameters.append(urlPart);
以及生成证书参数的代码:
QHttpPart filePath;
filePath.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"certificate\""));
QFile *file = new QFile(_filePath);
file->open(QIODevice::ReadOnly);
filePath.setBodyDevice(file);
file->setParent(this);
parameters.append(filePath);
我收到了正确的回复,消息是 "the webhook was set"。但是,当 Telegram 连接到我的 ssl 服务器时,ssl 握手没有以正确的方式完成(既没有发出 encrypted() 也没有发出 sslError() 信号)。我认为问题是我上传 public 证书的方式。如您所见,对于文件 QHttpPart,我没有设置 content-type header 因为我不知道要使用什么值。我不知道这是否是问题所在。我对 url 使用 "text/plain",但不知道证书文件使用什么。
所以,我不知道我的问题是什么。甚至,我不确定它是否可能是文件上传。使用自签名证书不是问题,因为文档表明这是一种有效的方式。任何帮助将不胜感激。
提前致谢。
终于找到问题了,是content-type。我删除了第一个参数的内容类型,即 urlPart。并且还将内容类型添加到文件路径,作为值 "application/x-x509-ca-cert"。它现在就像一个魅力。