I have a pretty simple JSON Document and want to get all emailAddresses that belong to an 'email'-Contact with a specific source of origin.
This is the JSON:
{
"errors": [
],
"individuals": [
{
"contacts": [
{
"id": "urn:uuid:fb383908-4c4a-a00e-3cd2-1f9acf3caecf",
"origins": [
{
"source": "sourceA"
}
],
"type": "eMail",
"emailAddress": "sourceA#email.com",
"verificationStatus": "verification denied"
},
{
"id": "urn:uuid:fb383908-4c4a-a00e-3cd2-1f9acf3caecf",
"origins": [
{
"source": "sourceA"
}
],
"type": "address",
"verificationStatus": "verification denied"
}
],
"id": "urn:uuid:cebb2e06-8bcf-8125-2eee-bb04f8965bcd"
},
{
"contacts": [
{
"id": "urn:uuid:fb383908-4c4a-a00e-3cd2-aaaaaaaaa",
"origins": [
{
"source": "sourceB"
}
],
"type": "eMail",
"emailAddress": "sourceB#email.com",
"verificationStatus": "verification denied"
},
{
"id": "urn:uuid:fb383908-4c4a-a00e-3cd2-aaaaaaaaa",
"origins": [
{
"source": "sourceB"
}
],
"type": "address",
"verificationStatus": "verification denied"
}
],
"id": "urn:uuid:cebb2e06-8bcf-8125-2eee-bbbbbbbbbbbb"
}
]
}
And this is the JsonPath i have come up with:
$..contacts[?(#.type == 'eMail' && #.origins[?(#.source=='sourceA')])].emailAddress
In my mind this should only return one email address, namely sourceA#email.com but i always get both addresses.
Where is my mistake?
PS: sorry for the title, i honestly did not know how to phrase this better
Use the index position for origins instead of using nested expressions.
$..contacts[?(#.type == 'eMail' && #.origins[0].source =='sourceA')].emailAddress
If you are using Jayway JsonPath you can use filter operators like contains
$..contacts[?(#.type == 'eMail' && #.origins[*].source contains 'sourceA')].emailAddress
OR in
$..contacts[?(#.type == 'eMail' && 'sourceA' in #.origins[*].source)].emailAddress
OR empty
$..contacts[?(#.type == 'eMail' && #.origins[?(#.source=='sourceA')] empty false)].emailAddress
Related
I have a requirement to roll a collection of nodes that uses the current node name (within the collection) and for the value take each child nodes value (single node) into a string array, then use the parents key as the key.
Given.
{
"client": {
"addresses": [
{
"id": "27ef465ef60d2705",
"type": "RegisteredOfficeAddress"
},
{
"id": "b7affb035be3f984",
"type": "PlaceOfBusiness"
},
{
"id": "a8a3bef166141206",
"type": "EmailAddress"
}
],
"links": [
{
"id": "29a9de859e70799e",
"type": "Director",
"name": "Bob the Builder"
},
{
"id": "22493ad4c4fd8ac5",
"type": "Secretary",
"name": "Jennifer"
}
],
"Names": [
{
"id": "53977967eadfffcd",
"type": "EntityName",
"name": "Banjo"
}
]
}
}
from this the output needs to be
{
"client": {
"addresses": [
"RegisteredOfficeAddress",
"PlaceOfBusiness",
"EmailAddress"
],
"links": [
"Director",
"Secretary"
],
"Names": [
"EntityName"
]
}
}
What is the best way to achieve this? Any pointers to what/how to do this would be greatly appreciated.
Ron.
You can iterate over entries of your client object first with the help of the $each function, then get types for each of them, and combine via $merge:
{
"client": client
~> $each(function($list, $key) {{ $key: $list.type }})
~> $merge
}
Live playground: https://stedi.link/OpuRdE9
I have problem with webhook, or to be more accurate - with sending data with POST method using endpoint.
I am using this endpoint for POST method:
https://edapi.campaigner.com/v1/Import/AddOrUpdate?ApiKey=apikey_value
and this JSON snippet:
{
"Subscribers": [
{
"EmailAddress": "email",
"CustomFields": [
{
"FieldName": "Source",
"Value": "source"
},
{
"FieldName": "Campaign",
"Value": "campaign"
},
{
"FieldName": "Medium",
"Value": "medium"
}
],
"Lists": [
200468800
]
}
]
}
But, after I set automation workflow to trigger transfer data from one database (provider 1) to another base (provider 2) I get error:
{
"ContactsSubmitted": 1,
"Successes": 0,
"Failures": [
{
"EmailAddress": "email",
"ErrorCode": 101,
"Message": "Invalid Email Address"
}
]
}
Any suggestions? Additional explanation: FieldName is name from provider 2 and field value is name from provider 1.
Missing [some_variable ] is part where my code throws and error. So, the right code is:
{
"Subscribers": [
{
"EmailAddress": "[email]",
"CustomFields": [
{
"FieldName": "Source",
"Value": "[source]"
},
{
"FieldName": "Campaign",
"Value": "[campaign]"
},
{
"FieldName": "Medium",
"Value": "[medium]"
}
],
"Lists": [
200468800
]
}
]
}
I'm looking to go from a JSON structure that looks something like this:
{
"id": "955559665",
"timestamp": "2022-04-21 00:00:19",
"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0 Safari/605.1.15",
"remote_addr": "123.456.789.012",
"read": "0",
"data": {
"80928111": {
"field": "80928111",
"value": "Z01234567",
"flat_value": "Z01234567",
"label": "ID",
"type": "text"
},
"90924321": {
"field": "90924321",
"value": {
"first": "Jane",
"last": "Doe"
},
"flat_value": "first = Jane\nlast = Doe",
"label": "Name",
"type": "name"
},
"88888770": {
"field": "88888770",
"value": "jdoe001#gmail.com",
"flat_value": "jdoe001#gmail.com",
"label": "Email",
"type": "email"
},
"12345678": {
"field": "12345678",
"value": "https://www.google.com/subdomain/attachment/file.txt",
"flat_value": "https://www.google.com/subdomain/attachment/file.txt",
"label": "Choose File",
"type": "file"
}
}
}
Ultimately to something like this:
{
"name_val":"Name: first = Jane\nlast = Doe\nEmail: jdoe001#gmail.com\n",
"file": {
"id": "12345678C",
"name": "file.txt"
}
}
In the original JSON, the 'data' object represents a form submission. Each sub object represents a field on the submitted form. The only distinction I'm interested in is the 'type' of field identified as 'file'.
Every response that is not of 'file' type, I want to concatenate into one large String value that looks like: 'label1: flat_value1\nlabel2: flat_value2...'
Note, the number of actual fields is variable.
Then I need a second object to show the field of type 'file', by identifying the 'field' id, and the name of the file.
I've gotten pieces of this to work. For example, using pluck and filter, I've been able to separate the types of fields.
Something like this:
%dw 2.0
output application/json
---
[
"fields": payload.data pluck(
{
"field": $."label",
"value": $."flat_value",
"type": $."type"
}
) filter ($."type" != "file") default "",
"files": payload.data pluck(
{
"type": $."type",
"fieldId": $."field"
}
) filter ($."type" == "file") default ""
]
Gives me:
[
{
"fields": [
{
"field": "ID",
"value": "Z01234567",
"type": "text"
},
{
"field": "Name",
"value": "first = Jane\nlast = Doe",
"type": "name"
},
{
"field": "Email",
"value": "jdoe001#gmail.com",
"type": "email"
}
]
},
{
"files": [
{
"type": "file",
"fieldId": "12345678"
}
]
}
]
And playing around with a modified JSON input, I was able to easily see concatenation similar to how I want to see it, but not quite there:
%dw 2.0
output application/json
var inputJson = [
{
"field": "ID",
"value": "Z01234567",
"type": "text"
},
{
"field": "Name",
"value": "first = Jane\nlast = Doe",
"type": "name"
}
]
---
inputJson map ((value, index) -> value.field ++ ': ' ++ value.value)
Gives me:
[
"ID: Z01234567",
"Name: first = Jane\nlast = Doe"
]
But I can't seem to put it all together and go from Beginning to End.
There are several ways to implement this. I recommend to try to encapsulate the parts that you get working and use them as building blocks.
%dw 2.0
output application/json
fun fields(x) = x.data pluck(
{
"field": $."label",
"value": $."flat_value",
"type": $."type"
}
) filter ($."type" != "file") default ""
fun files(x) = x.data pluck(
{
"type": $."type",
"fieldId": $."field"
}
) filter ($."type" == "file") default ""
---
{
name_val: fields(payload) reduce ((item,acc="") -> acc ++ item.field ++ ': ' ++ item.value ++ "\n"),
files: files(payload)[0]
}
Output:
{
"name_val": "ID: Z01234567\nName: first = Jane\nlast = Doe\nEmail: jdoe001#gmail.com\n",
"files": {
"type": "file",
"fieldId": "12345678"
}
}
I have below JSON and i require to validate the status based on given id in my automation script. For that JSON path require
[
[
{
"id": 9905130204,
"category": {
"id": 0,
"name": "string"
},
"name": "doggie",
"photoUrls": [
"string"
],
"tags": [
{
"id": 0,
"name": "string"
}
],
"status": "available"
},
{
"id": 9905130203,
"name": "Jeffs Doggie11/6/2019 2:44:53 PM",
"photoUrls": [
"string"
],
"tags": [],
"status": "available"
},
{
"id": 9905130217,
"name": "Goot Doggie",
"photoUrls": [
"https://media.karousell.com/media/photos/products/2017/09/14/doggi_door_stopper_1505372529_5cdd1eba0"
],
"tags": [],
"status": "available"
}
]
]
I want to extract "status": "available" based on "id": 9905130217. No clue how to do that, please help.
You can use the following jsonpath expression to find the status where id = n:
$.[?(#.id == 'n')].status
So, for your specific case:
$.[?(#.id == '9905130217')].status
Note, that this assumes id is unique.
I've got the following JSON being sent to the server from the browser:
{
"title": "Testing again 2",
"abstract": "An example document",
"_href": "http://google.com",
"tags": [ "person" ],
"attributes": [ {
"id": 1,
"type": "TEXT",
"data": "test"
} ],
"sections": [ {
"id": 1,
"type": "LIST",
"data": [ {
"revision": 124,
"text": "test"
} ]
} ]
}
I need to make sure that the keys "_href", "id" and "revision" are not in the object anyplace at any level.
I found this but it doesn't quite work.
I searched npms.io and found has-any-deep which you can use after JSON.parse ing the JSON.
you need to parse json then check into the data
var str = '{
"title": "Testing again 2",
"abstract": "An example document",
"_href": "http://google.com",
"tags": [ "person" ],
"attributes": [ {
"id": 1,
"type": "TEXT",
"data": "test"
} ],
"sections": [ {
"id": 1,
"type": "LIST",
"data": [ {
"revision": 124,
"text": "test"
} ]
} ]
}';
var jsonObj = JSON.parse(str);
if ( typeof jsonObj._href == 'undefined') {
// check
}
A simple but not 100% foolproof solution would be to parse the JSON to string, and just search for your keys:
var a = JSON.stringify(JSONObject);
var occurs = false;
['"_href"', '"id"', '"version"'].forEach(function(string) {
if(a.indexOf(string) > -1) occurs = true;
});
The issue of course, is if there are values that match
'_href', 'id', 'version' in your JSON. But if you want to use native JS, I guess this is a good bet.
var a = {
"title": "Testing again 2",
"abstract": "An example document",
"tags": [ "person" ],
"attributes": [ {
"type": "TEXT",
"data": "test"
} ],
"sections": [ {
"type": "_href asdad",
"data": [ {
"text": "test"
} ]
} ]
},
b = {
"title": "Testing again 2",
"abstract": "An example document",
"_href": "http://google.com",
"tags": [ "person" ],
"attributes": [ {
"id": 1,
"type": "TEXT",
"data": "test"
} ],
"sections": [ {
"id": 1,
"type": "LIST",
"data": [ {
"revision": 124,
"text": "test"
} ]
} ]
},
aJson = JSON.stringify(a),
bJson = JSON.stringify(b);
var occursa = false, occursb = false;
['"_href"', '"id"', '"version"'].forEach(function(string) {
if(aJson.indexOf(string) > -1) { occursa = true};
});
['"_href"', '"id"', '"version"'].forEach(function(string) {
if(bJson.indexOf(string) > -1) { occursb = true};
});
console.log("a");
console.log(occursa);
console.log("b");
console.log(occursb);
You could use the optional second reviver parameter to JSON.parse for this:
function hasBadProp(json) {
let badProp = false;
JSON.parse(json, (k, v) => {
if ([_href", "id", "revision"].includes(k)) badProp = true;
return v;
});
return badProp;
}