Search code examples
node.jshttpszapierzapier-cli

Zapier application: send body with GET request


I'm making an integration for the intouch api in Zapier. For some reason, the API is set up to receive queries in the body of the GET requests, rather than in the parameters.

This is all working in Postman but it seems that the z.request function ignores a body option attribute with GET requests.

Here is my code:

const test = (z, bundle) => {
  const query = {
    matterGuid: "bf508fcf-5f36-4191-93d6-fecd5a7f6a04",
    getFields: ["matter.reference"],
  };

  return z.request({
    method: "GET",
    url: baseUrl + "/matters",
    body: JSON.stringify(query), //I've tried body, json, raw, data, etc
  });
};

And here is the response I receive:

{
      status: 400,
      json: { message: 'No request data received', success: false, errors: [] },
      data: { message: 'No request data received', success: false, errors: [] },
      content: '{"message":"No request data received","success":false,"errors":[]}',
      request: {
        method: 'GET',
        headers: {
          'user-agent': 'Zapier',
          'x-intouch-o-token': 'xxxxxxxxxxxxxxxxxxx',
          'Content-Type': 'application/json; charset=utf-8'
        },
        url: 'https://demo.intouch.cloud/api/v2/public/matters',
        _addContext: [Function: addContext],
        input: {
          bundle: [Object],
          _zapier: [Object],
          _addContext: [Function: addContext]
        },
        merge: true,
        removeMissingValuesFrom: { params: false, body: false },
        replace: true,
        skipThrowForStatus: false,
        _requestStart: 2020-10-24T11:42:37.026Z
      },
      skipThrowForStatus: false,
      headers: Headers {
        [Symbol(map)]: [Object: null prototype] {
          date: [Array],
          'content-type': [Array],
          'content-length': [Array],
          connection: [Array],
          'set-cookie': [Array],
          'access-control-allow-origin': [Array],
          'access-control-allow-headers': [Array],
          'access-control-allow-methods': [Array],
          'x-content-type-options': [Array],
          'arr-disable-session-affinity': [Array],
          'x-frame-options': [Array],
          'strict-transport-security': [Array],
          'cf-cache-status': [Array],
          'cf-request-id': [Array],
          'expect-ct': [Array],
          'report-to': [Array],
          nel: [Array],
          server: [Array],
          'cf-ray': [Array]
        }
      },
      getHeader: [Function: getHeader],
      throwForStatus: [Function],
      _addContext: [Function: addContext]
    }

Solution

  • Maybe this is not the ideal solution but I've found a workaround for this.

    I discovered that as part of the middleware in the z.request method, the body is explicitly deleted from GET requests.

    // No need for body on get
      if (req.method === 'GET') {
        delete req.body;
      }
    

    As a result, I was able to add in more middleware to put the body back in. Fortunately, the custom middleware functions added to the before array run after Zapier's own middleware, meaning that the body was not affected by the function above.

    This is what I came up with to get around this:

    const includeQuery = (request, z, bundle) => {
      if (request.method ==='GET'){
        if (bundle.inputData.matterGuid && bundle.inputData.getFields){
          const query = {
            matterGuid: bundle.inputData.matterGuid,
            getFields: bundle.inputData.getFields.split(','),
          };
          request.body = JSON.stringify(query);
        }    
      }
    
      return request;
    };
    

    This was then added to the befores array in the exported object, like this:

      befores: [includeApiKey, includeQuery],
      afters: [handleBadResponses],
    

    I'd be really interested to hear if anyone has a better solution to this issue.