【问题标题】:Convert Query String to Request body response error将查询字符串转换为请求正文响应错误
【发布时间】:2019-02-02 17:50:23
【问题描述】:

我正在尝试将有效的查询字符串转换为请求正文,但我收到一个错误,提示我缺少一个属性。我从另一篇文章中获得了@Tanaike 的帮助,该文章提供了将参数分解为编码格式的编码 URI 函数。但是,当我的“pairs”参数中有 30-50 对时,URLFetch 会出现查询字符串长度限制错误。所以我尝试将其作为请求正文发送。

var botParams = {
"name": "TestBot",
"base_order_volume": 0.001,
"take_profit": 1.5,
"safety_order_volume": 0.001,
"martingale_volume_coefficient": 2,
"martingale_step_coefficient": 1,
"max_safety_orders": 1,
"active_safety_orders_count": 1,
"safety_order_step_percentage": 2.5,
"take_profit_type": "total",
"stop_loss_percentage": 0,
"cooldown": 0,
"pairs": [
  "BTC_ADA",
  "BTC_TRX"
],
"trailing_enabled":"true",
"trailing_deviation":0.5,
"strategy_list": [
  {
    "strategy":"cqs_telegram"
  }
]
  };    
  
  try {

//    var totalParams = keys.reduce(function(q, e, i) {
//      q += (e == "pairs" ? botParams[e].reduce(function(s, f, j) {
//        s += e + "[]=" + f + (j != botParams[e].length - 1 ? "&" : "");
//        return s;
//      },"") : e + "=" + (typeof botParams[e] == "object" ? 
//encodeURIComponent(JSON.stringify(botParams[e])) : 
//encodeURIComponent(botParams[e]))) + (i != keys.length - 1 ? "&" : "");
//      return q;
//    }, endPoint); //Thanks to Tanaike


//Call
//Base
var baseUrl = "https://3commas.io";        
//Total Endpoint
var endPoint = "/public/api/ver1/bots/274339/update?";


//Convert Bot Params + endPoint to Encoded URI
var keys = Object.keys(botParams);
var totalParams = keys.reduce(function(q, e, i) {
  q += e + "=" + (typeof botParams[e] == "object" ? encodeURIComponent(JSON.stringify(botParams[e])) : encodeURIComponent(botParams[e])) + (i != keys.length - 1 ? "&" : "");
  Logger.log(encodeURIComponent(botParams[e]))
  return q;
},endPoint);

Logger.log(totalParams)   

//Create Signature
var signature = Utilities.computeHmacSha256Signature(totalParams, secret);    
//Convert from byte
signature = signature.map(function(e) {return ("0" + (e < 0 ? e + 256 : e).toString(16)).slice(-2)}).join("");

var headers = {
  "APIKEY": key,
  "Signature": signature,
};
var params = {
  "method": "PATCH",
  "headers": headers,     
  "payload" : totalParams,
  //Show full exceptions      
   muteHttpExceptions: true
};  

var finalURL = baseUrl + "/public/api/ver1/bots/274339/update";

Logger.log(finalURL)
//https://3commas.io/public/api/ver1/bots/274339/update

// Call final URL with params
var data = UrlFetchApp.fetch(finalURL, params).getContentText();
var json = JSON.parse(data);
Logger.log(json)
  } catch (err) {Logger.log(err)}
}

我收到的当前错误是{error_attributes={name=[is missing]}, error_description=Invalid parameters, error=record_invalid} 所以由于某种原因它无法识别我的姓名属性。当我记录结果时,我看到名称是作为字符串传递的。

记录结果:/public/api/ver1/bots/274339/update?name=TestBot&amp;base_order_volume=0.001&amp;take_profit=1.5&amp;safety_order_volume=0.001&amp;martingale_volume_coefficient=2&amp;martingale_step_coefficient=1&amp;max_safety_orders=1&amp;active_safety_orders_count=1&amp;safety_order_step_percentage=2.5&amp;take_profit_type=total&amp;stop_loss_percentage=0&amp;cooldown=0&amp;pairs=%5B%22BTC_ADA%22%2C%22BTC_TRX%22%5D&amp;trailing_enabled=true&amp;trailing_deviation=0.5&amp;strategy_list=%5B%7B%22strategy%22%3A%22cqs_telegram%22%7D%5D

3 逗号文档:https://github.com/3commas-io/3commas-official-api-docs/blob/master/bots_api.md#edit-bot-permission-bots_write-security-signed

只是寻找关于它可能是什么的建议。谢谢。

【问题讨论】:

    标签: google-apps-script


    【解决方案1】:

    我认为在您的情况下,botParams 可能需要以表单形式发送,而查询参数需要从botParams 创建以创建签名。所以修改后的脚本如下。

    修改脚本:

    var key = 'apikey';
    var secret = 'apisecret';
    var editBots = "/ver1/bots/274339/update";
    var baseUrl = "https://3commas.io";
    var endPoint = "/public/api"+editBots;
    var botParams = {
      "name": "TestBot",
      "base_order_volume": 0.001,
      "take_profit": 1.5,
      "safety_order_volume": 0.001,
      "martingale_volume_coefficient": 2,
      "martingale_step_coefficient": 1,
      "max_safety_orders": 1,
      "active_safety_orders_count": 1,
      "safety_order_step_percentage": 2.5,
      "take_profit_type": "total",
      "stop_loss_percentage": 0,
      "cooldown": 0,
      "pairs": ["BTC_ADA", "BTC_TRX"],
      "trailing_enabled": "true",
      "trailing_deviation": 0.5,
      "strategy_list": [{"strategy": "cqs_telegram"}]
    };
    var keys = Object.keys(botParams);
    var totalParams = keys.reduce(function(q, e, i) {return q += (e == "pairs" ? botParams[e].reduce(function(s, f, j) {return s += e + "=" + f + (j != botParams[e].length - 1 ? "&" : "")},"") : e + "=" + (typeof botParams[e] == "object" ? encodeURIComponent(JSON.stringify(botParams[e])) : encodeURIComponent(botParams[e]))) + (i != keys.length - 1 ? "&" : "")}, endPoint + "?");
    var signature = Utilities.computeHmacSha256Signature(totalParams, secret);
    signature = signature.map(function(e) {return ("0" + (e < 0 ? e + 256 : e).toString(16)).slice(-2)}).join("");
    var headers = {
      'APIKEY': key,
      'Signature': signature,
    };
    var params = {
      method: 'PATCH',
      headers: headers,
      payload: Object.keys(botParams).reduce(function(o, e) {
        o[e] = typeof botParams[e] == "object" ? JSON.stringify(botParams[e]) : e;
        return o;
      }, {}),
      muteHttpExceptions: true
    };
    var data = UrlFetchApp.fetch(baseUrl + endPoint, params).getContentText();
    Logger.log(data)
    

    注意:

    • 我不确定 API 的规范。所以如果上面的脚本不起作用,你能向API的经理询问以下几点吗?
      1. 关于"pairs": ["BTC_ADA", "BTC_TRX"],botParams,在此脚本中,使用与创建查询参数相同的过程,如pairs=BTC_ADA&amp;pairs=BTC_TRX。这是正确的吗?
      2. keysecret 是否需要包含在 botParams 中才能创建 signature
      3. keysecret 是否需要包含在负载中?
      4. 是否需要同时满足 2 和 3 的要求?

    编辑:

    修改点:

    从:
      payload: Object.keys(botParams).reduce(function(o, e) {
        o[e] = typeof botParams[e] == "object" ? JSON.stringify(botParams[e]) : e;
        return o;
      }, {}),
    
    到:
      payload: Object.keys(botParams).reduce(function(o, e) {
        o[e] = typeof botParams[e] == "object" ? JSON.stringify(botParams[e]) : botParams[e];
        return o;
      }, {}),
    

    【讨论】:

    • @Phil 对不起。我无法理解您所说的chat
    • @Phil 感谢您的回复。我认为您的回复信息很重要。根据您的评论,您可以在botParams 中尝试使用"pairs": ["BTC_ADA", "BTC_TRX"] 的脚本吗?顺便问一下,"pairs": ["BTC_ADA", "BTC_TRX"] 可以同时用于创建签名和请求体吗?
    • @Phil 谢谢。我会检查的。
    • @Phil 我添加了一个修改点。请您确认并尝试一下。如果出现与signature相关的错误,能否向API管理员询问正确的值?
    • @Phil 从之前的结果,已经发现加密的脚本是正确的。但在这种情况下,虽然使用了正确的值进行加密,但会出现签名错误。不幸的是,我无法理解这个问题。如果我发现了问题,我想在这里报告。但是现在,我必须为我的拙劣技能道歉。
    【解决方案2】:

    我发现了这个问题。怀疑是编码问题。这就是最终的工作。

            var totalParams2 = keys.reduce(function(q, e, i) {
              q += (e == "pairs" ? botParams[e].reduce(function(s, f, j) {
                s += e + encodeURIComponent("[]")+"=" + f + (j != botParams[e].length - 1 ? "&" : "");            
                return s;
              },"") : e + "=" + (typeof botParams[e] == "object" ? encodeURIComponent(JSON.stringify(botParams[e])) : encodeURIComponent(botParams[e]))) + (i != keys.length - 1 ? "&" : "");
              return q;
            }, "");
    

    添加 e + encodeURIComponent("[]")+ 特别是因为 API 的设置方式。我必须对我的对数组进行编码。

    【讨论】:

    • 很高兴您的问题得到了解决。感谢您发布答案。对此表示赞同。我很抱歉我帮不上忙。
    • 嗨。我知道这是一个非常古老的帖子,但我想要这个确切的东西。当我将上面的 sn-p 放在下面脚本中的 totalParams 人口时,我得到一个签名无效错误。我真的很感激任何帮助!
    猜你喜欢
    • 1970-01-01
    • 2014-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-18
    • 1970-01-01
    • 2016-09-18
    相关资源
    最近更新 更多