6

I have created a REST Endpoint (exposed on force.com site) to allow Webhook messages.

The third party service will POST data to the webhook that looks like this:

Body:

{ "channel": "server", "email": "[email protected]", "messageId": "test-message-37q7z9", "projectId": "oYOQY8rnYw", "replay": true, "timestamp": "2018-12-04T16:22:37.195Z", "traits": { "trait1": 1, "trait2": "test", "trait3": true }, "type": "identify", "userId": "test-user-x1nyrr" } 

How can I read the attributes in the traits object? (i.e. trait1, trait2). I should note the attributes in the traits object may increase/decrease in size so this needs to be somewhat dynamic.

This is what I have so far but I'm not sure how to parse the payload.

@RestResource(urlMapping='/webhook') global class WebhookReq { @HttpPost global static String doPost() { //Blob name = RestContext.request.params.get('name'); String traits = RestContext.request.params.get('traits'); RestRequest req = RestContext.request; String result = JSON.deserialize(req.getBody()); return result; } } 

2 Answers 2

8

Since the types can be mixed, you need to use either the JSONParser (I would not recommend this) or JSON.deserializeUntyped. Here's the latter method:

Map<String, Object> params = (Map<String, Object>)JSON.deserializeUntyped( RestContext.request.requestBody.toString() ); Map<String, Object> traits = (Map<String, Object>)params.get('traits'); for(String key: traits.keySet()) { Object value = traits.get(key); if(value instanceof integer) { ... } else if(value instanceof string) { ... } else if(value instanceof boolean) { ... } } 

Since I don't know what you intend to do with this, I can't really write more, but at this point, you should have everything you need.

4
  • May I know why why you don't recommend JSONParser? Commented Dec 28, 2021 at 8:10
  • 1
    @NBR It has terrible performance characteristics, is difficult to use correctly, and usually requires writing more code than any other means of parsing JSON. I have literally used it exactly zero times in any code I've written for any project since I started writing Apex code in 2007. Commented Dec 28, 2021 at 9:03
  • Thanks.! How to get the value of object field? I am getting runtime error if I try to use obj.Name. Is there a way without creating a class? Something like obj.get('name' ). obj.get('industry')? This is not a sObject. Commented Dec 28, 2021 at 13:50
  • @NBR See this Q&A and others in our canonical-qa tag that speak about JSON parsing. We've got a lot content available on this topic. Commented Dec 28, 2021 at 15:15
3

You can use deserializeUntyped(jsonString) here as below. Refer to the example details on the documentation.

Map<String, Object> myMap = (Map<String, Object>) JSON.deserializeUntyped(req.getBody().toString()); Map<String, Object> traitsMap = (Map<String, Object>)myMap.get('traits'); for(Integer i = 1; i < traitsMap.size(); i++) { system.debug(traitsMap.get('traits'+i)); // will print the value of traits<i> } 

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.