Stringify JSON in Logic App - json

We are sending messages to a service bus using a logic app. These messages will later be consumed by another service, the service expects the message content to be a string - essentially a stringified JSON object, with escape characters.
We are not able to find a method to stringify a JSON object in Logic Apps. Even if we explicitly provide a escaped string the logic app itself detects that it's stringified JSON and unescapes it and then sends it as a JSON object. We don't want that, we simply want it to send the string as it is. We have already tried changing the content type to text/plain, it does not work. The logic app always sends the unescaped string as JSON.
This post on MSDN: https://social.msdn.microsoft.com/Forums/office/en-US/e5dee958-09a7-4784-b1bf-facdd6b8a568/post-json-from-logic-app-how-to-escape-data?forum=azurelogicapps is of no help because doing this will violate the request contract of the message consuming service

Do you need the stringified message to include opening and closing double quotes?
I've tried this and it worked for me.
I have my JSON object as an output of a compose
Then, I initialised a variable with the Base64 encoded value of the escaped stringified JSON (you need to add ALL the proper escaping required,
mine was just a PoC)
Then, you send the variable already in Base64 to Service Bus. (You need to remove the encoding on that action).
"actions": {
"Compose_JSON_Object": {
"inputs": {
"message": "I want this as a string"
},
"runAfter": {},
"type": "Compose"
},
"Initialise_Variable_with_Stringified_JSON_Base64_Encoded": {
"inputs": {
"variables": [
{
"name": "jsonAsStringBase64",
"type": "String",
"value": "#base64(concat('\"', replace(string(outputs('Compose_JSON_Object')), '\"', '\\\"'), '\"'))"
}
]
},
"runAfter": {
"Compose_JSON_Object": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Send_message": {
"inputs": {
"body": {
"ContentData": "#variables('jsonAsStringBase64')",
"ContentType": "text/plain"
},
"host": {
"connection": {
"name": "#parameters('$connections')['servicebus']['connectionId']"
}
},
"method": "post",
"path": "/#{encodeURIComponent(encodeURIComponent('temp'))}/messages",
"queries": {
"systemProperties": "None"
}
},
"runAfter": {
"Initialise_Variable_with_Stringified_JSON_Base64_Encoded": [
"Succeeded"
]
},
"type": "ApiConnection"
}
},
This way, I got the message stringified.
HTH

Related

How to encode special characters in Wiremock request body?

I'm using Wiremock server to mock responses and using JSON format to mock responses.
{
"request":
{
"url": "/token",
"method": "POST",
"bodyPatterns" : [{
"contains": "username=test_user#gmail.com&password=passwordtest_security_token"
}]
},
"response":
{
"status": 200,
"headers":
{
"Content-Type" : "application/json"
},
"jsonBody": {"message": "ok"}
}
This is not working as the '#' in the email is not encoded. I need to pass "test_user%40gmail" for the request to work.
Here the change is only at one place. But for other mocks, request bodies have many special characters**(#,%*\n\s)**. Is there any way to handle the encoding part in the Wiremock.
Also, is there way to encode the string in url?
In the above example there is an accolade missing which prevents is from loading in WireMock. The below example is complete:
{
"request": {
"url": "/token",
"method": "POST",
"bodyPatterns": [{
"contains": "username=test_user#gmail.com&password=passwordtest_security_token"
}
]
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"jsonBody": {
"message": "ok"
}
}
}
In your question you highlighted that you need to use %40 instead of #. I have been unable to replicate this scenario. As I'm unsure if you're posting through a form, or raw string.
In the case that you use a regular Form Data option this results in failure to match.
But sending it as a raw body the result is quite the opposite. The example behaves exactly as you would described it should. Below is a screenshot of my Postman result:

Parsing string containing complex struct

I'm receiving a third-party API payload response like:
{
"message": "Validation failed because [{reason=CONDITIONAL_INVALID_VALUE, field=/targetingCriteria, batchIndex=0, type=INVALID_VALUE, message=/locale cannot be set to en if urn:li:adTargetingFacet:interfaceLocales is set to urn:li:locale:it_IT, parameters={field1=/locale, value2=urn:li:locale:it_IT, value1=en, field2=urn:li:adTargetingFacet:interfaceLocales, key=}}, {reason=FIELD_VALUE_TOO_LOW, field=dailyBudget, batchIndex=0, type=INVALID_VALUE, message=/dailyBudget/amount value 1 cannot be lower than 10.00, parameters={min=10.00, field=/dailyBudget/amount, costType=CPM, type=SPONSORED_UPDATES, value=1, key=}}]",
"status": 400
}
and I'd like to transform in something like:
{
"errors": [{
"reason": "CONDITIONAL_INVALID_VALUE",
"field": "/targetingCriteria",
"batchIndex": "0",
"type": "INVALID_VALUE",
"message": "/locale cannot be set to en if urn:li:adTargetingFacet:interfaceLocales is set to urn:li:locale:it_IT",
"parameters": "{field1=/locale, value2=urn:li:locale:it_IT, value1=en, field2=urn:li:adTargetingFacet:interfaceLocales, key=}"
},
{
"reason": "FIELD_VALUE_TOO_LOW",
"field": "dailyBudget",
"batchIndex": "0",
"type": "INVALID_VALUE",
"message": "/dailyBudget/amount value 1 cannot be lower than 10.00",
"parameters": "{min=10.00, field=/dailyBudget/amount, costType=CPM, type=SPONSORED_UPDATES, value=1, key=}"
}
]
}
But I'm struggling to find a clear golang approach to this problem, the main problems are:
no valid json is available: word are not correctly quoted with "
= symbol instead of :
nested graphs bracket
I'm currently try to transform in a valid json string and then parse as json but I have various problem with nested elements
Any idea?
EDIT: This is what I've done right now: https://play.golang.org/p/B7bdPCJoHc2

How to add Response Card in Lex using PutIntent method?

I am trying to add a Response Card in lex using putIntent(). In AWS the putIntent method accepts responseCard as a String but how to add title, subTitle, ImageUrl, button values, and button names at the time of creating an Intent using response card parameter through putIntent?
So can anyone please help me to solve the issue. Provide a sample input where response card as String which can contain the above attributes. Thank you in advance.
"slots": [
{
"description": "string",
"name": "string",
"priority": number,
"responseCard": "string",
"sampleUtterances": [ "string" ],
"slotConstraint": "string",
"slotType": "string",
"slotTypeVersion": "string",
"valueElicitationPrompt": {
"maxAttempts": number,
"messages": [
{
"content": "string",
"contentType": "string",
"groupNumber": number
}
],
"responseCard": "string" --(how to pass title, imageUrl and other attributes)
}
Looks like you got the correct slots portion of the full response format from Lex API PutIntent.
The responseCard format can be found at Lambda Input Response Format
"responseCard": {
"version": integer-value,
"contentType": "application/vnd.amazonaws.card.generic",
"genericAttachments": [
{
"title":"card-title",
"subTitle":"card-sub-title",
"imageUrl":"URL of the image to be shown",
"attachmentLinkUrl":"URL of the attachment to be associated with the card",
"buttons":[
{
"text":"button-text",
"value":"Value sent to server on button click"
}
]
}
]
}
Assuming you create that responseCard object in the format above as a variable named responseCard, then to make that object a string to pass in PutIntent try:
JSON.stringify(responseCard) if using Node.js, or
json.dumps(responseCard, separators=(',',':')) if using Python.

How to Post JSON Array/string value?

I need to post some values to a REST service. I'm using POSTMAN rest client for my test and i can post string, integer, boolean values to rest service there is no problem. But i could not post array values ;
I am using this parameter, this parameter is working except Array values ;
{
"parameters": [
{
"type": "string",
"name": "nameandsurname",
"value": {"string":{ "value": "myname"}}
},
{
"type": "Array/string",
"name": "arrayvariable",
**"value": {"string":{ "value": "value1"}}** This line is not working...
}
]
}
In Postman you can post JSON this way:
Select method POST
In section Body choose raw and content-type JSON(application/json)
Paster your JSON into Body
You can download this export from Postman and try it
https://www.dropbox.com/s/ulmoc8n8gmgb076/tests.postman_collection.json?dl=0

Guzzle - Get Raw JSON Response

I've been trying to get this working all day so this is my last resort.
I am trying to call an api using guzzle, and this drupal_symfony_inject module:
https://github.com/Capgemini/drupal_symfony_inject
I have the following config in hook_symfony_yaml_config_params():
// Assets client.
$assets_resources_file = $resources_folder . '/moderation.json';
$param_array['bubl_api_assets_service_client.service.description'] = $assets_resources_file;
$param_array['bubl_api_assets_client.class'] = 'BUBL\Clients\Assets\Client';
And this in my service definition:
{
"name": "BUBL moderation client",
"apiVersion": "v1",
"description": "BUBL moderation REST API client",
"operations": {
"getAllBubls": {
"httpMethod": "GET",
"uri": "/su/bubls",
"responseModel": "getJSONResponse",
"parameters": {
"before": {
"location": "uri",
"type": "integer",
"required": false
},
"after": {
"location": "uri",
"type": "integer",
"required": false
},
"max": {
"location": "uri",
"type": "integer",
"required": false
}
}
}
},
"models": {
"getJSONResponse": {
"type": "object",
"additionalProperties": {
"location": "json"
}
},
"getHTMLResponse": {
"type": "object",
"properties": {
"html": {
"location": "body",
"type": "string"
}
}
}
}
}
I have a client with the operations simply returning the response from guzzle, for example:
public function getAllBubls($before = NULL, $after = NULL) {
$response = $this->client->sendRequest('getAllBubls', ['before' => $before, 'after' => $after]);
return $response;
}
And when using it it works absolutely fine, like so:
global $_drupal_symfony_di_container;
/** #var BUBL\Clients\Moderation\Client $client */
$client = $_drupal_symfony_di_container->get('bubl_api_moderation_client');
if (is_callable(array($client, $service_name))) {
$response = $client->{$service_name}();
return $data_source = $response['bubls'];
}
Now, my problem is that the response is ran through json_decode before I get hold of it, and giving me an array, which is causing me all kinds of problems with the migrate module. I know that it is because of the
responseModel set at
"responseModel": "getJSONResponse",
However, I can't find a way to simply request a raw response. I have tried (as was alluded to in the documentation), removing the responseModal altogether and adding in:
"responseType": "primitive",
and (separately I mean)
"responseModel": "getHTMLResponse",
But unfortunately I wouldn't receive any data back with either - just an empty array. I just can't seem to find a way to ignore all of the parsing and just get the response back in JSON? Is it possible?
I've also tried to create another Model to use, but the types are either array or object, and the rest of the properties are really confusing to me in the documentation, so nothing I've tried is helping. It doesn't seem like it shouldn't go through a Model or Response Class at all, and that there is some way to bypass it perhaps ("primitive" would make sense to me, but alas not).
BTW I'm new to guzzle, and I know this seems a bit over engineered for this one call, but it is important for elsewhere, it's in place and I would like to get my head round it if it's possible to use it.
Thanks.
Ok so I found a couple of things that helped me, namely this
https://github.com/Rarst/wporg-client/blob/33fb0dcce9f170b92824d09f5717ca814d7ecd29/php/WporgService.php
Which is based on guzzle, so I took the parameters from the 'body' response response model and made this:
"getRawResponse": {
"type": "object",
"properties": {
"body": {
"location": "body",
"type": "string"
}
}
}
Which returned a Guzzle Stream. So searching for stream docs I found this
Not getting expected response from Guzzle
Which directed me to change my request to
public function getAllBubls($before = NULL, $after = NULL) {
$response = $this->client->sendRequest('getAllBubls', ['before' => $before, 'after' => $after]);
// Get the raw JSON response.
return $response['body']->getContents();
}
Which has returned to me the unparsed JSON.