Page tree
Skip to end of metadata
Go to start of metadata

Post Webhook workflow sends an HTTP POST notification to a specified URL (see Managing Workflows to learn how to add, edit and remove workflows.)

Notification payload contains the following data:

  1. formId, 
  2. campaignId, 
  3. sessionId, 
  4. trackingCode and 
  5. field values (if Send Fields parameter is checked).
Workflow Property NameDescription
URL

URL where the POST request will be sent to.

Handshake Key

An optional value that will be sent as HTTP Header "X-SmartForms-Handshake-Key". It can be used to pass client-specified data for authenticity and functional purposes.

JSON Payload

Flag that determines the payload format.

When checked, the data will be posted in JSON Format.

When not checked, the data will be posted as POST form parameters.

Send FieldsWhen checked, values for all fields are also posted.
Retry TimeoutNumber of minutes that shall be waited for before making another attempt to POST data after a failed request.
Retry Maximum CountSpecifies the maximum number of attempts to execute the workflow.

POST Payload Parameters

Parameter NameDescription
sessionIdUnique Id (UUID) of a form session
campaignIdUnique id (UUID) of a campaign this form session is running in
formIdUnique id (UUID) of a form version this form session is running
trackingCodeUnique code assigned to this form session

fieldNameA

fieldNameB

fieldNameX

Value of field which has name "fieldNameA"

Value of field which has name "fieldNameB"

Value of field which has name "fieldNameX"

POST Payload Example
// Below is a printout log of HTTP request parameters
sessionId=5aadabcc-a557-4d14-a898-606a4ce6b96e
campaignId=dd73a941-1001-4232-85fc-e835cbc6b50e
formId=4fefeeea-39db-4613-bb77-914c52ee353f
trackingCode=AYFE8XTK
user.name=John Singleton
user.email=john.singleton@myemail.com
user.attachment.1=Bond.pdf;750869


JSON Payload Format

PropertyDescription
sessionIdUnique Id (UUID) of a form session
campaignIdUnique id (UUID) of a campaign this form session is running in
formIdUnique id (UUID) of a form version this form session is running
trackingCodeUnique code assigned to this form session
fieldsAn array of field details
Field Properties
nameName of a field
idA session-unique id (UUID) of the field
cloneIndexA clone number, a positive integer when field was defined is a part of a clonable group and form session contains more than one clones of a field with the same name
validatedA flag that indicates whether this field has passed form validation
hiddenA flag that indicates whether this field is visible on session form
valueType

Type of a field valuie, possible value types are:

  • TEXT,
  • INTEGER,
  • FLOAT,
  • FILE_ATTACHMENT,
  • DATE,
  • TIME_OF_DAY,
  • DATETIME,
  • HTML
valueValue of a field
JSON Payload Example
{
  "formId": "4fefeeea-39db-4613-bb77-914c52ee353f",
  "campaignId": "dd73a941-1001-4232-85fc-e835cbc6b50e",
  "trackingCode": "YSLWQJTL",
  "sessionId": "a2d4683b-1621-4f29-a0c9-2ea0c795155d",
  "fields": [
    {
      "cloneIndex": 0,
      "validated": true,
      "hidden": false,
      "valueType": "TEXT",
      "name": "user.name",
      "id": "7667670b-513c-44b5-843d-4720a9a0c1e9",
      "value": "John Singleton"
    },
    {
      "cloneIndex": 0,
      "validated": true,
      "hidden": false,
      "valueType": "TEXT",
      "name": "user.email",
      "id": "b51731c9-6f47-4ad4-9135-eceb058b14ef",
      "value": "john.singleton@myemail.com"
    },
    {
      "cloneIndex": 0,
      "validated": true,
      "hidden": false,
      "valueType": "FILE_ATTACHMENT",
      "name": "user.attachment",
      "id": "eab119a0-eec1-4bc4-a9a5-3e95accab07f",
      "value": "Bond.pdf;750869"
    }
  ]
}

Sample Code for Client-Side WebHook Implementations

Below we have listed several code snippets for different platforms and implementation flavours:

Java POST WebHook Servlet
package au.com.fifthocean.webhook.samples;

import java.io.IOException;
import java.util.Enumeration;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class SmartformsWebHookServlet extends javax.servlet.http.HttpServlet {

	private static final Log logger = LogFactory.getLog(SmartformsWebHookServlet.class);

	private final static String SMARTFORMS_HADSHAKE_KEY = "SMARTFORMS-QWERTY1234";

	@Override
	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// in do GET, shall be disallowed
		response.setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
	}

    // Method to process form POST (non JSON payload) notification
	@Override
	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		logger.info("In webhook servlet ");
		
		String handShakeKey = request.getHeader("X-SmartForms-Handshake-Key");
		if (handShakeKey == null || !handShakeKey.equals(SMARTFORMS_HADSHAKE_KEY)) {
			response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
			return;
		}
		Enumeration<String> en = request.getParameterNames();
		while (en.hasMoreElements()) {
			String pname = en.nextElement();
			logger.info(pname + "=" + request.getParameter(pname));
		}
		
		if(this.processWebhookDataAsForm(request.getParameterMap())) {
            // success
			response.setStatus(HttpServletResponse.SC_OK);
			return;
        } else {
            // not OK, SmartForms will repeat it until the maximum retry limit is reached
			response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
			return;
        }
		
	}
	
	private boolean processWebhookDataAsForm(Map<String, String[]> map) {
        // some processing inside this class or outside
        logger.info("webhook data as Form map size=" + map.size());    
        return false;
    }
}


Java REST JSON WebHook Listener
package au.com.fifthocean.webhook.samples;

import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Path("/webhook")
public class SmartformsWebHookListener {
	@Context
    private HttpServletRequest request;

	private static final Logger logger = LoggerFactory.getLogger(SmartformsWebHookListener.class);

	private final static String SMARTFORMS_HADSHAKE_KEY = "SMARTFORMS-QWERTY1234";
	
	// method to process JSON payload
	@POST
	@Consumes(MediaType.APPLICATION_JSON)
	@Path("/notify/form/submit")
	public Response newFormSubmittedAsJsonFormat(String input) {

		logger.info("In /webhook/notify/form/submit");
		String handShakeKey = request.getHeader("X-SmartForms-Handshake-Key");		
		if (handShakeKey == null || !handShakeKey.equals(SMARTFORMS_HADSHAKE_KEY)) {
			return Response.status(Response.Status.UNAUTHORIZED).build();				
		}
		
		if (this.processWebhookDataAsJson(input)) {
			// success
			return Response.status(Response.Status.OK).build();	
		} else {
			// not OK, SmartForms will repeat it until the maximum retry limit
			// is reached
			return Response.status(Response.Status.BAD_REQUEST).build();	
		}

	}
    
    private boolean processWebhookDataAsJson(String data) {
        // some processing inside this class or outside
        logger.info("webhook data as JSON " + data);     
        return false;

    }
}


Liferay DXP WebHook Listener
package au.com.fifthocean.webhook.samples;

import java.util.Collections;
import java.util.Enumeration;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;

import org.osgi.service.component.annotations.Component;

import com.liferay.portal.kernel.json.JSONException;
import com.liferay.portal.kernel.json.JSONFactoryUtil;
import com.liferay.portal.kernel.json.JSONObject;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;

@ApplicationPath("/webhook")
@Component(immediate = true, property = {"jaxrs.application=true"}, service = Application.class)
public class SmartformsWebHookListener extends Application {
	private static final Log logger = LogFactoryUtil.getLog(SmartformsWebHookListener.class);
	@Context HttpServletRequest request;
	
	public Set<Object> getSingletons() {
		return Collections.<Object>singleton(this);
	}

	private final static String SMARTFORMS_HADSHAKE_KEY = "SMARTFORMS-QWERTY1234";
	
	// method to process JSON payload
	@POST
	@Path("/notify/form/submit/as-json")
	public void newFormSubmittedAsJsonFormat(String input) {
		logger.info("In /webhook/notify/form/submit-as-json");
		
		String handShakeKey = request.getHeader("X-SmartForms-Handshake-Key");
		if(handShakeKey == null || !handShakeKey.equals(SMARTFORMS_HADSHAKE_KEY) ) {
			throw new WebApplicationException(Response.Status.UNAUTHORIZED);			
		}
		
		JSONObject data;
		try {
			data = JSONFactoryUtil.createJSONObject(input);
		} catch (JSONException e) {
			e.printStackTrace();
			throw new WebApplicationException(Response.Status.BAD_REQUEST);
		}
		
		if(this.processWebhookDataAsJson(data)) {
			// success
			return;
		} else {
			// not OK, SmartForms will repeat it until the maximum retry limit is reached
			throw new WebApplicationException(Response.Status.BAD_REQUEST);
		}
	}	
	
	// method to process non-JSON payload
	@POST
	@Path("/notify/form/submit")
	public void newFormSubmittedAsFormPost() {
		logger.info("In /webhook/notify/form");
		
		String handShakeKey = request.getHeader("X-SmartForms-Handshake-Key");
		if(handShakeKey == null || !handShakeKey.equals(SMARTFORMS_HADSHAKE_KEY) ) {
			throw new WebApplicationException(Response.Status.UNAUTHORIZED);			
		}
		
		Enumeration<String> en = this.request.getParameterNames();
		while(en.hasMoreElements()) {
			String pname = en.nextElement();
			logger.info(pname + "=" + this.request.getParameter(pname));
		}
		
		if(this.processWebhookDataAsForm(this.request.getParameterMap())) {
			// success
			return;
		} else {
			// not OK, SmartForms will repeat it until the maximum retry limit is reached
			throw new WebApplicationException(Response.Status.BAD_REQUEST);
		}
	}	
	
	private boolean processWebhookDataAsForm(Map<String, String[]> map) {
		// some processing inside this class or outside
		logger.info("webhook data as Form map size=" + map.size());		
		return false;
	}

	private boolean processWebhookDataAsJson(JSONObject data) {
		// some processing inside this class or outside
		logger.info("webhook data as JSON " + data.toJSONString());		
		return false;
	}
}


  • No labels