You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改C libcurl代码验证Webhook消息发送状态及JSON错误?

解决Discord Webhook JSON无效错误及请求状态验证

你遇到的错误:

{"code": 50109, "message": "The request body contains invalid JSON."}

核心原因是my_description中的特殊字符(比如双引号、反斜杠)破坏了JSON结构,加上原代码仅检查curl请求是否发送成功,未验证Webhook的业务处理结果。以下是修改后的完整代码:

#include <stdio.h>
#include <curl/curl.h>
#include <string.h>
#include <stdlib.h>

#define nullptr ((void*)0)

// 响应体接收缓冲区
typedef struct {
    char *data;
    size_t size;
} ResponseBuffer;

// curl写回调函数,用于接收响应体
static size_t write_callback(void *contents, size_t size, size_t nmemb, void *userp) {
    size_t realsize = size * nmemb;
    ResponseBuffer *buf = (ResponseBuffer *)userp;

    char *ptr = realloc(buf->data, buf->size + realsize + 1);
    if(!ptr) {
        fprintf(stderr, "内存分配失败\n");
        return 0;
    }

    buf->data = ptr;
    memcpy(&(buf->data[buf->size]), contents, realsize);
    buf->size += realsize;
    buf->data[buf->size] = '\0';

    return realsize;
}

// JSON特殊字符转义函数
void escape_json_string(const char *input, char *output, size_t output_size) {
    if(!input || !output || output_size == 0) return;

    size_t in_idx = 0, out_idx = 0;
    while(input[in_idx] != '\0' && out_idx < output_size - 1) {
        switch(input[in_idx]) {
            case '"':
                if(out_idx + 2 > output_size - 1) break;
                output[out_idx++] = '\\';
                output[out_idx++] = '"';
                break;
            case '\\':
                if(out_idx + 2 > output_size - 1) break;
                output[out_idx++] = '\\';
                output[out_idx++] = '\\';
                break;
            case '\n':
                if(out_idx + 2 > output_size - 1) break;
                output[out_idx++] = '\\';
                output[out_idx++] = 'n';
                break;
            case '\r':
                if(out_idx + 2 > output_size - 1) break;
                output[out_idx++] = '\\';
                output[out_idx++] = 'r';
                break;
            case '\t':
                if(out_idx + 2 > output_size - 1) break;
                output[out_idx++] = '\\';
                output[out_idx++] = 't';
                break;
            default:
                output[out_idx++] = input[in_idx];
                break;
        }
        in_idx++;
    }
    output[out_idx] = '\0';
}

int main() {
    char message[65500];
    int max_len = sizeof(message);
    CURL *curl;
    CURLcode res;
    long http_code = 0;

    char webhook[] = "DISCORD_WEBHOOK";
    char my_description[] = "Description with \"quotes\" and \\backslashes\\";
    char escaped_desc[65500];

    // 转义描述中的JSON特殊字符
    escape_json_string(my_description, escaped_desc, sizeof(escaped_desc));
    // 生成合法的JSON
    snprintf(message, max_len, "{\"username\": \"Test\",\"embeds\":[{\"description\": \"%s\"}]}", escaped_desc);

    // 初始化响应缓冲区
    ResponseBuffer response_buf = {NULL, 0};

    curl = curl_easy_init();
    if(curl) {
        struct curl_slist* headers = nullptr;
        headers = curl_slist_append(headers, "Content-Type: application/json");
        if(!headers) {
            fprintf(stderr, "创建HTTP头失败\n");
            curl_easy_cleanup(curl);
            return 1;
        }

        // 设置curl选项
        curl_easy_setopt(curl, CURLOPT_URL, webhook);
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, message);
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
        // 设置响应体接收回调
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response_buf);
        // 禁止信号处理,避免程序中断
        curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L);

        // 执行请求
        res = curl_easy_perform(curl);

        // 获取HTTP响应码
        curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);

        // 处理请求结果
        if(res != CURLE_OK) {
            fprintf(stderr, "请求发送失败: %s\n", curl_easy_strerror(res));
        } else {
            if(http_code == 200 || http_code == 204) {
                printf("消息发送成功\n");
            } else {
                fprintf(stderr, "Webhook处理失败,HTTP状态码: %ld\n", http_code);
                if(response_buf.data) {
                    fprintf(stderr, "错误详情: %s\n", response_buf.data);
                }
            }
        }

        // 清理资源
        curl_slist_free_all(headers);
        curl_easy_cleanup(curl);
    } else {
        fprintf(stderr, "curl初始化失败\n");
    }

    // 释放响应缓冲区
    if(response_buf.data) {
        free(response_buf.data);
    }

    return 0;
}

关键修改说明:

  • JSON转义:新增escape_json_string函数,处理双引号、反斜杠等特殊字符,确保生成的JSON格式合法,从根源解决50109错误。
  • 响应体捕获:通过write_callback函数收集Webhook返回的响应内容,方便查看具体错误信息。
  • HTTP状态码验证:使用curl_easy_getinfo获取HTTP响应码,Discord Webhook成功时返回200或204,非此状态则判定为业务错误。
  • 完善错误处理:区分curl请求失败(如网络问题)和Webhook业务失败(如JSON无效),分别打印对应的错误信息。
  • 资源清理:确保所有动态分配的资源(如响应缓冲区、curl头列表)都被正确释放,避免内存泄漏。

内容的提问来源于stack exchange,提问作者Moga Onamil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 21:01:07