Code Examples#

Trigger Pre-Poll Examples#

Heads up! This code is only valid for the v2 platform -- the CLI platform is mostly incompatible.

"use strict"; 

var Zap = {
  // STRAIGHT PASS THROUGH
  // same as not providing the method at all
  // for illustration purposes only
  simple_pre_poll: function(bundle) {
    return bundle.request;
  },

  // CHANGE REQUEST METHOD
  // for endpoints that don't like the default GET
  simple_pre_poll: function(bundle) {
    bundle.request.method = 'POST';
    return bundle.request;
  },

  // PLACE A HEADER BASED ON USER INPUT
  // a trigger field that should be added as a header but
  // if there isn't one, default to "None"
  some_header_pre_poll: function(bundle) {
    var request = bundle.request;
    request.headers["X-Project-ID"] = bundle.trigger_fields.project_id || "None";
    return request;
  },

  // SUBSTITUTE HUMAN FRIENDLY CHOICES
  // if you add a trigger field with human friendly choices:
  //     Yesterday,Today,Tomorrow
  // but the querystring should be:
  //     &when=-1, &when=0, or &when=1
  event_pre_poll: function(bundle) {
    var request = bundle.request;
    switch (bundle.trigger_fields.when) {
      case "Yesterday":
        request.params.when = -1;
        break;
      case "Today":
        request.params.when = 0;
        break;
      default:
        request.params.when = 1;
    }
    return request;
  },

  // BUILD THE URL YOURSELF
  // this does exactly what we do when transforming the URL
  // from bundle.url_raw to bundle.request.url
  // utilizes underscores template system (preloaded with proper syntax)
  room_pre_poll: function(bundle) {
    var request = bundle.request;
    // bundle.url_raw is 'http://.campfirenow.com/room//speak.json'
    // bundle.auth_fields is {account_name: 'myaccount', api_key: '1234567890'}
    request.url = _.template(bundle.url_raw)(bundle.auth_fields);
    // request.url is 'http://myaccount.campfirenow.com/room//speak.json'
    // bundle.auth_fields is {room_id: 12345, message: 'Hello world!'}
    request.url = _.template(request.url)(bundle.trigger_fields);
    // request.url is 'http://myaccount.campfirenow.com/room/12345/speak.json'
    return request;
  }
}

Trigger Post-Poll Examples#

Heads up! This code is only valid for the v2 platform -- the CLI platform is mostly incompatible.

"use strict"; 

var Zap = {
  // STRAIGHT PASS THROUGH OF JSON
  // same as not providing the method at all
  // for illustration purposes only
  straight_post_poll: function(bundle) {
    // bundle.response.content is '[{"id":1234,"title":"Hello!"}, ... ]'
    return z.JSON.parse(bundle.response.content);
  },

  // WRAP IN ARRAY
  // for APIs that return a single object
  straight_post_poll: function(bundle) {
    // bundle.response.content is '{"id":1234,"title":"Hello!"}'
    return [z.JSON.parse(bundle.response.content)];
  },

  // CENTS INTO DOLLARS
  // take a key in cents and offer it up as a dollar formatted string
  sale_post_poll: function(bundle) {
    // bundle.response.content is '[{"id":1234,"cents":925}, ... ]'
    var results = z.JSON.parse(bundle.response.content);
    _.each(results, function(result) {
      result.dollars = "$" + (Math.floor(result.cents / 100)) + "." + (result.cents % 100);
    })
    // results is '[{"id":1234,"cents":925,"dollars":"$9.25"}, ... ]'
    return results;
  },

  // XML INTO JSON
  // given an string of xml data, turn that into JSON:
  //   <messages type="array">
  //     <message>
  //       <id type="integer">2</id>
  //       <title>Anyone home?</title>
  //       <body>I can't seem to see anything!</body>
  //     </message>
  //     <message>
  //       <id type="integer">1</id>
  //       <title>Hello there world!</title>
  //       <body>I am just tickled to see you!</body>
  //     </message>
  //   </messages>
  my_xml_doc_post_poll: function(bundle) {
    // bundle.response.content is xml string from API, $ is preloaded jQuery
    var xml = $($.parseXML(bundle.response.content)).find('message');
    // build javascript primitives: array of objects
    var results = _.map(xml, function(element){
      return {
        id: $(element).find('id').text(),
        title: $(element).find('title').text(),
        body: $(element).find('body').text()
      };
    });
    // results is '[{"id":"2","title":"Anyone home?","body":"I can't seem to see anything!"}, ... ]'
    return results;
  }
}

Catching Webhooks Example#

Heads up! This code is only valid for the v2 platform -- the CLI platform is mostly incompatible.

"use strict";

var Zap = {
  // STRAIGHT PASS THROUGH OF CLEANED_REQUEST
  // same as not providing the method at all
  // for illustration purposes only
  straight_catch_hook: function(bundle) {
    // bundle.cleaned_request is usually an object or array
    return bundle.cleaned_request;
  },

  // PLACE QUERY STRING AS MAIN OBJECT
  // in this example our hook is just a GET with a query string
  // there is no request content or body, maybe a url like this:
  //   GET https://zapier.com//hooks/catch/123/n/456789/?name=bryan&age=27
  simple_get_catch_hook: function(bundle) {
    // bundle.cleaned_request includes the query string already parsed
    // but you could parse it yourself from bundle.request.querystring:
    var example = $.param(bundle.request.querystring);

    // but let's just return the cleaned_request version:
    return bundle.cleaned_request.querystring; // {"name":"bryan","age":27}
  },

  // MOVE LIST ON SUBKEY TO MAIN OBJECT
  // if a json POST contains a list on a root object's key "data" 
  // we can move the list to the parent to trigger for each item
  // the content/body might look like:
  //   {"data":[{"name":"bryan","age":27},{"name":"mike","age":23}]}
  myjson_catch_hook: function(bundle) {
    // bundle.cleaned_request includes the json already parsed
    // but you could parse it yourself from bundle.request.content:
    var example = z.JSON.parse(bundle.request.content).data;

    // but let's just return the cleaned_request version:
    return bundle.cleaned_request.data; // the array
  }

  // FILTER OUT CERTAIN STATIC WEBHOOKS
  // if your hooks are noisy, then you may want to filter based on
  // some static value, or even user provided trigger fields
  filter_out_catch_hook: function(bundle) {
    // manually create json from the posted string
    var json = z.JSON.parse(bundle.request.content);

    // filter out hooks that aren't the event type we care about
    if (json.event_type != 'new_comment') {
      return []; // return [] or {} to take no action
    }

    // filter out hooks that aren't the status that the user expected
    if (bundle.trigger_fields.status && json.status != bundle.trigger_fields.status) {
      return []; // return [] or {} to take no action
    }

    // else
    return json;
  },
}

Action Pre-Write Examples#

Heads up! This code is only valid for the v2 platform -- the CLI platform is mostly incompatible.

"use strict"; 

var Zap = {
  // STRAIGHT PASS THROUGH
  // same as not providing the method at all
  // for illustration purposes only
  pass_through_pre_write: function(bundle) {
    return bundle.request;
  },

  // WRAP FIELDS IN TOP-LEVEL ARRAY UNDER DATA KEY
  wrap_in_array_pre_write: function(bundle) {
    bundle.request.data = JSON.stringify({data: [bundle.action_fields]})
    return bundle.request;
  },

  // DO NOT UNFLATTEN __
  // by default we will turn fields like {custom__c: 12}
  // into {custom: {c: 12}}, but this can avoid this by
  // using the "full" action fields, like this
  dont_unwrap_pre_write: function(bundle) {
    bundle.request.data = JSON.stringify(bundle.action_fields_full);
    return bundle.request;
  },

  // LIMIT STRING LENGTH
  // a field called message cannot be longer than 256 characters
  message_pre_write: function(bundle) {
    var outbound = z.JSON.parse(bundle.request.data);
    outbound.message = outbound.message.substring(0, 256);
    bundle.request.data = JSON.stringify(outbound);
    return bundle.request;
  },

  // GENERATE XML FOR POSTING
  // you'll have access to your action fields
  // we'd normally POST as JSON, but this shows how to do XML
  xml_doc_pre_write: function(bundle) {
    // root el is ignored in .html()
    var xml = $("<XMLDocument><message/></XMLDocument>");
    // bundle.action_fields is {title: "Anyone home?", body: "I can't seem to see anything!"}
    Object.keys(bundle.action_fields).forEach(function(key){
      $(xml.find("message")).append($("<" + key + " />").text(bundle.action_fields[key]));
    })
    // '<message><title>Anyone home?</title><body>I can't seem to see anything!</body></message>'
    bundle.request.data = xml.html();
    // set the headers
    bundle.request.headers['Content-Type'] = "application/xml; charset=utf-8";
    bundle.request.headers['Accept'] = "application/xml";
    return bundle.request;
  },

  // FORM ENCODE INSTEAD OF JSON
  // sometimes you don't want to JSON encode, so this example shows how
  // to form encode POST data instead (just like a form submission)
  my_form_pre_write: function(bundle) {
    // build a querystring from the object with all fields
    bundle.request.data = $.param(bundle.action_fields_full);
    // correct the content type header
    bundle.request.headers['Content-Type'] = 'application/x-www-form-urlencoded';
    return bundle.request;
  }
}

Search Post-Write Examples#

Heads up! This code is only valid for the v2 platform -- the CLI platform is mostly incompatible.

Sometimes, a search endpoint will return a successful response despite the search being unsuccessful. To account for this, you need to manipulate the response in a _post_search method:

// let's say the response content looks like this:
// {
//   "search_results": {},
//   "time": "2018-04-01T01:02:03.456-00:00"
// }
// by default, our system will interpret this as a successful search
// and return the "search_results" and "time" keys -- what we really
// want is the content nested under that search_results key (which in
// this example is an empty object, because there was no search match)

var Zap = {
  my_search_key_post_search: function(bundle) {
    var response = z.JSON.parse(bundle.response.content);
    return response.search_results;
  }
}

REST Hook Subscription Examples#

Heads up! This code is only valid for the v2 platform -- the CLI platform is mostly incompatible.

var Zap = {
    pre_subscribe: function(bundle) {
        bundle.request.method = 'POST';
        bundle.request.headers['Content-Type'] = 'application/x-www-form-urlencoded';
        bundle.request.data = $.param({
            url: bundle.target_url,
            list_id: bundle.trigger_fields.list_id, // from trigger field
            append_data: 1
        });
        return bundle.request;
    },
    post_subscribe: function(bundle) {
        // must return a json serializable object for use in pre_unsubscribe
        var data = z.JSON.parse(bundle.response.content);
        // we need this in order to build the {{webhook_id}}
        // in the rest hook unsubscribe url
        return {webhook_id: data.id};
    },
    pre_unsubscribe: function(bundle) {
        bundle.request.method = 'DELETE';
        // bundle.subscribe_data is from return data in post_subscribe method
        bundle.request.url = 'https://example.com/x.php?id=' + bundle.subscribe_data.webhook_id;
        bundle.request.data = null;
        return bundle.request;
    },
};

Adding Trigger Fields to Subscription Payload

var Zap = {

  pre_subscribe: function (bundle) { 
    if (Object.keys(bundle.trigger_fields).length) {
      var data = z.JSON.parse(bundle.request.data);
      var dataWithFields = Object.assign({}, data, bundle.trigger_fields);
      bundle.request.data = JSON.stringify(dataWithFields);
    }
    return bundle.request;
  }

};

Session Auth Examples#

Heads up! This code is only valid for the v2 platform -- the CLI platform is mostly incompatible.

var Zap = {
  get_session_info: function(bundle) {
    var api_key,
        api_key_request_payload,
        api_key_response;

    // Assemble the meta data for our key swap request
    api_key_request_payload = {
        method: 'POST',
        url: 'https://api.domain-name.com/api/login',
        params: bundle.auth_fields,
        headers: {
            'Content-Type': 'application/json',  // Could be anything.
            Accept: 'application/json' 
        }
    };

    // Fire off the key exchange request.
    api_key_response = z.request(api_key_request_payload);

    // Extract the `api_key` from returned JSON.
    api_key = z.JSON.parse(api_key_response.content).api_key;

    // This structure is an example. You may need to add
    // a different key name, or multiple keys, depending
    // on your API's requirements.
    // This will be mixed into bundle.auth_fields in future calls.
    return {'api_key': api_key};
  },

  new_contact_post_poll: function(bundle) {

    // We will catch bundle.response.status_code === 401
    // If your API doesn't conform to this standard, you can handle it yourself:
    if (z.JSON.parse(bundle.response.content).code === 401) {
      throw new InvalidSessionException(); // Call get_session_info() and try the request again
    }

    return z.JSON.parse(bundle.response.content);
  }
};
↑ Was this documentation useful? Yes No