Lambda 节点 JS Shopify API 调用

Lambda Node JS Shopify API Call

过去几天我一直在尝试解决这个问题,但没有成功,我对 Node Js 和 Lambda 还很陌生。我正在尝试使用 lambda 创建一个 API,当我调用这个新的 API 时,我想在 Shopify 中创建一个新的重定向对象。我的函数

中有以下代码 运行
const http = require('https')

exports.handler = async (event) => {
    return httprequest().then((data) => {
        const response = {
            statusCode: 200,
            body: JSON.stringify(data),
        };
    return response;
    });
};
function httprequest() {
     var username = "shopify-api-private-username";
     var password = "shopify-api-private-password";
     var auth = 'Basic ' + Buffer.from(username + ':' + password).toString('base64');
    
     return new Promise((resolve, reject) => {
        const options = {
            host: 'store-name.myshopify.com',
            path: '/admin/api/2020-04/redirects.json',
            port: 443,
            method: 'POST',
            headers: {
              'Authorization': auth,
              'Content-Type': 'application/json',
            },
            body: JSON.stringify({"redirect":{"path":"http://www.apple.com/forum","target":"http://forums.apple.com"}})
        };
        
        const req = http.request(options, (res) => {
            console.log(res);
            if (res.statusCode < 200 || res.statusCode >= 300) {
                return reject(new Error('statusCode=' + res.statusCode));
            }
            var body = [];
            res.on('data', function(chunk) {
                body.push(chunk);
            });
            res.on('end', function() {
                try {
                    body = JSON.parse(Buffer.concat(body).toString());
                } catch(e) {
                    reject(e);
                }
                resolve(body);
            });
        });
        req.on('error', (e) => {
          reject(e.message);
        });
        // send the request
       req.end();
    });
}

随着我不断更改代码,我不断收到以下错误。在响应中添加控制台日志后,我看到以下内容,不确定这是 Lambda/Node 响应还是 Shopify:

Function logs:
  servername: 'store-name.myshopify.com',
      alpnProtocol: false,
      authorized: true,
      authorizationError: null,
      encrypted: true,
      _events: [Object: null prototype],
      _eventsCount: 11,
      connecting: false,
      _hadError: false,
      _parent: null,
      _host: 'store-name.myshopify.com',
      _readableState: [ReadableState],
      readable: true,
      _maxListeners: undefined,
      _writableState: [WritableState],
      writable: true,
      allowHalfOpen: false,
      _sockname: null,
      _pendingData: null,
      _pendingEncoding: '',
      server: undefined,
      _server: null,
      ssl: [TLSWrap],
      _requestCert: true,
      _rejectUnauthorized: true,
      parser: [HTTPParser],
      _httpMessage: [Circular],
      [Symbol(res)]: [TLSWrap],
      [Symbol(asyncId)]: 4,
      [Symbol(kHandle)]: [TLSWrap],
      [Symbol(kSetNoDelay)]: false,
      [Symbol(lastWriteQueueSize)]: 0,
      [Symbol(timeout)]: null,
      [Symbol(kBuffer)]: null,
      [Symbol(kBufferCb)]: null,
      [Symbol(kBufferGen)]: null,
      [Symbol(kCapture)]: false,
      [Symbol(kBytesRead)]: 0,
      [Symbol(kBytesWritten)]: 0,
      [Symbol(connect-options)]: [Object]
    },
    _header: 'POST /admin/api/2020-04/redirects.json HTTP/1.1\r\n' +
      'Authorization: Basic base64code_replace_for_security_reasons=\r\n' +
      'Content-Type: application/json\r\n' +
      'Host: store-name.myshopify.com\r\n' +
      'Connection: close\r\n' +
      'Content-Length: 0\r\n' +
      '\r\n',
    _onPendingData: [Function: noopPendingOutput],
    agent: Agent {
      _events: [Object: null prototype],
      _eventsCount: 2,
      _maxListeners: undefined,
      defaultPort: 443,
      protocol: 'https:',
      options: [Object],
      requests: {},
      sockets: [Object],
      freeSockets: {},
      keepAliveMsecs: 1000,
      keepAlive: false,
      maxSockets: Infinity,
      maxFreeSockets: 256,
      maxCachedSessions: 100,
      _sessionCache: [Object],
      [Symbol(kCapture)]: false
    },
    socketPath: undefined,
    method: 'POST',
    insecureHTTPParser: undefined,
    path: '/admin/api/2020-04/redirects.json',
    _ended: false,
    res: [Circular],
    aborted: false,
    timeoutCb: null,
    upgradeOrConnect: false,
    parser: HTTPParser {
      '0': [Function: parserOnHeaders],
      '1': [Function: parserOnHeadersComplete],
      '2': [Function: parserOnBody],
      '3': [Function: parserOnMessageComplete],
      '4': null,
      _headers: [],
      _url: '',
      socket: [TLSSocket],
      incoming: [Circular],
      outgoing: [Circular],
      maxHeaderPairs: 2000,
      _consumed: false,
      onIncoming: [Function: parserOnIncomingClient]
    },
    maxHeadersCount: null,
    reusedSocket: false,
    [Symbol(kCapture)]: false,
    [Symbol(kNeedDrain)]: false,
    [Symbol(corked)]: 0,
    [Symbol(kOutHeaders)]: [Object: null prototype] {
      authorization: [Array],
      'content-type': [Array],
      host: [Array]
    }
  },
  [Symbol(kCapture)]: false

如有任何帮助,我们将不胜感激。提前谢谢你。

顺便说一句,我直接在新的 Lambda 函数上执行此操作。我唯一的文件是 index.js.

节点版本 Node.js12.x

如评论中正确指出的那样,您的代码无法正常工作的原因是 Bad Request。这是一个错误的请求,因为您实际上并没有随请求发送负载。您从 Stack Overflow 获得的代码可能是针对 GET 请求的,只是将 body 属性 添加到 options 对象不会工作。因为根据 Node.js docs for HTTPSoptions 对象没有任何名为 body.

的 属性

根据 Node.js docs for HTTP request,您需要使用 write 函数发送 POST 数据。

// Write data to request body
req.write(postData);

要修复您的代码,请添加内容长度 属性 并写入 post 数据。检查代码注释。

    const http = require('https')
    
    exports.handler = async (event) => {
        return httprequest().then((data) => {
            const response = {
                statusCode: 200,
                body: JSON.stringify(data),
            };
        return response;
        });
    };
    function httprequest() {
         var username = "shopify-api-private-username";
         var password = "shopify-api-private-password";
         var auth = 'Basic ' + Buffer.from(username + ':' + password).toString('base64');
        
         return new Promise((resolve, reject) => {
            const data = JSON.stringify({"redirect":{"path":"http://www.apple.com/forum","target":"http://forums.apple.com"}});
            const options = {
                host: 'store-name.myshopify.com',
                path: '/admin/api/2020-04/redirects.json',
                port: 443,
                method: 'POST',
                headers: {
                  'Authorization': auth,
                  'Content-Type': 'application/json',
                  'Content-Length': data.length // Added content length
                }
            };
            
            const req = http.request(options, (res) => {
            console.log(res);
            if (res.statusCode < 200 || res.statusCode >= 300) {
                return reject(new Error('statusCode=' + res.statusCode));
            }
            var body = [];
            res.on('data', function(chunk) {
                body.push(chunk);
            });
            res.on('end', function() {
                try {
                    body = JSON.parse(Buffer.concat(body).toString());
                } catch(e) {
                    reject(e);
                }
                resolve(body);
            });
        });
        req.on('error', (e) => {
          reject(e.message);
        });
        // send the request
        // write POST data
        req.write(data)
       req.end();
    });
}

我已经验证了这段代码,它在本地和 AWS Lambda 函数中都运行良好。如果你现在收到422,说明已经添加了重定向。

此外考虑使用 Shopify API Node.js that provides better error handling, rate limiting and other required features. You can also have a look at Shopify's Official Node library