How do I parse text by line in an Azure Logic App? - azure

I've got a Logic App that reads in an email from a form submission. Unfortunately, I only have access to the email and not where the form results are stored, so I currently have the Logic App set up to pull in the email and convert it to text.
If it was just one field, I assume I could just grab it all, throw it in a variable and split it to get what I need, but I'm not sure how to do this with multiple lines.
The emails always come in with this format:
---
Date: 08/18/2022
Time: 09:30:00
Requestor Name: Robert Bobson
Requestor Email: bob#companyname.com
Requestor Phone Number: 800-867-5309
Site Name: CompanyName
Site Number: 123456789
---
Am I able to set a line index and then grab everything on that line and then split it before assigning it to a variable? Is this going to require RegEx or is there a workaround or expression in Logic Apps that will handle this?
Thank you in advance!

You can achieve your requirement using expressions.
First, try removing the extra lines from the given email. below is the expression I'm using to achieve the same.
split(outputs('Compose'),'\n\n')
The above expression results in:
Am I able to set a line index and then grab everything on that line and then split it before assigning it to a variable?
yes, This is possible using the below expression
outputs('Compose_2')?[0] gives the Date
outputs('Compose_2')?[1] gives the Time
...
RESULTS:
Alternatively, You can convert the string into Parsable Json and then Parse it through Parse JSON Action. Below is the flow of my Logic App
In the above step I'm extracting the values on both left and right sides and storing them into a variable. You can use either of slice or substring functions to extract the values.
In the next step I'm trying to Parse the values through Parse JSON action.
RESULTS:
You can test the same using below code view in your logicapp
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"Compose": {
"inputs": "Date: 08/18/2022\n\nTime: 09:30:00\n\nRequestor Name: Robert Bobson\n\nRequestor Email: bob#companyname.com\n\nRequestor Phone Number: 800-867-5309\n\nSite Name: CompanyName\n\nSite Number: 123456789",
"runAfter": {},
"type": "Compose"
},
"Compose_2": {
"inputs": "#split(outputs('Compose'),'\n\n')",
"runAfter": {
"Compose": [
"Succeeded"
]
},
"type": "Compose"
},
"Compose_3": {
"inputs": "#body('Parse_JSON')?['Site Name']",
"runAfter": {
"Parse_JSON": [
"Succeeded"
]
},
"type": "Compose"
},
"Initialize_variable": {
"inputs": {
"variables": [
{
"name": "length",
"type": "integer"
}
]
},
"runAfter": {
"Compose_2": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Initialize_variable_2": {
"inputs": {
"variables": [
{
"name": "Json",
"type": "string"
}
]
},
"runAfter": {
"Initialize_variable": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Parse_JSON": {
"inputs": {
"content": "#concat('{',substring(variables('Json'),0,sub(length(variables('Json')),1)),'}')",
"schema": {
"properties": {
"Date": {
"type": "string"
},
"Requestor Email": {
"type": "string"
},
"Requestor Name": {
"type": "string"
},
"Requestor Phone Number": {
"type": "string"
},
"Site Name": {
"type": "string"
},
"Site Number": {
"type": "string"
},
"Time": {
"type": "string"
}
},
"type": "object"
}
},
"runAfter": {
"Until": [
"Succeeded"
]
},
"type": "ParseJson"
},
"Until": {
"actions": {
"Append_to_string_variable": {
"inputs": {
"name": "Json",
"value": "#{outputs('Current_Object')},"
},
"runAfter": {
"Current_Object": [
"Succeeded"
]
},
"type": "AppendToStringVariable"
},
"Current_Object": {
"inputs": "\"#{substring(outputs('Compose_2')?[variables('length')],0,indexOf(outputs('Compose_2')?[variables('length')],':'))}\":\"#{slice(outputs('Compose_2')?[variables('length')],add(indexOf(outputs('Compose_2')?[variables('length')],':'),2),length(outputs('Compose_2')?[variables('length')]))}\"",
"runAfter": {},
"type": "Compose"
},
"Increment_variable": {
"inputs": {
"name": "length",
"value": 1
},
"runAfter": {
"Append_to_string_variable": [
"Succeeded"
]
},
"type": "IncrementVariable"
}
},
"expression": "#equals(variables('length'), length(outputs('Compose_2')))",
"limit": {
"count": 60,
"timeout": "PT1H"
},
"runAfter": {
"Initialize_variable_2": [
"Succeeded"
]
},
"type": "Until"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"parameters": {},
"triggers": {
"manual": {
"inputs": {},
"kind": "Http",
"type": "Request"
}
}
},
"parameters": {}
}

You can Convert the email body using "Html To Text" action and then assign it to an array variable by using the split expression for any delimiter.

Related

Azure Logic App - Remove Double Quotes from Queue Message's Raw Input

I am attempting to send encoded base64 to an Azure Queue using a Logic App. However, the Logic App inserts the message to the queue with double quotes. This is causing problems for my pipeline downstream.
Here is my process:
Create a JSON message
"Compose": {
"inputs": {
"environment": "environment",
"group": "group",
"job": "job",
"project": "project",
"variables": {
"variable_1": "variable_1",
"variable_2": "variable_2"
},
"version": "version"
},
"runAfter": {},
"type": "Compose"
}
Encode the JSON message to base64
"Compose_2": {
"inputs": "#base64(outputs('Compose'))",
"runAfter": {
"Compose": [
"Succeeded"
]
},
"type": "Compose"
}
Add a message to queue
"Add_a_message_to_queue": {
"inputs": {
"parameters": {
"message": "#string(outputs('Compose_2'))",
"queueName": "queueName"
},
"serviceProviderConfiguration": {
"connectionName": "connectionName",
"operationId": "operationId",
"serviceProviderId": "serviceProviderId"
}
},
"runAfter": {
"Compose_2": [
"Succeeded"
]
},
"type": "ServiceProvider"
}
The issue was resolved by cutting Compose_2 and converting to base64 in Add_a_message_to_queue. Correction below:
Create JSON
"Compose": {
"inputs": {
"environment": "environment",
"group": "group",
"job": "job",
"project": "project",
"variables": {
"variable_1": "variable_1",
"variable_2": "variable_2"
},
"version": "version"
},
"runAfter": {},
"type": "Compose"
}
Add a message to queue
"Add_a_message_to_queue": {
"inputs": {
"parameters": {
"message": "#string(outputs('Compose_2'))",
"queueName": "queueName"
},
"serviceProviderConfiguration": {
"connectionName": "connectionName",
"operationId": "operationId",
"serviceProviderId": "serviceProviderId"
}
},
"runAfter": {
"Compose_2": [
"Succeeded"
]
},
"type": "ServiceProvider"
}

How to get a logic app to stop running after a successful run each day

I have a logic app that I want to run once a line item appears in a table each day. once that line item appear, i don't want the logic app to run anymore that day. Can't quite think of how to accomplish this.
Apart from using the related triggers you can use Terminate action to stop the flow.
After using Get entities (V2) I'm trying to Parse the result to get the timestamp of that particular entity to check if the table has an added row or not for that day
After parsing below is the condition that I'm using
{
"contains": [
"#formatDateTime(body('Parse_JSON')?[0]?['Timestamp'],'dd-MM-yyyy')",
"#formatDateTime(utcNow(),'dd-MM-yyyy')"]
}
Below is the complete flow of my Logic App
RESULTS:
To reproduce the same in your Logic App you can use the below code view
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"Condition": {
"actions": {
"Terminate": {
"inputs": {
"runStatus": "Succeeded"
},
"runAfter": {},
"type": "Terminate"
}
},
"else": {
"actions": {
"Delay": {
"inputs": {
"interval": {
"count": 2,
"unit": "Hour"
}
},
"runAfter": {},
"type": "wait"
},
"HTTP": {
"inputs": {
"method": "POST",
"uri": "<URI>"
},
"runAfter": {
"Delay": [
"Succeeded"
]
},
"type": "Http"
}
}
},
"expression": {
"and": [
{
"contains": [
"#formatDateTime(body('Parse_JSON')?[0]?['Timestamp'],'dd-MM-yyyy')",
"#formatDateTime(utcNow(),'dd-MM-yyyy')"
]
}
]
},
"runAfter": {
"Parse_JSON": [
"Succeeded"
]
},
"type": "If"
},
"Get_entities_(V2)": {
"inputs": {
"host": {
"connection": {
"name": "#parameters('$connections')['azuretables']['connectionId']"
}
},
"method": "get",
"path": "/v2/storageAccounts/#{encodeURIComponent(encodeURIComponent('AccountNameFromSettings'))}/tables/#{encodeURIComponent('<TableName>')}/entities"
},
"runAfter": {},
"type": "ApiConnection"
},
"Parse_JSON": {
"inputs": {
"content": "#body('Get_entities_(V2)')?['value']",
"schema": {
"items": {
"properties": {
"FirstName": {
"type": "string"
},
"LastName": {
"type": "string"
},
"PartitionKey": {
"type": "string"
},
"RowKey": {
"type": "string"
},
"Timestamp": {
"type": "string"
},
"odata.etag": {
"type": "string"
}
},
"required": [
"odata.etag",
"PartitionKey",
"RowKey",
"Timestamp",
"FirstName",
"LastName"
],
"type": "object"
},
"type": "array"
}
},
"runAfter": {
"Get_entities_(V2)": [
"Succeeded"
]
},
"type": "ParseJson"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"parameters": {
"$connections": {
"defaultValue": {},
"type": "Object"
}
},
"triggers": {
"manual": {
"inputs": {
"schema": {}
},
"kind": "Http",
"type": "Request"
}
}
},
"parameters": {
"$connections": {
"value": {
"azuretables": {
"connectionId": "/subscriptions/<SUB_ID>/resourceGroups/<RG>/providers/Microsoft.Web/connections/azuretables",
"connectionName": "azuretables",
"id": "/subscriptions/<SUB_ID>/providers/Microsoft.Web/locations/centralus/managedApis/azuretables"
}
}
}
}
}
Alternatively, you can use Recurrence trigger to trigger it in regular intervals with the same logic.

retrieve values from an json array in azure logic app

what will be the easiest way to retrive the "HydraulicPressure" and "FailedPickupsLastHr" values from the below json in logic app?
{
"variables": [
{
"name": "sensorarray",
"type": "String",
"value": "{\"ContentData\":{\"applicationId\":\"0db2345\",\"deviceId\":\"178\",\"enqueuedTime\":\"2022-09-17T14:27:22.386Z\",\"enrichments\":{},\"messageSource\":\"properties\",\"messageType\":\"devicePropertyReportedChange\",\"properties\":[{\"name\":\"FailedPickupsLastHr\",\"value\":42},{\"name\":\"HydraulicPressure\",\"value\":30.863390107917837}],\"schema\":\"default#v1\",\"templateId\":\"dtmi:z\"},\"Properties\":{\"iotcentral-application-id\":\"05\",\"iotcentral-message-source\":\"properties\",\"iotcentral-message-type\":\"devicePropertyReportedChange\",\"iotcentral-device-id\":\"1q9hn5l4xcl\",\"x-opt-sequence-number\":5663,\"x-opt-offset\":\"5307784\",\"x-opt-enqueued-time\":\"2022-09-17T14:27:28.046Z\",\"message-id\":{\"EncodeSize\":38},\"group-sequence\":0},\"SystemProperties\":{\"EnqueuedTimeUtc\":\"2022-09-17T14:27:28.046Z\",\"Offset\":\"5307784\",\"PartitionKey\":null,\"SequenceNumber\":5663}}"
}
]
}
Load this definition as a new LogicApp into your tenant ...
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"Initialize_Failed_Pickups_Last_Hr": {
"inputs": {
"variables": [
{
"name": "FailedPickupsLastHr",
"type": "integer",
"value": "#variables('Object')['ContentData']['properties'][0]['value']"
}
]
},
"runAfter": {
"Initialize_Hydraulic_Pressure": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Initialize_Hydraulic_Pressure": {
"inputs": {
"variables": [
{
"name": "HydraulicPressure",
"type": "string",
"value": "#{variables('Object')['ContentData']['properties'][1]['value']}"
}
]
},
"runAfter": {
"Initialize_Object": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Initialize_Object": {
"inputs": {
"variables": [
{
"name": "Object",
"type": "object",
"value": "#JSON(variables('Payload'))"
}
]
},
"runAfter": {
"Initialize_Payload": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Initialize_Payload": {
"inputs": {
"variables": [
{
"name": "Payload",
"type": "string",
"value": "{\"ContentData\":{\"applicationId\":\"0db2345\",\"deviceId\":\"178\",\"enqueuedTime\":\"2022-09-17T14:27:22.386Z\",\"enrichments\":{},\"messageSource\":\"properties\",\"messageType\":\"devicePropertyReportedChange\",\"properties\":[{\"name\":\"FailedPickupsLastHr\",\"value\":42},{\"name\":\"HydraulicPressure\",\"value\":30.863390107917837}],\"schema\":\"default#v1\",\"templateId\":\"dtmi:z\"},\"Properties\":{\"iotcentral-application-id\":\"05\",\"iotcentral-message-source\":\"properties\",\"iotcentral-message-type\":\"devicePropertyReportedChange\",\"iotcentral-device-id\":\"1q9hn5l4xcl\",\"x-opt-sequence-number\":5663,\"x-opt-offset\":\"5307784\",\"x-opt-enqueued-time\":\"2022-09-17T14:27:28.046Z\",\"message-id\":{\"EncodeSize\":38},\"group-sequence\":0},\"SystemProperties\":{\"EnqueuedTimeUtc\":\"2022-09-17T14:27:28.046Z\",\"Offset\":\"5307784\",\"PartitionKey\":null,\"SequenceNumber\":5663}}"
}
]
},
"runAfter": {},
"type": "InitializeVariable"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"parameters": {
"ParameterTest1": {
"defaultValue": "\"\"",
"type": "String"
}
},
"triggers": {
"manual": {
"inputs": {
"method": "GET",
"schema": {}
},
"kind": "Http",
"type": "Request"
}
}
},
"parameters": {}
}
It will give you my answer in full and show you how to get to the values you're after.
The basic steps are ...
Initialize the initial JSON you have as a string.
Then convert that string to an object using the json expression
The last two steps involve expressions to extract the values you're after.
Basically, you need to parse the string value to an object and then evaluate it.
I have reproduced in my environment, you can similarly do it for your json array as below:
Firstly, select initialize variable step and then set it with below json example :
[{
"variables":
{
"name": "sensorarray",
"type": "String"
}
}]
Then, select the SELECT step
And then select the varaible you want from array and then get it with using item as below:
Output:
Try to update your array as the given example and try the above steps you will get the output as above.

Azure Logic Apps create JSON array from separate received xml

I am new to Azure and have to create JSON Array from separate XML messages received by the logic app. The logic app requests data and receives the response in XML format. I proposed an approach that is saving the message in Azure storage then through the Azure function create the JSON array. Is this approach affect the performance? Is there any idea?
Thanks in advance
There are 2 ways where you can completely rely on Logic apps without involving Azure functions
Consider this to be the sample xml
<?xml version="1.0"?>
<PurchaseOrder PurchaseOrderNumber="99503" OrderDate="1999-10-20">
<Address Type="Shipping">
<Name>Adam Murphy</Name>
<Street>123 Maple Street</Street>
<City>Mill Valley</City>
<State>CA</State>
<Zip>10999</Zip>
<Country>Ireland</Country>
</Address>
<Address Type="Billing">
<Name>Tai Yee</Name>
<Street>8 Oak Avenue</Street>
<City>Old Town</City>
<State>PA</State>
<Zip>95819</Zip>
<Country>Ireland</Country>
</Address>
<DeliveryNotes />
</PurchaseOrder>
WAY-1
You can directly convert xml to json using json(xml(triggerBody()))
Here is the logic app for your reference -
output
If you want to have a custom json, then you can create one using Parse_Json and Compose Connectors.
Here I'm just taking the output of Compose Connector to Parse_Json in order to parse the resultant Json to get the custom JSON script. Below is the Json I'm trying to create.
{
"PurchaseOrder": {
"OrderNumber": "#{body('Parse_JSON')?['PurchaseOrder']?['#PurchaseOrderNumber']}",
"PurchaseDate": "#{body('Parse_JSON')?['PurchaseOrder']?['#OrderDate']}",
"Location": [
{
"Name": "#{items('For_each')?['Name']}",
"Address": "#{items('For_each')?['Street']},#{items('For_each')?['City']},#{items('For_each')?['State']},#{items('For_each')?['Country']},#{items('For_each')?['Zip']}"
}
]
}
}
output
Here is the code view of my logic app. You can directly use this to get the exact workflow in your logic app.
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"Compose": {
"inputs": "#json(xml(triggerBody()))",
"runAfter": {},
"type": "Compose"
},
"For_each": {
"actions": {
"Compose_2": {
"inputs": {
"PurchaseOrder": {
"Location": [
{
"Address": "#{items('For_each')?['Street']},#{items('For_each')?['City']},#{items('For_each')?['State']},#{items('For_each')?['Country']},#{items('For_each')?['Zip']}",
"Name": "#{items('For_each')?['Name']}"
}
],
"OrderNumber": "#{body('Parse_JSON')?['PurchaseOrder']?['#PurchaseOrderNumber']}",
"PurchaseDate": "#{body('Parse_JSON')?['PurchaseOrder']?['#OrderDate']}"
}
},
"runAfter": {},
"type": "Compose"
}
},
"foreach": "#body('Parse_JSON')?['PurchaseOrder']?['Address']",
"runAfter": {
"Parse_JSON": [
"Succeeded"
]
},
"type": "Foreach"
},
"Parse_JSON": {
"inputs": {
"content": "#outputs('Compose')",
"schema": {
"properties": {
"?xml": {
"properties": {
"##version": {
"type": "string"
}
},
"type": "object"
},
"PurchaseOrder": {
"properties": {
"##OrderDate": {
"type": "string"
},
"##PurchaseOrderNumber": {
"type": "string"
},
"Address": {
"items": {
"properties": {
"##Type": {
"type": "string"
},
"City": {
"type": "string"
},
"Country": {
"type": "string"
},
"Name": {
"type": "string"
},
"State": {
"type": "string"
},
"Street": {
"type": "string"
},
"Zip": {
"type": "string"
}
},
"required": [
"##Type",
"Name",
"Street",
"City",
"State",
"Zip",
"Country"
],
"type": "object"
},
"type": "array"
}
},
"type": "object"
}
},
"type": "object"
}
},
"runAfter": {
"Compose": [
"Succeeded"
]
},
"type": "ParseJson"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"parameters": {},
"triggers": {
"manual": {
"inputs": {
"schema": {}
},
"kind": "Http",
"type": "Request"
}
}
},
"parameters": {}
}
WAY-2
You can use liquid templates in order to convert xml to json using Transform XML to JSON Connector. For more information you can refer thread1 and thread2.
REFERENCES:
Logic App: Basic XML to JSON Expression Conversion

Randomize list in Azure Logic Apps

Is it possible to randomize the elements of an array using just functions from WDL in Logic apps?
Let's imagine you have array from 1 to 10
You create one lement randomized array variable
first(variables('Array'))
And a temp value (tempValue) and temp array (temp) (used in later steps because self referencing is not allowed)
Then you create until loop like so
With Until condition being
equals(length(variables('Randomized')), length(variables('Array')))
Calculate random index tempValue in array (random index at which we will split array)
rand(0,sub(length('Randomized'),1))
And combine new array temp by inserting current iteration value at random place
union(
take(
variables('Randomized'),
variables('tempInteger')
),
array(variables('Array')[add(iterationIndexes('Until'),1)]),
skip(
variables('Randomized'),
variables('tempInteger')
)
)
And after condition statement set randomized variable to temp value
Which after the last iteration will net you randomized input table
And full code example
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"Init_Randomized_One_Element_Array": {
"inputs": {
"variables": [
{
"name": "Randomized",
"type": "Array",
"value": [
"#first(variables('Array'))"
]
}
]
},
"runAfter": {
"Init_Unrandomized_Array": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Init_Randomized_Temp_Array": {
"inputs": {
"variables": [
{
"name": "temp",
"type": "Array"
}
]
},
"runAfter": {
"Init_Randomized_One_Element_Array": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Init_Temp_Calculated_Value": {
"inputs": {
"variables": [
{
"name": "tempInteger",
"type": "integer"
}
]
},
"runAfter": {
"Init_Randomized_Temp_Array": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Init_Unrandomized_Array": {
"inputs": {
"variables": [
{
"name": "Array",
"type": "Array",
"value": [
1,
2,
3,
4,
5,
6,
7,
8,
9,
10
]
}
]
},
"runAfter": {},
"type": "InitializeVariable"
},
"Until": {
"actions": {
"Add_random_element_to_temp_array": {
"inputs": {
"name": "temp",
"value": "#union(\r\n\ttake(\r\n\t\t variables('Randomized'),\r\n\t\t variables('tempInteger')\r\n\t),\r\n\tarray(variables('Array')[add(iterationIndexes('Until'),1)]),\r\n\tskip(\r\n\t variables('Randomized'),\r\n\t variables('tempInteger')\r\n\t)\r\n)\r\n"
},
"runAfter": {
"Random_Index_to_insert": [
"Succeeded"
]
},
"type": "SetVariable"
},
"Random_Index_to_insert": {
"inputs": {
"name": "tempInteger",
"value": "#rand(0,sub(length('Randomized'),1))"
},
"runAfter": {},
"type": "SetVariable"
},
"Set_randomized_from_temp": {
"inputs": {
"name": "Randomized",
"value": "#variables('temp')"
},
"runAfter": {
"Add_random_element_to_temp_array": [
"Succeeded"
]
},
"type": "SetVariable"
}
},
"expression": "#equals(length(variables('Randomized')), length(variables('Array')))",
"limit": {
"count": 60,
"timeout": "PT1H"
},
"runAfter": {
"Init_Temp_Calculated_Value": [
"Succeeded"
]
},
"type": "Until"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"parameters": {},
"triggers": {
"manual": {
"inputs": {
"schema": {}
},
"kind": "Http",
"type": "Request"
}
}
}
}
There is no direct way to randomize anything in a LogicApp.
I suppose you could come up with some pattern that could pseudorandomize a list entirely within a Logic App, but....
The more 'correct' way to handle this would be with a Function.

Resources