documentation logo
All you’ll ever need to know about Declarative Webhooks and how to get started.

Pages

Step 3: Callout Template Request Body (JSON Format)

Request Body Page (JSON Builder)

NOTE: If the template is using the GET method, this step is skipped. GET methods don’t use bodies.

NOTE: Once you start mapping fields in the JSON Builder, you CANNOT change the Main Object and Number of records on your Callout Template. If you want to change either of these, you need to remove all mappings set in the JSON Builder. Then you have the option to update the Main Object and Number or records. This is by design as the values set in JSON are dependent on the Main Object and Number of records selected.  

About JSON

JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to read and write. It is also easy for machines to parse and generate.

JSON is built on two structures:

  • A collection of name/value pairs.
  • An ordered list of values.

An object is an unordered set of name/value pairs. An object begins with { (left brace) and ends with } (right brace). Each name is followed by : (colon) and the name/value pairs are separated by , (comma). A value can be a string in double quotes, or a number, or true or false or null, or an object or an array.  Exmaple: { “name” : “Maria”, “age” : 30 }

An array is an ordered collection of values. An array begins with [ (left bracket) and ends with ] (right bracket). Values are separated by , (comma). Example: [ “orange”, “apple”, “cherry” ] These structures can be nested. Example: { “name” : { “first” : “John”, “last” : “Doe” } , “email” : “john@example.com”, “children_age” : [ 12, 8, 3 ] }

More about JSON here: https://www.w3resource.com/JSON/introduction.php  

JSON Builder

Let’s get started with the JSON Builder. To add nodes to the JSON body, select the ‘+’ icon as displayed below:

When adding a new node, first we need to set the Node Name, a name to define the value.

You can type in a static node name (the most commonly used option) or dynamically define a node name by clicking the edit icon on the right side of the input. The edit button opens a popup with various options for dynamic node name generation, including using a field from the main object, a formula, a custom metadata value, or a custom setting value.

Then we have options to select either “Object”, “List of Objects”, “Single Value”, “List of Values” or “Built using an Apex Class” in the Node Type field.

Here are a few more details to help you on your Node Type selection:

  • Object: This will create a node in JSON, containing another structure of key-value pairs. You only need to provide the name of the node. After adding the Object node, you can add additional nodes inside this object by clicking the “+” button inside the newly created node.
  • List of Objects: If this is selected, it will generate a list of objects in JSON.
    • To create a JSON list with a single element, simply leave the ‘Using Related List’ option unselected. This allows you to map fields from the main record (or child record if you are already in another list) to the nodes inside the JSON list.
    • To create a JSON list with multiple elements based on a Salesforce related list, choose the desired list in the ‘Using Related List’ input. Options include selecting a related list from the Main Object, an object related to it, or even grandchildren-related lists. Once chosen, you can map fields from the selected related list into the nodes within the JSON list.
    • To create a JSON list with manually defined elements, known as a parameter list, navigate to the ‘Advanced’ section within the ‘Edit Node’ popup. In the ‘Build this JSON List’ input, select ‘As a Parameter list based on fields.’ If chosen, you can manually add list elements later, specifying values for each node. Map fields from the Main Object (or child record if you are already in another list) to customize each element.
  • List of Values: If you select this option, you can send a list of values in the node. It can be a list of static values or a field mapped from an object or a related list of objects, the latter generating a list with more than one entry. You can also build the list manually with values from different sources by selecting the “Define each element in the list individually” option, See “Selecting a Source” below for details.
  • Single Value: Use this option to send single values in a node. It can be a static text, number, or a field mapped to the value of the node. See “Selecting a Source” below for details.
  • Built using an Apex Class: This gives you the option to use an Apex class to generate this node. More details in the “Using Apex to generate a node” section below.

 

Selecting a Source

If you select “List of Values” or “Single Value” in the Node Type input, you are able to select a source for the value. That can be a Static value, a Salesforce Field, a Formula based on the fields of the current object, a value from a Custom Setting or a value from a Custom Metadata record. For “List of Values” only, you also have the option to “Define each element in the list individually”.

  • Static Value: This is a static option for if you want to send the same value every time the callout is made. Enter the value you want it to send in the Static Value field. If you choose “Array”, enter all the values that you want to send, one per line.
  • Field: Here you can select any field from the Main Object or related objects you selected in the Callout Template. If you select a related list of objects and Node Type is Array, it will create a list with values from each related record.
    •  
    • The Field Selector allows you to select fields from the Main Object, any related object (up to 5 levels deep) and any related list (one level). For example, if the Main Object is Account, the selection below allows you to select the Username of the Owner of the account.
    • If the selected field is a Blob field (for example Attachment -> Body or ContentVersion -> VersionData), then you will also be asked to provide the encoding to be used: Base64, Hex or Raw (which only works for UTF-8 content)
  • Formula: This allows you to build a formula using the current object’s fields that will be used to generate the node. 
    • Clicking the Edit icon will open the Formula editor. See more details in the “Using Formulas” section of this user guide.
  • Custom Metadata: This allows you to map a field from a Custom Metadata Type record.
    • Clicking the Edit icon will open the Custom Metadata selector.
  • Custom Setting: This allows you to map a field from a Hierarchy or List Custom Setting record.
    • Clicking the Edit icon will open the Custom Setting selector.
  • Define each element in the list individually: This allows you to select a source for each value added to the list. This helps you build more complex lists that are defined based on criteria.

 

Node Data Type

This lets you choose the data type of the JSON node value. It can be Text, Number or a True/False value. Text values include out of the box fields like First Name, Last Name, Description and so on. Any field in Salesforce that is a data type of the following will need to be Text:

  • Auto-Number
  • Email
  • Phone
  • Text
  • Text Area
  • Text Area (Long)
  • Text Area (Rich)
  • Text Area (Encrypted)
  • URL

When you are mapping Date or DateTime fields, you need to use Text as well. The Date fields are sent in the standard yyyy-MM-dd format and the DateTime fields are set in the standard yyyy-MM-ddTHH:mm:ss.sssZ format.

When Text is selected, you have the option to send empty strings when a value is null. If that option is selected, if the mapped value is null, then an empty string is sent instead. You can find that option in the “Advanced” section of the “Edit Node” popup.

Using Apex to generate a node

If the body of the callout is too complex to be generated with the methods above, you have the option to use an Apex class to generate part of the request body. Simply select “Built using an Apex Class” in Node Type field and enter the class name that will generate that part of the JSON body. The class needs to be global and extend the d_wh.JSONNodeCallable abstract class.

Below is an example class that can be used to generate a JSON node.

global class TestCallable extends d_wh.JSONNodeCallable {

    global override Object Generate(List<Id> mainRecordIds, Object cachedData) {

        // Add code to generate json node

    }

}

The mainRecordIds parameter contains the list of ids of the used record(s). If the callout is a “One Record” type, the list will contain one Id. If no Main Object is selected, the list will be empty.

The cachedData parameter contains the object returned by the CacheDataCallable class, and null if a cache class is not mentioned ( See details about CacheDataCallable below).

In order to generate a JSON body, the returned object can be one of the following types: String, Decimal, Boolean, List<Object>, Map<String, Object>. If list type or map type is returned, Object inside then should also be one of the types: String, Decimal, Boolean, List<Object>, Map<String, Object>.

If you select at least one node that is generated using Apex, you are provided with the option to run a cache class before generating nodes. In order to avoid hitting the SOQL limits when using apex to generate nodes (for example in lists), you can specify a class to run once, before the JSONNodeCallable classes. The class needs to be global and extend the d_wh.CacheDataCallable abstract class.

Below is an example class that can be used to cache some of the data before building the JSON.

global class TestCallable extends d_wh.CacheDataCallable {

    global override Object Cache(List<Id> mainRecordIds) {

        // Add code to query and return data to be cached

    }

}

The mainRecordIds parameter contains the list of ids of the used record(s).

The response can be any type of object. It will be sent back to you as the cachedData parameter in the JSONNodeCallable class you use generating the node.  

Dynamically generating nodes (node criteria)

“In the ‘Advanced’ section of the ‘Edit Node’ popup, you can determine whether a node is generated during runtime by utilizing a formula. Locate the ‘This node is generated (criteria)’ field. By default, it is set to ‘Always,’ but you have the option to edit it and incorporate a formula. This allows you to dynamically decide if the node should be generated based on criteria from the main object.

Create from sample JSON request

If you have a JSON Sample from the API documentation from the app or platform being implemented, you can create your Request Body quickly by utilizing the ‘Generate from sample JSON’ button. This enables you to quickly map your Main Object to your external system bypassing creating Node Names with stand-in values.

One example may be Quickbooks. Let’s say you are looking at the Account Request Body details on the API documentation of QuickBooks. You can find a Request Body sample to copy and pull into the Declarative Webhooks app:

image56

 

After you copy the Request Body, select the ‘Generate from sample JSON’ button and paste your example.

Click “Generate and replace exiting body” and you will see this has been added into the Request Body of your Callout Template. From here, you can begin mapping Salesforce fields from your Main Object by selecting the edit icon next to the row and replacing the static values from the sample body. This helps you to quickly map without having to manually create each Node Name with a provided guide from your external system API documentation.

NOTE: If you have started mapping in the JSON Builder and you opt to utilize the ‘Generate from sample JSON’ button, your previous mapping will be overwritten. It is advised you begin with your sample JSON first before mapping additional Nodes.  

Generate based on fields from Main Object

If you want to generate the JSON body based on fields from the main object, click the “Generate from Main Object fields” button.

It will open a popup that will allow you to select the fields used to generate the body.

Once you select all the fields, click “Generate and replace existing body” and see the JSON body being generated for you.

NOTE: If you have started mapping in the JSON Builder and you opt to utilize the ‘Generate from Main Object fields’ button, your previous request body will be overwritten.