Parsing Service Bus Queue message in Logic App parameter function - json

I receive a error from my SharePoint Get-Item action when I try to use data from the Service Bus message triggering my Logic App (inner xml omitted):
Unable to process template language expressions in action 'Get_items' inputs at line '1' and column '1641': 'The template language function 'json' parameter is not valid. The provided value '<?xml version="1.0" encoding="utf-8"?>
<Projektaufgabe id="b92d6817-694e-e611-80ca-005056a5e651" messagename="Update">
...
</Projektaufgabe>' cannot be parsed: 'Unexpected character encountered while parsing value: . Path '', line 0, position 0.'.
The decoded message xml looks okay even quoted in the error message.
The received queue message body seems okay - only the ContentType is empty:
(ContentData truncated)
{
"ContentData": "77u/PD94bWwgdmVyc2lvbj0iMS4wIiBl...=",
"ContentType": "",
"ContentTransferEncoding": "Base64",
"Properties": {
"DeliveryCount": "1",
"EnqueuedSequenceNumber": "20000001",
"EnqueuedTimeUtc": "2016-07-29T09:03:40Z",
"ExpiresAtUtc": "2016-08-12T09:03:40Z",
"LockedUntilUtc": "2016-07-29T09:04:10Z",
"LockToken": "67796ed8-a9f0-4f6a-952b-ccf4eda00071",
"MessageId": "f3ac2ce4e7b6417386611f6817bf5da1",
"ScheduledEnqueueTimeUtc": "0001-01-01T00:00:00Z",
"SequenceNumber": "31806672388304129",
"Size": "1989",
"State": "Active",
"TimeToLive": "12096000000000"
},
"MessageId": "f3ac2ce4e7b6417386611f6817bf5da1",
"To": null,
"ReplyTo": null,
"ReplyToSessionId": null,
"Label": null,
"ScheduledEnqueueTimeUtc": "0001-01-01T00:00:00Z",
"SessionId": null,
"CorrelationId": null,
"TimeToLive": "12096000000000"
}
My parsing function for the SharePoint Get-Item OData filter looks like this:
#{json(base64ToString(triggerBody().ContentData)).Projektaufgabe.id}
I already tried to separate decoding and casting to string:
#{json(string(decodeBase64(triggerBody().ContentData))).Projektaufgabe.id}
Since it seems to be an issue decoding the message, I reckoned it wouldn't help much receiving a json message instead of xml from the Service Bus queue.

So from what I can see you are trying to convert an xml to json. You are very close - only issue is #json() expects either
A string that is a valid JSON object
An application/xml object to convert to JSON
Here, the #base64toString() is converting to a string, but you really need to let #json() know this is #2 and not #1, so changing expression to this should work:
#{json(xml(base64toBinary(triggerBody()[contentdata])))[foo]}
Let me know

Related

422 error trying to save json data to the database

I'm trying to save data to my MySql db from a Node method. This includes a field called attachments.
console.log(JSON.stringify(post.acf.attachments[0])); returns:
{
"ID": 4776,
"id": 4776,
"title": "bla",
"filename": "bla.pdf",
"filesize": 1242207,
"url": "https://example.com/wp-content/uploads/bla.pdf",
"link": "https://example.com/bla/",
"alt": "",
"author": "1",
"description": "",
"caption": "",
"name": "bla",
"status": "inherit",
"uploaded_to": 0,
"date": "2020-10-23 18:05:13",
"modified": "2020-10-23 18:05:13",
"menu_order": 0,
"mime_type": "application/pdf",
"type": "application",
"subtype": "pdf",
"icon": "https://example.com/wp-includes/images/media/document.png"
}
This is indeed the data I want to save to the db:
await existing_post.save({
...
attachments: post.acf.attachments[0],
)};
However, the attachments field produces a 422 server error (if I comment out this field, the other fields save without a problem to the db). I'm not getting what is causing this error. Any ideas?
I've also tried
await existing_post.save({
...
attachments: post.acf.attachments,
)};
but then it seems to just save "[object Object]" to the database.
The field in the database is defined as text. I've also tried it by defining the field as json, but that made no difference.
exports.up = function (knex, Promise) {
return knex.schema.table("posts", function (table) {
table.longtext("attachments");
});
};
The 422 error code is about the server unable to process the data you are sending to it. In your case, your table field is longtext when post.acf.attachments seems like an object. That's why it saves [object Object] to your db (It is the return value of the toString() method).
Try using
await existing_post.save({
...
attachments: JSON.stringify(post.acf.attachments),
)};
MySQL and knex both support the JSON format, I'd suggest you change the field to json. (See knex docs and mysql 8 docs). You'll stiil need to stringify your objects tho.
EDIT: I just saw that Knex supports jsonInsert (and plenty other neat stuff) as a query builder that should be useful for you.
Mysql also support a large range of cool stuffs for handling jsons
In addition, when you fetch the results in the database, you'll need to parse the JSON result to get an actual JSON object:
const acf = await knex('posts').select('acf').first();
const attachment = JSON.parse(acf.attachment;
Knex also provide jsonExtract that should fill your needs (See also the mysql json_extract

How to parse nested JSON, within a string, using Kusto

I have a Python Azure Function that produces custom logging messages when the Function executes. I need to pull out some of the JSON values nested in the logging message.
How can I use Kusto to access the nested JSON within the logging message string?
Example logging message:
Desired values marked with <----------
####### EventGrid trigger processing an event:
{
"id": "long-guid",
"data": {
"api": "FlushWithClose",
"requestId": "long-guid",
"eTag": "long-guid",
"contentType": "application/octet-stream",
"contentLength": 16264, <----------------------
"contentOffset": 0,
"blobType": "BlockBlob",
"blobUrl": "https://function.blob.core.windows.net/parentdir/childdir/file.name",
"url": "https://function.dfs.core.windows.net/parentdir/childdir/file.name", <---- JUST FILE.NAME here
"sequencer": "long-guid",
"identity": "long-guid",
"storageDiagnostics": {
"batchId": "long-guid"
}
},
"topic": "/subscriptions/long-guid/resourceGroups/resourceGroup/providers/Microsoft.Storage/storageAccounts/accountName",
"subject": "/blobServices/default/containers/containerName/blobs/childDir/file.name",
"event_type": "Microsoft.Storage.BlobCreated"
} #######
I imagine it has something to do with the Kusto extend function, but piping in...
| extend parsedMessage = todynamic(message)
| project timestamp, test = parsedMessage["id"]
...yields only an empty test column
message in your specific case isn't a valid JSON payload - as it has the ###... EventGrid trigger processing an event: prefix (and a somewhat similar suffix).
That is why todynamic() isn't able to process it and why you're not able to reference properties in the JSON payload that's included in it.
Ideally, you would change the payload you ingest to be a valid JSON payload, and re-type the target column to dynamic instead of string.
If you can't do that, you can use the substring() function or parse operator to get everything but the aforementioned prefix/suffix, and parse the output of that using todynamic()
though note that doing that each time you query the data bears runtime overhead that could be avoided by following the advice above.

How to handle api responses with null values? Kotlin

Ive been trying to handle this kind of situation where the api call response gives me this type of response and I no longer know how I will handle it. The response sometimes exposes a value and sometimes a null resulting for app to crash. The api also changes depending in the situation. Sometime the field is not there, sometime its there but has a value of null, and sometimes has a value of empty string. Do you know any work around to handle this situation?
Api response:
"valrep_landimp_lot_details": [
{
"valrep_landimp_propdesc_area": "1000",
"valrep_landimp_propdesc_block": null,
"valrep_landimp_propdesc_lot": "3",
"valrep_landimp_propdesc_lot_classification": null,
"valrep_landimp_propdesc_place": null,
"valrep_landimp_propdesc_registered_owner": "RANK A",
"valrep_landimp_propdesc_registry_date_day": "01",
"valrep_landimp_propdesc_registry_date_month": "01",
"valrep_landimp_propdesc_registry_date_year": "1980",
"valrep_landimp_propdesc_registry_of_deeds": "Makati City",
"valrep_landimp_propdesc_survey_nos": null,
"valrep_landimp_propdesc_tct_no": "T-33333"
}
]
Data class:
#field:SerializedName("valrep_landimp_propdesc_block")
val valrepLandimpPropdescBlock: String? = null
How call the variable:
it?.valrepLandimpPropdescBlock!!
Error : kotlin.KotlinNullPointerException
Thank you in advance!

"status_code": 422, "error_code": "REQUEST_PARAM_PARSE", "detail": "The 'data' parameter must be a list"

I’m using the HTTP Request Wizard to set up a POST request to MonkeyLearn. This endpoint expects a JSON in the request body (or payload body). It must be an object with the data property and a list of the texts you want to classify as value. For example:
{
"data": [
"This is the best sentiment analysis tool ever!!!",
]
}
So, in the HTTP Request Wizard, I set up under Parameters:
Name: data
Value: "This is the best sentiment analysis tool evert!!!"
Type: GetorPost
However, in the preview response I get:
{
"status_code": 422,
"error_code": "REQUEST_PARAM_PARSE",
"detail": "The ‘data’ parameter must be a list"
}
I can’t figure out what list the endpoint expect?
I am not familiar with the "HTTP Request Wizard" and cannot find it either. But from what you've written it is clear that you are sending a string and not an array of strings. You value should look like this: Value: [ "This is the best sentiment analysis tool evert!!!" ]

Zapier Catch (Raw) Hook JSON parsing issue

I would like to configure sync between two different CRMs (Clevertap and Intercom) using Zapier and Webhooks. In general Clevertap sends the following JSON to webhook:
{
"targetId": 1548328164,
"profiles": [
{
"event_properties": {
"MSG-sms": true,
"MSG-push": true,
"businessRole": "EMPLOYEE",
"Mobile Number": "123123123123",
"Name": "Artem Hovtvianisa",
"Title": "Mr",
"Last Name": "Hovtvianisa",
"Gender": "M",
"Customer type": "Business Account Holder",
"MSG-email": true,
"First Name": "Artem",
"Last seen IP": "111.177.74.50",
"tz": "GMT+0200",
"International customer": "yes",
"isBusiness": true,
"Email": "xxxyyy#gmail.com",
"Identity": 15675
},
"objectId": "e32e4de3c1e84b2d9bab3707c92cd092",
"all_identities": [
"15675",
"xxxyyy#gmail.com"
],
"email": "xxxyyy#gmail.com",
"identity": "15675"
}
]
}
Zapier provides two types of catch webhook: regular and Raw.
Catch Raw Hook
When I use this type, JSON raw data will be handled OK and on the next step (Zapier JS code app) I am able to pass proper JSON data like in example above.
However when I use simple JS code to parse JSON object and get profiles[0] array value I get the following error "TypeError: Cannot read property '0' of undefined"
JS Code from Code step:
var result = JSON.parse(JSON.stringify(inputData));
console.log(result.profiles[0]);
return result;
Catch Hook
In case I use regular Catch Hook, hook parse data in some odd way, like this:
JSON.parse cannot recognize this structure.
Please advise how can I handle Webhook Zapier step in a proper way in order to get profiles[0] array item values?
Thanks in advance!
David here, from the Zapier Platform team. You're on the right track!
Catch Raw Hook is the way to go here. Your issue is that the data is coming in as a string and you're re-stringifying it before parsing it, which gets you back to where you came from. A simpler version:
JSON.stringify("asdf") // => "\"asdf\"", quotes in the string
JSON.parse("\"asdf\"") // => "asdf", the original string
"asdf".profiles // => undefined
undefined[0] // => error, cannot read property "0" of undefined
Instead, just parse it and you're good to go!
// all your variables are already in "inputData", so yours,
// also named inputData, must be referenced explicitly.
const result = JSON.parse(inputData.inputData);
return {result: result, firstProfile: result.profiles[0]};