带有Google脚本的MWS发布请求

时间:2019-01-21 17:59:32

标签: javascript post google-apps-script amazon-mws

我正在尝试通过Google脚本向亚马逊发出发布请求,以收集信息。

我们正在尝试将订单发送到MWS并将其自动转移到工作表上。

我到了签署请求的最后一步。

我不确定的几件事:

  1. 他们说我们使用密钥进行散列,我只看到一个客户机密  以及访问密钥ID,该怎么使用?
  2. 我是否将URL添加为已签名内容的一部分?他们在MWS Scratch pad上添加如下所示:

POST mws.amazonservices.com /Orders/2013-09-01

是否必须在单独的行上,是否需要张贴以及其余内容。有点不清楚。

  1. 我在网上阅读了sha256字节代码是经过base64编码的,而不是字符串文字,那是真的吗?
  2. 我尝试使用在线工具对亚马逊提供给我的字符串进行哈希处理,并将其与他们提供的哈希值进行比较,并与base64编码匹配。我也尝试解码,没有匹配项

有人可以给我发送一个可行的示例,以便我了解发生了什么以及如何运行吗?

谢谢!

以下是我到目前为止的内容:

function POSTRequest() {

  var url = 'https:mws.amazonservices.com/Orders/2013-09-01?';

  var today = new Date();
  var todayTime = ISODateString(today);

  var yesterday = new Date();
  yesterday.setDate(today.getDate() - 1);
  yesterday.setHours(0,0,0,0);
  var yesterdayTime = ISODateString(yesterday); 

  var dayBeforeYesterday = new Date();
  dayBeforeYesterday.setDate(today.getDate() - 2);
  dayBeforeYesterday.setHours(0,0,0,0);
  var dayBeforeYesterdayTime = ISODateString(dayBeforeYesterday); 

  var unsignedURL = 
  'POST\r\nhttps:mws.amazonservices.com\r\n/Orders/2013-09-01\r\n'+
  'AWSAccessKeyId=xxxxxxxxxxx' +
  '&Action=ListOrders'+
  '&CreatedAfter=' + dayBeforeYesterdayTime +
  '&CreatedBefore' + yesterdayTime +
  '&FulfillmentChannel.Channel.1=AFN' +
  '&MWSAuthToken=xxxxxxxxxxxx'+
  '&MarketplaceId.Id.1=ATVPDKIKX0DER' +
  '&SellerId=xxxxxxxxxxx'+
  '&SignatureMethod=HmacSHA256'+
  '&SignatureVersion=2'+
  '&Timestamp='+ ISODateString(new Date) + 
  '&Version=2013-09-0';

  var formData = {
        'AWSAccessKeyId' : 'xxxxxxxxx',
        'Action' : "ListOrders",
        'CreatedAfter' : dayBeforeYesterdayTime,
        'CreatedBefore' : yesterdayTime,
        'FulfillmentChannel.Channel.1' : 'AFN',
        'MWSAuthToken' : 'xxxxxxxxxxxx',
        'MarketplaceId.Id.1' : 'ATVPDKIKX0DER',
        'SellerId' : 'xxxxxxxxxx',
        'SignatureMethod' : 'HmacSHA256',
        'SignatureVersion' : '2',
        'Timestamp' : ISODateString(new Date),
        'Version' : '2013-09-01',
        'Signature' : calculatedSignature(unsignedURL)

      };

   var options = {
     "method" : "post",
     "muteHttpExceptions" : true,
     "payload" : formData
   };


  var result = UrlFetchApp.fetch(url, options);
  writeDataToXML(result);
  Logger.log(result);


  if (result.getResponseCode() == 200) {
  writeDataToXML(result);
  }
}




function calculatedSignature(url) {
var urlToSign = url;
var secret = "xxxxxxxxxxxxxxxxxxx";
var accesskeyid = 'xxxxxxxxxxxxxxx';

  var byteSignature = Utilities.computeHmacSha256Signature(urlToSign, secret);
// convert byte array to hex string
var signature = byteSignature.reduce(function(str,chr){
  chr = (chr < 0 ? chr + 256 : chr).toString(16);
  return str + (chr.length==1?'0':'') + chr;
},'');


  Logger.log("URL to sign: " + urlToSign);
  Logger.log("");
  Logger.log("byte " + byteSignature);
  Logger.log("");
  Logger.log("reg " + signature);

var byte64 =  Utilities.base64Encode(byteSignature)
Logger.log("base64 byte " + Utilities.base64Encode(byteSignature));
  Logger.log("");
Logger.log("base64 reg " + Utilities.base64Encode(signature)); 

 return byte64;
}

2 个答案:

答案 0 :(得分:4)

步骤1,创建要签名的字符串

string_to_sign是以下各项的组合:

  • 字符串POST后跟一个NEWLINE字符
  • 主机名mws.amazonservices.com,后跟NEWLINE
  • API URL,通常只是/或类似/Orders/2013-09-01之类的,后面跟着NEWLINE
  • URL编码中除Signature以外的所有参数的字母列表,例如a=1&b=2,后面没有任何内容

最小参数似乎如下:

  • AWSAccessKeyId是Amazon提供的20个字符的代码
  • Action是您的API调用的名称,例如GetReport
  • SellerId是您的14个字符的卖方ID
  • SignatureMethodHmacSHA256
  • SignatureVersion2
  • Timestamp是一个类似20181231T23:59:59Z的日期,表示新年UTC之前的一秒
  • Version2013-09-01之类的API版本
  • 呼叫需要
  • 其他参数 ,具体取决于Action
  • 的值

请注意:

  • NEWLINE字符只是“ \ n”,而不是“ \ r \ n”
  • 主机名应包括“ https://”或“ http://”
  • Signature参数对于以后的实际调用是必需的(请参阅步骤3),但它不是string_to_sign的一部分。

您的string_to_sign现在应该看起来像这样:

POST
mws.amazonservices.com
/Orders/2013-09-01
AWSAccessKeyId=12345678901234567890&Action=ListOrders&CreatedAfter .... &Version=2013-09-01

第2步,对该字符串签名

  • 使用40个字符的Secret Key来计算上述字符串的SHA256哈希值
  • 使用Base64对该哈希进行编码
  • 使用伪代码:signature = Base64encode( SHA256( string_to_sign, secret_key ))

第3步,发送呼叫

使用完整的按字母顺序排列的参数列表发送HTTPS POST请求,现在将包括上面的签名作为Signature放在中间的某个位置,因为您需要保持字母顺序升序。

https://mws.amazonservices.com/Orders/2013-09-01?AWSAccessKeyId....Version=2013-09-01

第4步,处理结果

您应该返回两件事:响应标头和XML文档。确保评估标头中的HTTP状态以及XML文档的所有内容。 HTTP返回“ 200 OK”时,某些错误消息深深地隐藏在XML中。

第5步,高级资料

如果使用要求发送文档的呼叫(例如SendFeed),则需要执行以下附加步骤:

  • 计算文档的MD5哈希值
  • 使用Base64对该哈希进行编码
  • 使用伪代码:contentmd5= Base64encode( MD5( document ))
  • 添加Content-Type: text/xml(或任何适合您的文档的内容)作为HTTP标头
  • 添加Content-MD5:加上base64编码的哈希作为HTTP标头

答案 1 :(得分:0)

此代码对构建类似应用程序有很大帮助。我更正了一些小问题以使其正常工作:

在签署ISODate之前需要解决替换“:”字符的问题

  var todayTime = ISODateString(today);
  var todayISO = todayTime;


  var todayTime_ = todayTime.replace(":", "%3A");
  todayTime = todayTime_.replace(":","%3A");

计算出的签名相同(快速且肮脏的解决方案,仅替换3种出现,并且需要更新以获取更多字符)


  Logger.log(unsignedURL);

  var tmpsignature = calculatedSignature(unsignedURL);

  var orsignature = tmpsignature;


// encode special chars
tmpsignature = encodeURIComponent(orsignature);
  }

我添加了标题并删除了表单,将所有参数都放在了网址中

var header = {
     "x-amazon-user-agent": "GoogleSheets/1.0 (Language=Javascript)",
    "Content-Type": "application/x-www-form-urlencoded"
     //  "Content-Type": "text/xml"
}; 


   var options = {
     "method" : "post",
     "muteHttpExceptions" : true,
   //  "payload" : formData,
     "header":header
   };

并将呼叫更改为url编码(表单无法正常工作,不知道为什么)


var url = 'https:mws-eu.amazonservices.com/Orders/2013-09-01?'+
'AWSAccessKeyId=<your stuff>'+
'&Action=GetOrder'+
  '&SellerId=<your stuff>+
  '&MWSAuthToken=<your token>'+
  '&SignatureVersion=2'+
  '&Timestamp='+todayTime'+ // remember to replace the ":" thru hex
  '&Version=2013-09-01'+
  '&Signature='+ tmpsignature+
  '&SignatureMethod=HmacSHA256'+
  '&AmazonOrderId.Id.1='+<your order;

解析响应:



 var result = UrlFetchApp.fetch(url, options);

  //writeDataToXML(result);
  Logger.log(result);

    var xml = result.getContentText();

  var document = XmlService.parse(xml);

这有效! :-)

我也用 https://mws-eu.amazonservices.com/scratchpad/index.html