Forum Discussion
We actually added this back in 19.2, but looks like it didn't make it into any release notes or into our Freemarker documentation -- I will make sure this gets added to our Freemarker documentation. In the meantime, you should be able to do this to parse JSON out of the request body:
<#assign requestBody = http.request.body />
<#assign requestBodyObj = utils.json.fromJson(requestBody) />
(Please note that the http.request.body object will only work when used in Endpoints -- it will throw an exception if used in a component on a community page)
-Doug
Hey DougS . Thanks for replying. I tried what you have mentioned above and that doesn't seem to be working when I am sending a webhook to my endpoint where I'm trying to get the request body. I basically just wrote your above-mentioned code and then I'm taking the requestBodyObj and putting it in a restadmin call as a variable to update a metadata field but nothing is getting set over there. Is there a different way to do that with your given code?
- DougS6 years agoKhoros Oracle
I tested this out on a site that was on a version that is higher than 19.1:
First I checked what version my site was on by going to https://mycommunitystagesite.com/status/version (replaced mycommunitystagesite with my community stage site's domain name) -- the site I was using was on 19.2 (19.2-release r1905141529).
After I confirmed my site was on 19.2, I added an endpoint to test out this functionality with. I went to Studio > Endpoints tab and created an endpoint named "test-request-body-json" with content type set to "application/json" and this Freemarker logic:
<#if ("POST" == http.request.method)> <#assign requestBody = http.request.body?trim /> <#if requestBody?starts_with("{")> <#assign requestBodyObj = utils.json.fromJson(requestBody) /> { "testValue": "${requestBodyObj.test}" } </#if> </#if>
I then issued an HTTP POST to the endpoint with a JSON payload that it expects to deal with (replaced the URL with the correct one for the endpoint I just created):
curl -X POST \ https://mycommunitystagesite.com/plugins/custom/mycompany/mycommunity/test-request-body-json \ -H 'Content-Type: application/json' \ -d '{ "test": "test value" }'
I got back the following response when I made that call:
HTTP/1.1 200 status: 200 Date: Mon, 08 Jul 2019 18:17:56 GMT Server: Apache Set-Cookie: LithiumVisitor=~27qCFEIuWNM27x0WA~KF9NHbFXpA8CcsDu2w8X0PiU5WUHrjc0zUqkczJSAbEV9sa_mN8fhAvAyycO7nbT846YrhqNV-6Sv_4SJi-aUw..; Expires=Thu, 05-Jul-2029 18:17:56 GMT; Path=/; HttpOnly Pragma: no-cache Expires: Thu, 01 Jan 1970 00:00:00 GMT Cache-Control: no-cache Cache-Control: no-store Vary: Origin,Access-Control-Request-Headers,Access-Control-Request-Method,Access-Control-Allow-Credentials,Access-Control-Max-Age,Accept-Encoding Content-Language: en-US Content-Encoding: gzip Keep-Alive: timeout=10, max=150 Connection: Keep-Alive Transfer-Encoding: chunked Content-Type: application/json;charset=UTF-8 { "testValue": "test value" }
I hope that helps you get things sorted. If you find you are on a version that is lower than 19.2, you can open a support case to request an upgrade to the stage site.
-Doug
- pp_016 years agoMentor
Hi DougS. With the code that you provided, we figured out that when the webhook is sent to our endpoint, initial if condition and the second line to get the request body is working, but this statement in your code
<#assign requestBodyObj = utils.json.fromJson(requestBody) />
doesn't seem to be working and after putting the check for if the body has_content we got to know that in the POST request something is coming to our endpoint but when I'm trying to get it in the restadmin call, nothing seems to set in my metadata where I'm trying to set the request body or any value in the object which comes in the body. I read in this article https://developer.khoros.com/khoroscaredevdocs/docs/working-with-webhooks that
requestBody: The entire body of the request, read as a UTF8-encoded stringand based on this when I'm getting the request body in my variable I also tried putting ?('utf-8') but that also didn't help. Is there something that I'm missing?
Below is my endpoint code -
<#attempt> <#assign alpha = http.request.body?trim?('utf-8') /> <#if alpha?? && alpha?has_content && alpha?is_string > <#assign alpha = alpha?eval /> <#assign updateProfile = restadmin('/users/sso_id/id/settings/name/profile.cert_info/set?value=L1 ${alpha.id}') /> <#elseif alpha?? && alpha?has_content && alpha?is_hash > <#assign updateProfile = restadmin('/users/sso_id/id/settings/name/profile.cert_info/set?value=L2') /> <#else> <#assign updateProfile = restadmin('/users/sso_id/id/settings/name/profile.cert_info/set?value=L3') /> </#if> <#recover> <#assign updateProfile = restadmin('/users/sso_id/id/settings/name/profile.cert_info/set?value=LEVEL4') /> </#attempt>
Also for an example, in the webhook documentation from where we are calling our endpoint, something like this is what we are supposed to get in the request body -
{ "id": "628fcaa9-cfd3-4a9b-aa62-9973ac938ad6", "organization_id": "a0d325d9-d8cb-466f-b515-c767949f7e9a", "event_type": "badge.created", "occurred_at": "2014-04-01T14:41:00Z" }
- DougS6 years agoKhoros Oracle
In my tests, utils.json.fromJson seems to be working.
You shouldn't need to add the ?('UTF-8') to the http.request.body call, as it returns the body as a UTF-8 encoding string already.
You might want to try something like this for your endpoint:
<#function doRestV1Call uri admin=false>
<#if admin>
<#assign restCall = restadmin />
<#else>
<#assign restCall = rest />
</#if>
<#return restCall(uri) />
</#function><#function setProfileField ssoId name val admin=false>
<#return doRestV1Call("/users/sso_id/" + ssoId + "/settings/name/" + name + "/set?value=" + val, true) />
</#function><#function setCertInfo ssoId val>
<#return setProfileField(ssoId, "profile.cert_info", val?url, true) />
</#function><#function getCertInfo ssoId>
<#return doRestV1Call("/users/sso_id/" + ssoId + "/settings/name/profile.cert_info", true).value />
</#function><#assign errorMsg = "" />
<#if ("POST" == http.request.method)>
<#attempt>
<#assign alpha = http.request.body />
<#if alpha?? && alpha?has_content && alpha?is_string>
<#assign alpha = utils.json.fromJson(alpha) />
<#assign updateProfile = setCertInfo(alpha.id, "L1" + alpha.id) />
<#elseif alpha?? && alpha?has_content && alpha?is_hash>
<#-- this should not happen -->
<#assign updateProfile = setCertInfo(alpha.id, "L2") />
<#else>
<#assign errorMsg = "no request body" />
</#if>
<#recover>
<#assign errorMsg = .error />
</#attempt><#if errorMsg?length lt 1>
<#attempt>
<#assign profileVal = getCertInfo(alpha.id) />
<#recover>
<#assign errorMsg = .error />
</#attempt>
</#if>
<#else>
<#assign errorMsg = "request must be an HTTP POST." />
</#if><#if errorMsg?length gt 0>
{
"successful": false,
"message": "${errorMsg?json_string}"
}
<#else>{
"successful": true,
"message": "profile updated",
"value": "${profileVal?json_string}"
}
</#if>-Doug
- pp_016 years agoMentor
Hello DougS . Sorry for bothering you with my last reply. The code which you provided on Monday seems to be working. I figured it out on Friday after posting my above comment. The statement
<#assign requestBodyObj = utils.json.fromJson(requestBody) />
was not working for me initially because of God knows what reason but when I tried again it worked and I got to know why it is crucial for my requirement as it is converting JSON string to a freemarker hash. The error was in my endpoint code in line no.4
<#assign updateProfile = restadmin('/users/sso_id/id/settings/name/profile.cert_info/set?value=L1 ${alpha.id}') />
where I have given space between the text "L1" and ${alpha.id} because of which nothing was getting set in my metadata. Removing that resolved that error. Your answers and suggestions have been very helpful. Thank you.
Related Content
- 9 years ago
- 12 years ago