【问题标题】:Bad Request: message text is empty when sending get request via winapi to telegram bot错误请求:通过 winapi 向电报机器人发送获取请求时消息文本为空
【发布时间】:2022-07-06 06:18:48
【问题描述】:

我正在尝试使用 winapi 和 c++ 从机器人向电报聊天发送消息。 这是我的代码

char szData[1024];

// initialize WinInet
HINTERNET hInternet = ::InternetOpen(TEXT("WinInet Test"), INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
if (hInternet != NULL)
{
    // open HTTP session
    HINTERNET hConnect = ::InternetConnect(hInternet, L"api.telegram.org", INTERNET_DEFAULT_HTTPS_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, NULL, 1);
    if (hConnect != NULL)
    {
        wstring request = L"/bot<bot_id>/sendMessage";

        // open request
        HINTERNET hRequest = ::HttpOpenRequest(hConnect, L"GET", (LPCWSTR)request.c_str(), NULL, NULL, 0, INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_SECURE, 1);
        if (hRequest != NULL)
        {
            // send request
            const wchar_t* params = L"?chat_id=<chat_id>&text=test";
            BOOL isSend = ::HttpSendRequest(hRequest, NULL, 0, (LPVOID)params, wcslen(params));

            if (isSend)
            {
                for (;;)
                {
                    // reading data
                    DWORD dwByteRead;
                    BOOL isRead = ::InternetReadFile(hRequest, szData, sizeof(szData) - 1, &dwByteRead);

                    // break cycle if error or end
                    if (isRead == FALSE || dwByteRead == 0)
                        break;

                    // saving result
                    szData[dwByteRead] = 0;
                }
            }

            // close request
            ::InternetCloseHandle(hRequest);
        }
        // close session
        ::InternetCloseHandle(hConnect);
    }
    // close WinInet
    ::InternetCloseHandle(hInternet);
}

wstring answer = CharPToWstring(szData);

return answer;

但我收到了{"ok":false,"error_code":400,"description":"Bad Request: message text is empty"} 的回复。 &lt;chat_id&gt; 是由数字组成的 id (12345678)。 如果我在邮递员或浏览器中运行此请求 - 那么一切正常。 我也尝试使用WinHttp* 方法运行这个请求,结果是一样的。 我应该更改我的请求参数以使其正常工作?

【问题讨论】:

    标签: c++ winapi telegram-bot


    【解决方案1】:

    这段代码有很多问题:

    • 您不需要将wstring::c_str() 的返回值强制转换为LPCWSTR(又名const wchar_t*),因为它已经是那个类型了。

    • 您不能在 GET 请求中发送正文数据。 Telegram Bot API 期望在 POST 请求中发送正文数据。

    • 您告诉HttpSendRequest()wchar_t* UTF-16 字符串发送正文数据,但这不是服务器期望的正确编码。您需要改用char* UTF-8 字符串。

    • 您没有发送Content-Type 请求标头来告诉服务器正文数据的格式是什么。 API 支持几种不同的格式。在这种情况下,由于您以application/x-www-form-urlencoded 格式发送数据,因此您需要在请求中添加Content-Type: application/x-www-form-urlencoded 标头。

    说了这么多,试试这个吧:

    // initialize WinInet
    HINTERNET hInternet = ::InternetOpenW(L"WinInet Test", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
    if (hInternet == NULL) ... // error handling
    
    // open HTTP session
    HINTERNET hConnect = ::InternetConnectW(hInternet, L"api.telegram.org", INTERNET_DEFAULT_HTTPS_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, NULL, 1);
    if (hConnect == NULL) ... // error handling
    
    // open request
    wstring wsResource = L"/bot<bot_id>/sendMessage";
    HINTERNET hRequest = ::HttpOpenRequestW(hConnect, L"POST", wsResource.c_str(), NULL, NULL, 0, INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_SECURE, 1);
    if (hRequest == NULL) ... // error handling
    
    // send request
    string sBody = u8"chat_id=<chat_id>&text=test";
    BOOL isSend = ::HttpSendRequestW(hRequest, L"Content-Type: application/x-www-form-urlencoded", -1L, sBody.c_str(), sBody.size());
    if (!isSend) ... // error handling
    
    string sReply;
    char szData[1024];
    DWORD dwByteRead;
    
    while (::InternetReadFile(hRequest, szData, sizeof(szData), &dwByteRead) && dwByteRead != 0)
    {
        // saving result
        sReply.append(szData, dwByteRead);
    }
    
    ...
    
    // use sReply as needed ...
    

    【讨论】:

      猜你喜欢
      • 2018-08-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-03
      • 1970-01-01
      • 2020-08-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多