Использование setWebhook из Qt для бота Telegram
Я занимаюсь разработкой бота Telegram с использованием Qt C++, и у меня возникают проблемы при попытке установить Webhook.
Сервер SSL
Прежде всего, я создал ssl-сервер, используя QTcpServer и QSslSocket. Некоторые пояснения по этому поводу можно найти в документе QSslSocket. Кроме того, я сгенерировал самоподписанный сертификат, как объясняет документ Telegram, используя команду:
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, я получаю предупреждение об использовании самозаверяющего сертификата (что я считаю нормальным), но могу подключиться к серверу. С сервера я могу прочитать данные, отправленные браузером. Итак, я думаю, что серверная сторона хороша.
Запрос на установку WebWook
Чтобы выполнить запрос на метод API setWebhook, я использую класс QHttpMultipart для создания многочастного запроса MIME. Для метода API необходимо связаться с URL и публичным сертификатом. Итак, я использую этот код для генерации параметра 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);
Я получаю правильный ответ с сообщением, что "веб-крючок был установлен". Но когда Telegram подключается к моему серверу ssl, рукопожатие ssl не завершается надлежащим образом (не передаются сигналы encrypted() и sslError()). Я думаю, что проблема в том, как я загружаю публичный сертификат. Как вы видите, для файла QHttpPart я не устанавливаю заголовок типа содержимого, потому что я не знаю, какое значение использовать. Я не знаю, может ли это быть проблемой. Я использую "text/plain" для URL, но не знаю, что использовать для файла сертификата.
Итак, я не знаю, в чем может быть моя проблема. Даже, я не уверен, может ли это быть загрузка файла или нет. Использование самозаверяющего сертификата не является проблемой, поскольку в документации это указано как действительный способ. Любая помощь будет оценена.
Заранее спасибо.
1 ответ
Я наконец нашел проблему, и это был тип контента. Я удалил тип содержимого первого параметра, urlPart. А также добавил тип содержимого в filePath, используя в качестве значения "application/x-x509-ca-cert". Теперь это работает как шарм.