<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <title>Best approach for handling a webhook</title>
  <link rel="self" href="https://uat.liferay.dev/c/message_boards/find_thread?p_l_id=119785294&amp;threadId=121160436" />
  <subtitle>Best approach for handling a webhook</subtitle>
  <id>https://uat.liferay.dev/c/message_boards/find_thread?p_l_id=119785294&amp;threadId=121160436</id>
  <updated>2026-08-02T06:52:36Z</updated>
  <dc:date>2026-08-02T06:52:36Z</dc:date>
  <entry>
    <title>RE: RE: Best approach for handling a webhook</title>
    <link rel="alternate" href="https://uat.liferay.dev/c/message_boards/find_message?p_l_id=119785294&amp;messageId=121238401" />
    <author>
      <name>Scarletake Bwi</name>
    </author>
    <id>https://uat.liferay.dev/c/message_boards/find_message?p_l_id=119785294&amp;messageId=121238401</id>
    <updated>2021-11-09T05:50:21Z</updated>
    <published>2021-11-09T05:50:20Z</published>
    <summary type="html">&lt;p&gt;hi&lt;/p&gt;
&lt;p&gt;I create a mvc-module, and relate the service-builder api.&lt;/p&gt;
&lt;p&gt;and create a site and page(public), pull the mvc-module in the page.&lt;/p&gt;
&lt;p&gt;i use view.jsp to do receiving job, &lt;/p&gt;
&lt;p&gt;by this way, i do not need to generate a new WAR and i can modify it
  just like other module.&lt;/p&gt;
&lt;p&gt;This is the best way I think so far&lt;/p&gt;</summary>
    <dc:creator>Scarletake Bwi</dc:creator>
    <dc:date>2021-11-09T05:50:20Z</dc:date>
  </entry>
  <entry>
    <title>RE: RE: Best approach for handling a webhook</title>
    <link rel="alternate" href="https://uat.liferay.dev/c/message_boards/find_message?p_l_id=119785294&amp;messageId=121235813" />
    <author>
      <name>Scarletake Bwi</name>
    </author>
    <id>https://uat.liferay.dev/c/message_boards/find_message?p_l_id=119785294&amp;messageId=121235813</id>
    <updated>2021-11-06T09:42:59Z</updated>
    <published>2021-11-06T09:42:58Z</published>
    <summary type="html">&lt;p&gt;Hi Pete&lt;/p&gt;
&lt;p&gt;thank you, very much.&lt;/p&gt;
&lt;p&gt;yeah, but my goal is to develop, receive, process, and send back all
  by liferay.&lt;br /&gt; if there have any new news, I will share with you&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;have a nice day&lt;/p&gt;</summary>
    <dc:creator>Scarletake Bwi</dc:creator>
    <dc:date>2021-11-06T09:42:58Z</dc:date>
  </entry>
  <entry>
    <title>RE: Best approach for handling a webhook</title>
    <link rel="alternate" href="https://uat.liferay.dev/c/message_boards/find_message?p_l_id=119785294&amp;messageId=121235391" />
    <author>
      <name>Pete Helgren</name>
    </author>
    <id>https://uat.liferay.dev/c/message_boards/find_message?p_l_id=119785294&amp;messageId=121235391</id>
    <updated>2021-11-05T18:06:33Z</updated>
    <published>2021-11-05T18:06:32Z</published>
    <summary type="html">&lt;p&gt;I may not be fully understanding either.  The only way I was able to
  handle the JSON that the api calback passed was to create a servlet
  that received the callback, grabbed the json payload from the request
  and then passed it to the S/B api.  So, yes, I had an SB project that
  handled the &amp;quot;backend&amp;quot;.  But I also created a second project,
  a servlet, that actually handled the &amp;quot;frontend&amp;quot;, the
  callback,  and then passed the payload to the SB.  The service builder
  itself doesn't recieve the callback, the servlet does and then the
  servlet calls the SB API to handle the backend.&lt;br /&gt;
  &lt;br /&gt; ​​​​​​​I hope that makes it a little clearer.  I could never
  get just the service builder to handle everything.&lt;/p&gt;
&lt;p&gt;Pete&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;</summary>
    <dc:creator>Pete Helgren</dc:creator>
    <dc:date>2021-11-05T18:06:32Z</dc:date>
  </entry>
  <entry>
    <title>RE: RE: Best approach for handling a webhook</title>
    <link rel="alternate" href="https://uat.liferay.dev/c/message_boards/find_message?p_l_id=119785294&amp;messageId=121234877" />
    <author>
      <name>Scarletake Bwi</name>
    </author>
    <id>https://uat.liferay.dev/c/message_boards/find_message?p_l_id=119785294&amp;messageId=121234877</id>
    <updated>2021-11-05T05:08:27Z</updated>
    <published>2021-11-05T05:08:26Z</published>
    <summary type="html">&lt;p&gt;hi Pete&lt;/p&gt;
&lt;p&gt;thank you so mush for reply, i think i did not explain well.&lt;/p&gt;
&lt;p&gt;Chatwoot will send a POST request with the payload to the configured
  URL, and i plan use a rest generated by SB to got it.&lt;/p&gt;
&lt;p&gt;but i do not know how to get request's body(payload).&lt;/p&gt;
&lt;p&gt;the steps are&lt;/p&gt;
&lt;p&gt;1. i create a service-builder module, it will have two modules, -api
  and -service&lt;/p&gt;
&lt;p&gt;2. i create a entity, set remote-service  as true&lt;/p&gt;
&lt;p&gt;3. in my ServiceImpl, i add a method with notation
  @AccessControlled(guestAccessEnabled = true)&lt;/p&gt;
&lt;p&gt;4. and i build service, generate wsdl....etc.&lt;/p&gt;
&lt;p&gt;yes, it will be called, but i do not now how to get request and it's parameter&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;for now, i create a dynamic web project, and put the WAR to webapp,
  use jsp to do it&lt;/p&gt;
&lt;pre&gt;
&lt;code class="language-java"&gt;&amp;lt;%@ page import=&amp;quot;java.io.*&amp;quot;%&amp;gt;

&amp;lt;%

	String payloadBody = null;
	StringBuilder stringBuilder = new StringBuilder();
	BufferedReader bufferedReader = null;

	try {
		InputStream inputStream = request.getInputStream();
		if (inputStream != null) {
			bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
			char[] charBuffer = new char[128];
			int bytesRead = -1;
			while ((bytesRead = bufferedReader.read(charBuffer)) &amp;gt; 0) {
				stringBuilder.append(charBuffer, 0, bytesRead);
			}
		} else {
			stringBuilder.append(&amp;quot;&amp;quot;);
		}
	} catch (IOException ex) {
		throw ex;
	} finally {
		if (bufferedReader != null) {
			try {
				bufferedReader.close();
			} catch (IOException ex) {
				throw ex;
			}
		}
	}
%&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;</summary>
    <dc:creator>Scarletake Bwi</dc:creator>
    <dc:date>2021-11-05T05:08:26Z</dc:date>
  </entry>
  <entry>
    <title>RE: Best approach for handling a webhook</title>
    <link rel="alternate" href="https://uat.liferay.dev/c/message_boards/find_message?p_l_id=119785294&amp;messageId=121233531" />
    <author>
      <name>Pete Helgren</name>
    </author>
    <id>https://uat.liferay.dev/c/message_boards/find_message?p_l_id=119785294&amp;messageId=121233531</id>
    <updated>2021-11-04T12:40:53Z</updated>
    <published>2021-11-04T12:40:52Z</published>
    <summary type="html">&lt;p&gt;Not much magic to it.  The json passed into the addVoiceMailRecord
  S/B metthod  is then rendered into an object using the import
  org.json.JSONObject;  So I have:&lt;/p&gt;
&lt;p&gt;
  &lt;br /&gt;         JSONObject vmrecord = new JSONObject(json);&lt;/p&gt;
&lt;p&gt;
  &lt;br /&gt; that renders the string into an object and at that point it is
  just parsing the json obejct to get what I need and then use other S/B
  methods to create the database object and populate it with the
  properties from the json object&lt;br /&gt;  &lt;/p&gt;
&lt;pre&gt;
&lt;code class="language-java"&gt;SimpleDateFormat formatter = new SimpleDateFormat(&amp;quot;yyyy-MM-dd'T'HH:mm:ss&amp;quot;, Locale.ENGLISH);
			
	VMRecord vmr = createVMRecord(id);
				
		try {
			vmr.setDate_time(formatter.parse(date_time));
			vmr.setGeneric_payload_account_id(generic_payload_account_id);
			vmr.setDownload_url(download_url);
			vmr.setDuration(duration);
			vmr.setCaller_number(caller_number);
			vmr.setCaller_number_type(caller_number_type);
			vmr.setCaller_name(caller_name);
			vmr.setCallee_user_id(callee_user_id);
			vmr.setCallee_number(callee_number);
			vmr.setCallee_number_type(callee_number_type);
			vmr.setCallee_name(callee_name);
			vmr.setCallee_extension_type(callee_extension_type);
			vmr.setCallee_id(callee_id);
			
			addVMRecord(vmr);
				
		} catch (Exception e) {
			// TODO Auto-generated catch block
				e.printStackTrace();
		}
			&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
  &lt;br /&gt; Thats about it&lt;/p&gt;</summary>
    <dc:creator>Pete Helgren</dc:creator>
    <dc:date>2021-11-04T12:40:52Z</dc:date>
  </entry>
  <entry>
    <title>RE: RE: Best approach for handling a webhook</title>
    <link rel="alternate" href="https://uat.liferay.dev/c/message_boards/find_message?p_l_id=119785294&amp;messageId=121228443" />
    <author>
      <name>Scarletake Bwi</name>
    </author>
    <id>https://uat.liferay.dev/c/message_boards/find_message?p_l_id=119785294&amp;messageId=121228443</id>
    <updated>2021-11-03T03:18:29Z</updated>
    <published>2021-11-03T03:18:29Z</published>
    <summary type="html">&lt;p&gt;hi Pete&lt;/p&gt;
&lt;p&gt;can you share how your SB method work with that payload.&lt;/p&gt;
&lt;p&gt;i use Chatwoot, webhook of Chatwoot will send a POST request with the
  payload to the configured URL.&lt;/p&gt;
&lt;p&gt;but i do not know how to get payload infomation from SB method(exposed REST).&lt;/p&gt;
&lt;p&gt;now i do is very like yours, but i use dynamic web project and jsp to
  do it.&lt;/p&gt;
&lt;p&gt;thank you in advance.&lt;/p&gt;</summary>
    <dc:creator>Scarletake Bwi</dc:creator>
    <dc:date>2021-11-03T03:18:29Z</dc:date>
  </entry>
  <entry>
    <title>RE: Best approach for handling a webhook</title>
    <link rel="alternate" href="https://uat.liferay.dev/c/message_boards/find_message?p_l_id=119785294&amp;messageId=121168129" />
    <author>
      <name>Pete Helgren</name>
    </author>
    <id>https://uat.liferay.dev/c/message_boards/find_message?p_l_id=119785294&amp;messageId=121168129</id>
    <updated>2021-09-25T19:14:08Z</updated>
    <published>2021-09-25T19:13:50Z</published>
    <summary type="html">&lt;p&gt;OK.  Hearing no suggestions, I went ahead and created a front end
  servlet to listen for the webhook calls and then called the SB methods
  to update the DB with the webhook content.  The only
  &amp;quot;tricky&amp;quot; part is that the webhook only passes a json object
  in the body.  So the solution at the servlet end was to do this:&lt;br /&gt;  &lt;/p&gt;
&lt;pre&gt;
&lt;code class="language-java"&gt;	public void doPost(HttpServletRequest request, HttpServletResponse response)
	  {
		
		// grab the whole body
		
		try {
			BufferedReader br = request.getReader();
			
			String json = br.lines().collect(Collectors.joining());
			
			 VMRecordLocalServiceUtil. addVoiceMailRecord(json);
			 
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	 }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The SB method took the json onject as a string, converted it to a
  JSON object, and then created a DB object, added the properties and
  added the record to the DB.  Don't know if it is the easiet approach
  to handling a webhook that passes a json object but this works and is simple.&lt;/p&gt;</summary>
    <dc:creator>Pete Helgren</dc:creator>
    <dc:date>2021-09-25T19:13:50Z</dc:date>
  </entry>
  <entry>
    <title>Best approach for handling a webhook</title>
    <link rel="alternate" href="https://uat.liferay.dev/c/message_boards/find_message?p_l_id=119785294&amp;messageId=121160435" />
    <author>
      <name>Pete Helgren</name>
    </author>
    <id>https://uat.liferay.dev/c/message_boards/find_message?p_l_id=119785294&amp;messageId=121160435</id>
    <updated>2021-10-04T17:20:51Z</updated>
    <published>2021-09-22T01:22:14Z</published>
    <summary type="html">&lt;p&gt;I am working with a Zoom webhook that triggers when a voicemail is
  left by a caller.  I created a table to store the webhook details for
  each call and used the service builder to create the DB IO.  I was
  *hoping* that I could just expose the SB API in such a way that I
  wouldn't need much additional plumbing to make it work but I can't
  figure out how to handle receiving the webhook api call and the json payload.&lt;br /&gt;
  &lt;br /&gt; The Zoom documentation provides this example payload:&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;{
  &amp;quot;event&amp;quot;: &amp;quot;phone.voicemail_received&amp;quot;,
  &amp;quot;event_ts&amp;quot;: 1626759486127,
  &amp;quot;payload&amp;quot;: {
    &amp;quot;account_id&amp;quot;: &amp;quot;2AB-cdEFGhijkLnop3qRs&amp;quot;,
    &amp;quot;object&amp;quot;: {
      &amp;quot;id&amp;quot;: &amp;quot;0388975092074598b47330a6a87e9a7b&amp;quot;,
      &amp;quot;date_time&amp;quot;: &amp;quot;2021-07-20T05:38:04Z&amp;quot;,
      &amp;quot;download_url&amp;quot;: &amp;quot;example.com&amp;quot;,
      &amp;quot;duration&amp;quot;: 30,
      &amp;quot;caller_number&amp;quot;: &amp;quot;15550100&amp;quot;,
      &amp;quot;caller_number_type&amp;quot;: 1,
      &amp;quot;caller_name&amp;quot;: &amp;quot;Dana&amp;quot;,
      &amp;quot;callee_user_id&amp;quot;: &amp;quot;user&amp;quot;,
      &amp;quot;callee_number&amp;quot;: &amp;quot;15550101&amp;quot;,
      &amp;quot;callee_number_type&amp;quot;: 1,
      &amp;quot;callee_name&amp;quot;: &amp;quot;Alex&amp;quot;,
      &amp;quot;callee_extension_type&amp;quot;: &amp;quot;string&amp;quot;,
      &amp;quot;callee_id&amp;quot;: &amp;quot;user&amp;quot;
    }
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;The SB method I exposed will work with that payload.  But when I use
  Postman to test I have to add a a bit more to the body&lt;/p&gt;
&lt;p&gt;The URL :  http://localhost:9080/api/jsonws/invoke&lt;/p&gt;
&lt;p&gt;And this added to the body:&lt;br /&gt;
  {&amp;quot;/myapp.vmrecord/add-voice-mail-record&amp;quot;:  then the payload
  and then close with a }&lt;/p&gt;
&lt;p&gt;So the whole body becomes:&lt;br /&gt;  &lt;/p&gt;
&lt;pre&gt;
&lt;code class="language-java"&gt;{&amp;quot;/myapp.vmrecord/add-voice-mail-record&amp;quot;:
{
        &amp;quot;event&amp;quot;: &amp;quot;phone.voicemail_received&amp;quot;,
        &amp;quot;event_ts&amp;quot;: 1626759486127,
        &amp;quot;payload&amp;quot;: {
            &amp;quot;account_id&amp;quot;: &amp;quot;2AB-cdEFGhijkLnop3qRs&amp;quot;,
            &amp;quot;object&amp;quot;: {
                &amp;quot;id&amp;quot;: &amp;quot;0388975092074598b47330a6a87e9a7b&amp;quot;,
                &amp;quot;date_time&amp;quot;: &amp;quot;2021-07-20T05:38:04Z&amp;quot;,
                &amp;quot;download_url&amp;quot;: &amp;quot;example.com&amp;quot;,
                &amp;quot;duration&amp;quot;: 30,
                &amp;quot;caller_number&amp;quot;: &amp;quot;15550100&amp;quot;,
                &amp;quot;caller_number_type&amp;quot;: 1,
                &amp;quot;caller_name&amp;quot;: &amp;quot;Dana&amp;quot;,
                &amp;quot;callee_user_id&amp;quot;: &amp;quot;user&amp;quot;,
                &amp;quot;callee_number&amp;quot;: &amp;quot;15550101&amp;quot;,
                &amp;quot;callee_number_type&amp;quot;: 1,
                &amp;quot;callee_name&amp;quot;: &amp;quot;Alex&amp;quot;,
                &amp;quot;callee_extension_type&amp;quot;: &amp;quot;string&amp;quot;,
                &amp;quot;callee_id&amp;quot;: &amp;quot;user&amp;quot;
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
  &lt;br /&gt; So the question is:  Can i invoke the SB API (method) and pass
  the payload without adding
  the &amp;quot;/myapp.vmrecord/add-voice-mail-record&amp;quot;: to the body
  (which I cannot do because Zoom is the one who sends the body in the
  webhook call as a POST)&lt;br /&gt;
  &lt;br /&gt; I
  tried http://localhost:9080/api/jsonws/invoke/myapp.vmrecord/add-voice-mail-record/json 
  but it doesn't recognize the signature.&lt;br /&gt;
  &lt;br /&gt; So the question is:  What is the best appraoch when you want a
  webhook to return json data and LR to consune it?  The SB part is
  sorted, the question is, do I need to frontend with with a portlet or
  other application to be able to consume it?&lt;br /&gt;
  &lt;br /&gt;  &lt;/p&gt;</summary>
    <dc:creator>Pete Helgren</dc:creator>
    <dc:date>2021-09-22T01:22:14Z</dc:date>
  </entry>
</feed>
