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

MT5通过WebRequest发送JSON至Discord报错400(无效JSON)求助

解决MT5通过Discord Webhook发送持仓信息的JSON无效问题

问题描述

运行MT5的MQL5代码获取持仓并通过Discord Webhook发送通知时,返回HTTP 400错误,提示请求体包含无效JSON。原代码及运行日志如下:

原代码

input string WebhookURL = "https://discord.com/api/webhooks/1288029176930242621/t-npSVLA5x8hv2QqAI8KfXbsiAXAtBMQcYyZyuuSYeFBOzr-AT-ldGGPAIXwUgeMOfB0";

void SendDiscordMessage(string message)
{
    Print("Raw message: ", message);
    
    // Escape newlines in the message
    StringReplace(message, "\n", "\\n");
    
    string json = "{\"content\":\"" + message + "\"}";
    Print("Final JSON Payload: ", json);
    
    char data[];
    StringToCharArray(json, data);
    ArrayResize(data, StringLen(json) + 1);  // Ensure the array has enough space

    char result[];
    string headers = "Content-Type: application/json";
    Print("Sending with headers: ", headers);
    string result_headers;

    int res = WebRequest("POST", WebhookURL, headers, 5000, data, result, result_headers);
    
    if (res < 0)
    {
        Print("Error sending message: ", GetLastError());
        return;
    }

    string response = CharArrayToString(result);
    Print("HTTP Response Code: ", res);
    Print("Response Raw Output: ", response);
}

void OnStart()
{
    Print("Discord notification script running on MT5...");

    int totalPositions = PositionsTotal();
    Print("Total open positions: ", totalPositions);

    for (int i = 0; i < totalPositions; i++)
    {
        ulong ticket = PositionGetTicket(i);
        if (PositionSelectByTicket(ticket))
        {
            string symbol = PositionGetString(POSITION_SYMBOL);
            double entryPrice = PositionGetDouble(POSITION_PRICE_OPEN);
            double stopLoss = PositionGetDouble(POSITION_SL);
            double takeProfit = PositionGetDouble(POSITION_TP);

            // Format the message
            string message = StringFormat("New Trade: %s\\nEntry: %.2f\\nSL: %.2f\\nTP: %.2f",
                symbol, entryPrice, stopLoss, takeProfit);
                
            Print("Complete message: ", message);  // Log the complete message
            SendDiscordMessage(message);
        }
        else
        {
            Print("Failed to select position with ticket: ", ticket);
        }
    }
}

运行日志

2024.09.24 18:03:05.733 TelegeramALert (MESZ24,H1)  Discord notification script running on MT5...
2024.09.24 18:03:05.733 TelegeramALert (MESZ24,H1)  Total open positions: 1
2024.09.24 18:03:05.733 TelegeramALert (MESZ24,H1)  Complete message: New Trade: MYMZ24\nEntry: 42574.00\nSL: 0.00\nTP: 0.00
2024.09.24 18:03:05.733 TelegeramALert (MESZ24,H1)  Raw message: New Trade: MYMZ24\nEntry: 42574.00\nSL: 0.00\nTP: 0.00
2024.09.24 18:03:05.733 TelegeramALert (MESZ24,H1)  Final JSON Payload: {"content":"New Trade: MYMZ24\nEntry: 42574.00\nSL: 0.00\nTP: 0.00"}
2024.09.24 18:03:05.733 TelegeramALert (MESZ24,H1)  Sending with headers: Content-Type: application/json
2024.09.24 18:03:06.211 TelegeramALert (MESZ24,H1)  HTTP Response Code: 400
2024.09.24 18:03:06.211 TelegeramALert (MESZ24,H1)  Response Raw Output: {"message": "The request body contains invalid JSON.", "code": 50109}

问题原因

  1. 未转义的控制字符:代码生成的消息包含实际换行符(ASCII 10),而非JSON要求的转义序列\\n,JSON规范禁止字符串内出现未转义的控制字符。
  2. 编码不匹配:MQL5默认用ANSI编码转换字符串,但Discord Webhook要求UTF-8编码的请求体,编码错误导致JSON解析失败。

修复后的代码

input string WebhookURL = "https://discord.com/api/webhooks/1288029176930242621/t-npSVLA5x8hv2QqAI8KfXbsiAXAtBMQcYyZyuuSYeFBOzr-AT-ldGGPAIXwUgeMOfB0";

void SendDiscordMessage(string message)
{
    Print("Raw message: ", message);
    
    // 将实际换行符替换为JSON兼容的转义序列
    StringReplace(message, "\n", "\\n");
    // 转义消息中的双引号,避免破坏JSON结构
    StringReplace(message, "\"", "\\\"");
    
    string json = "{\"content\":\"" + message + "\"}";
    Print("Final JSON Payload: ", json);
    
    char data[];
    // 使用UTF-8编码转换字符串,符合Discord要求
    StringToCharArray(json, data, 0, StringLen(json), CP_UTF8);

    char result[];
    string headers = "Content-Type: application/json; charset=utf-8";
    Print("Sending with headers: ", headers);
    string result_headers;

    int res = WebRequest("POST", WebhookURL, headers, 5000, data, result, result_headers);
    
    if (res < 0)
    {
        Print("Error sending message: ", GetLastError());
        return;
    }

    string response = CharArrayToString(result, 0, ArraySize(result), CP_UTF8);
    Print("HTTP Response Code: ", res);
    Print("Response Raw Output: ", response);
}

void OnStart()
{
    Print("Discord notification script running on MT5...");

    int totalPositions = PositionsTotal();
    Print("Total open positions: ", totalPositions);

    for (int i = 0; i < totalPositions; i++)
    {
        ulong ticket = PositionGetTicket(i);
        if (PositionSelectByTicket(ticket))
        {
            string symbol = PositionGetString(POSITION_SYMBOL);
            double entryPrice = PositionGetDouble(POSITION_PRICE_OPEN);
            double stopLoss = PositionGetDouble(POSITION_SL);
            double takeProfit = PositionGetDouble(POSITION_TP);

            // 生成消息时直接使用转义的换行符
            string message = StringFormat("New Trade: %s\\nEntry: %.2f\\nSL: %.2f\\nTP: %.2f",
                symbol, entryPrice, stopLoss, takeProfit);
                
            Print("Complete message: ", message);
            SendDiscordMessage(message);
        }
        else
        {
            Print("Failed to select position with ticket: ", ticket);
        }
    }
}

关键改动说明

  • 增强转义处理:新增双引号转义逻辑,避免持仓符号或内容含双引号时破坏JSON结构。
  • UTF-8编码支持:字符串与字符数组的转换均指定CP_UTF8参数,确保请求体编码符合Discord要求。
  • 请求头优化:在Content-Type中明确标注charset=utf-8,告知服务端请求体编码格式。
  • 移除冗余操作:删除不必要的ArrayResize,StringToCharArray会自动分配正确的数组空间。

内容的提问来源于stack exchange,提问作者yohans shegaw

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 00:14:53