• The webhooks will send out information based on the save event of a contract, company, and/or project profile.  
  • The webhooks must first be initially configured in the application; go to Admin >> System Settings >> API Settings (See screenshot below)
    • Default Media Type
      • Sends out data in either XML or JSON format
    • Default Secret
      • A secret that can be used to later verify that the data coming over is from Contracts; this information will come over in the header of the XML/JSON data
    • Default URL
      • Sends data to this URL  
    • Hook Type
      • After Save – Data will be sent after the save action on a company/contract/project object
      • Before Save – Data is sent over before the save action happens to allow data to be verified before the save happens
      • It is important to note that the data being sent over will be the same for the before and after save action.  The key difference is that with Before Save you can check the data coming over before the object is saved

  • Once these are set click New to create a new hook.  If you leave the URL, Media Type, and Secret fields empty they will use the defaults.
  • Once the hook is set up the application will send out data to whichever URL you specified.  
  • Once the webhooks are configured you will have to set up a servlet so that you can receive that data. (see the below code)
  • Your filename will be in the URL for example the below code is named posttest.java so you would set your default URL to localhost:8080/posttest

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Enumeration;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class WebhookServletExample extends HttpServlet {
	
	private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(WebhookServletExample.class);
	private static final String SECRET = "ExampleSecret";

	private boolean verifySecret(final String message, final String signature) throws Exception {
		final Mac mac = Mac.getInstance("HmacSHA512");
		mac.init(new SecretKeySpec(SECRET.getBytes(StandardCharsets.UTF_8), "HmacSHA512"));
		final byte[] bytes = mac.doFinal(message.getBytes(StandardCharsets.UTF_8));
		return Hex.encodeHexString(bytes).equals(signature);
	}

	@Override
	protected void doPost(final HttpServletRequest request, final HttpServletResponse response) throws IOException, ServletException {
		for (final Enumeration<String> headers = request.getHeaderNames(); headers.hasMoreElements(); ) {
			final String headerName = headers.nextElement();
			log.info(headerName + " : " + request.getHeader(headerName));
		}
		log.info("--- Data ---");
		final String data = IOUtils.toString(request.getInputStream());
		log.info(data);
		final boolean validSignature;
		try {
			validSignature = verifySecret(data, request.getHeader("signature"));
		} catch (final Exception e) {
			throw new RuntimeException("Error reading signature", e);
		}
		log.info("Signature is valid? " + validSignature);
		response.getOutputStream().print("{\"success\": true, \"message\":\"json message\"}");
	}
}
CODE