Compare two dates in logic apps - azure-logic-apps

I have two date objects where I need to find the duration. My question here is: How can I calculate duration between two date strings in logic apps?

You can use ticks() in order to compare two date strings. Ticks return the ticks property value for a specified timestamp.
syntax of ticks()
ticks('<timestamp>')
I have considered 2 dates (i.e., 2022-01-22T22:01:37Z,2022-02-20T22:01:37Z) for instance.
Then in the Calculate Duration connector I'm using the below expression
div(sub(ticks(outputs('Sample_Date1')),ticks(outputs('Sample_Date_2'))),864000000000)
The reason we divide by 864000000000 is that there are 100 * 100 * 100 * 60 * 60 * 24 ticks in a single day. In a nutshell, comparing two dates requires nothing more than a tick-to-day conversion. Hence as a result we get number of days as duration.
output:
Here is the code view of my logic app
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"Calculating_Duration": {
"inputs": "#div(sub(ticks(outputs('Sample_Date_2')),ticks(outputs('Sample_Date1'))),864000000000)",
"runAfter": {
"Sample_Date_2": [
"Succeeded"
]
},
"type": "Compose"
},
"Sample_Date1": {
"inputs": "2022-01-22T22:01:37Z",
"runAfter": {},
"type": "Compose"
},
"Sample_Date_2": {
"inputs": "2022-02-20T22:01:37Z",
"runAfter": {
"Sample_Date1": [
"Succeeded"
]
},
"type": "Compose"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"parameters": {},
"triggers": {
"manual": {
"inputs": {},
"kind": "Http",
"type": "Request"
}
}
},
"parameters": {}
}
REFERENCE:
Reference guide for expression functions - Azure Logic Apps

Related

Output of Stored Proc in Logic apps not becoming Dynamic content

I've made a Stored Proc and I've initialized it in a variable and am trying to make the output of the Stored Proc Dynamic content in Logic Apps, however. Once I put the variable in the Parse JSON step, it will not become Dynamic. Any advice on how to make my Stored Proc output Dynamic content?
My output varies on the number of entries I'm able to retrieve and I think that's my issue. I've set my Parse JSON scheme to look for 6 entries and sometimes I will get 8-10, which I believe is my problem How can I make it so that no matter how many entries come through from my Stored Proc, I can capture those values in dynamic content and use them?
I see that you are trying to check the SQL dynamic content rather than checking the Parse JSON Connector. Make sure you are checking in the dynamic content of Parse JSON.
Also, after reproducing from my end, I could able to get the expected results without using Parse Json too.
when you follow the above the process you can retrieve no matter how many entries are there in the table. Below is the complete flow that worked for me.
Below is the schema of my logic app
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"Execute_stored_procedure_(V2)": {
"inputs": {
"host": {
"connection": {
"name": "#parameters('$connections')['sql']['connectionId']"
}
},
"method": "post",
"path": "/v2/datasets/#{encodeURIComponent(encodeURIComponent('default'))},#{encodeURIComponent(encodeURIComponent('default'))}/procedures/#{encodeURIComponent(encodeURIComponent('[dbo].[proc1]'))}"
},
"runAfter": {},
"type": "ApiConnection"
},
"Parse_JSON": {
"inputs": {
"content": "#body('Execute_stored_procedure_(V2)')",
"schema": {
"properties": {
"OutputParameters": {
"properties": {},
"type": "object"
},
"ResultSets": {
"properties": {
"Table1": {
"items": {
"properties": {
"firstname": {
"type": "string"
},
"lastname": {
"type": "string"
}
},
"required": [
"firstname",
"lastname"
],
"type": "object"
},
"type": "array"
}
},
"type": "object"
},
"ReturnCode": {
"type": "integer"
}
},
"type": "object"
}
},
"runAfter": {
"Execute_stored_procedure_(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": {
"sql": {
"connectionId": "/subscriptions/xxxx/resourceGroups/xxxx/providers/Microsoft.Web/connections/sql",
"connectionName": "sql",
"id": "/subscriptions/xxxx/providers/Microsoft.Web/locations/eastus/managedApis/sql"
}
}
}
}
}

Logic app loop through all elements on the array and add it to the body/description

Actually I don't know if this will work. But I have long array with a lot of elements, I need to display all element in order on the body/description of Jira ticket without writing it manually (example: outputs('Compose')?[0] outputs('Compose')?[1] outputs('Compose')?[2] ). Is there anyway to do it using loop? or any other method?
Note: I don't want it to be as paragraph I need it the same as the array listed.
Example array:
[ 'first element', 'second element', 'third element', ]
printed/displayed format:
first element
second element
third element
I tried using loop but don't understand it.
please consider that I'm new to the Logic App or any other technologies with the same idea
There are ways which we can perform data operations such as:
Line by line
Spaces
Option 1: Line by line
Firstly, I have initialized a variable as below:
Then used Join (Data Operations) as below:
(here I just clicked Enter in Join with )
Output:
Code view:
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"Initialize_variable": {
"inputs": {
"variables": [
{
"name": "emo",
"type": "array",
"value": [
"rithwik",
"bojja",
"chotu"
]
}
]
},
"runAfter": {},
"type": "InitializeVariable"
},
"Join": {
"inputs": {
"from": "#variables('emo')",
"joinWith": "\n"
},
"runAfter": {
"Initialize_variable": [
"Succeeded"
]
},
"type": "Join"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"parameters": {},
"triggers": {
"manual": {
"inputs": {
"schema": {}
},
"kind": "Http",
"type": "Request"
}
}
},
"parameters": {}
}
So now you can use the output of Join(body('Join')
Option 2: Spaces
If you keep space in Join you will get ouput as below:
Output:
Code view:
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"Initialize_variable": {
"inputs": {
"variables": [
{
"name": "emo",
"type": "array",
"value": [
"rithwik",
"bojja",
"chotu"
]
}
]
},
"runAfter": {},
"type": "InitializeVariable"
},
"Join": {
"inputs": {
"from": "#variables('emo')",
"joinWith": " "
},
"runAfter": {
"Initialize_variable": [
"Succeeded"
]
},
"type": "Join"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"parameters": {},
"triggers": {
"manual": {
"inputs": {
"schema": {}
},
"kind": "Http",
"type": "Request"
}
}
},
"parameters": {}
}
I'm going to assume that what you end up putting together needs to be separated by a html line break (i.e. <br>) but if this not the case then you can make it whatever you want.
I've just tried to mimic what you provided with this basic flow ...
You can see the first step is a compose for your array and the second step is initialising a string variable using the join expression. This concatenates all strings within the array together separated by the HTML line break.
join(outputs('Compose'), '<br>')
Result

get emails for last x number of hours in logic app

I am using "get emails v3" action in "outlook.com" for logic apps. I want to search emails based on subject filters in todays date only. I want following search criteria where I want emails between two times.
((receivedDateTime:#{utcNow()})) BETWEEN (receivedDateTime:#{addToTime(utcNow(), 1, 'Day')})
Is there any way to do that?
After reproducing it was clear that this is because of the format of receivedDateTime is not as same as the format of utcNow(). To achieve your requirement, you need to compare the dates in same format using condition. Below is how I to achieve your requirement using condition action.
Left side Condition
formatDateTime(items('For_each_2')?['receivedDateTime'],'dd/MM/yyyy')
Right side Condition
formatDateTime(addDays(utcNow(), -1), 'dd/MM/yyyy')
Here is the complete flow of my logic app
RESULTS:
Below is the code view of my Logic App
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"For_each_2": {
"actions": {
"Condition": {
"actions": {
"Append_to_array_variable": {
"inputs": {
"name": "Email",
"value": "#items('For_each_2')"
},
"runAfter": {},
"type": "AppendToArrayVariable"
}
},
"expression": {
"and": [
{
"greaterOrEquals": [
"#formatDateTime(items('For_each_2')?['receivedDateTime'],'dd/MM/yyyy')",
"#formatDateTime(addDays(utcNow(), -1), 'dd/MM/yyyy')"
]
},
{
"lessOrEquals": [
"#formatDateTime(items('For_each_2')?['receivedDateTime'],'dd/MM/yyyy')",
"#formatDateTime(utcNow(),'MM/dd/yyyy')"
]
}
]
},
"runAfter": {},
"type": "If"
}
},
"foreach": "#body('Get_emails_(V3)')?['value']",
"runAfter": {
"Initialize_variable": [
"Succeeded"
]
},
"type": "Foreach"
},
"Get_emails_(V3)": {
"inputs": {
"host": {
"connection": {
"name": "#parameters('$connections')['office365']['connectionId']"
}
},
"method": "get",
"path": "/v3/Mail",
"queries": {
"fetchOnlyFlagged": false,
"fetchOnlyUnread": false,
"fetchOnlyWithAttachment": false,
"folderPath": "Inbox",
"importance": "Any",
"includeAttachments": false
}
},
"runAfter": {},
"type": "ApiConnection"
},
"Initialize_variable": {
"inputs": {
"variables": [
{
"name": "Email",
"type": "array"
}
]
},
"runAfter": {
"Get_emails_(V3)": [
"Succeeded"
]
},
"type": "InitializeVariable"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"parameters": {
"$connections": {
"defaultValue": {},
"type": "Object"
}
},
"triggers": {
"manual": {
"inputs": {
"schema": {}
},
"kind": "Http",
"type": "Request"
}
}
},
"parameters": {
"$connections": {
"value": {
"office365": {
"connectionId": "/subscriptions/<SUBID>/resourceGroups/<RG>/providers/Microsoft.Web/connections/office365",
"connectionName": "office365",
"id": "/subscriptions/<SUBID>/providers/Microsoft.Web/locations/centralus/managedApis/office365"
}
}
}
}
}
If I've understood you correctly then this is the sort approach you need to take.
There's an additional parameter to that connector called Search Query.
In there, you can put an expression that looks like the following ...
received>#{formatDateTime(addDays(utcNow(), -1), 'MM/dd/yyyy')}
You're close, if you look at the doco though, the name of the field is different to what comes back in the response.
https://learn.microsoft.com/en-gb/graph/search-query-parameter
You may just need to play around with the formula to give you exactly what you want given the response is all in UTC. I think -1 day is the easiest but it may not be perfect for you.

How to check json and do filtering in Logic App

In my Logic App one of the action item gives me Json value as like this . This is recorded in compose action.
{
"device1": 24,
"device2": 25,
"device3": 26
}
I would like to take only that device name and value whose value is equal to and above 25 (in this case device2 and device3)and then pass that value in subsequent method like creating and sending an alert message for each device name whose value is 25 or more.
How can I do that in logic app?
Here is one of the workaround that worked for me. In order to filter the Json in well defined, easy format (i.e., devices whose value is greater than 25) and also for future use, we need to convert the json of format
{
"device1": 24,
"device2": 25,
"device3": 26
}
to
[
{
"deviceName": "\"device1\"",
"value": "24"
},
{
"deviceName": "\"device3\"",
"value": "26"
},
{
"deviceName": "\"device2\"",
"value": "25"
}
]
We first need to convert the Json into array. This can be done in 2 ways
Way -1 (using subString())
syntax in Method 1 step 1
substring(string(outputs('Compose')),1,sub(lastIndexOf(string(outputs('Compose')),'}'),1))
syntax in Method 1 step 2
array(split(string(outputs('Convert_To_Array_Method_1_step_1')),','))
Way -2 (using replace())
syntax in Method 2 step 1
replace(string(outputs('Compose')),'{','[')
syntax in Method 2 step 2
replace(string(outputs('Convert_To_Array_Method_2_step_1')),'}',']')
output:
You need to initialize an array variable in order to store the resultant json.
We can now extract the values inside the json by taking either of syntax in Method 1 step 2or syntax in Method 2 step 2 outputs in For each connector.
In Extract values compose connector I'm trying to extract the values of the devices by taking substring expression.
syntax in Extract values
substring(item(),add(indexOf(item(),':'),1),sub(length(item()),add(indexOf(item(),':'),1)))
Here I'm just extracting the values that are there after ':'.
The same goes with device names too. I'm extracting the device names that are there from index 0 to ':'.
syntax in Formatted JSON
{
"inputs": {
"deviceName": "#substring(item(), 0, indexOf(item(), ':'))",
"value": "#outputs('Extract_Value')"
}
}
Then lastly I'm storing the resultant Formatted Json to a variable.
output:
Now I'm just parsing the the Formatted variable which gives me the results of device name and value.
In the next step I'm using Condition connector to check if the value greater than or equal to 25
syntax in Condition
int(items('For_each_2')['value'])
if the condition is true then it stores the value to Required Values.
output:
Here is the code view of my logic app
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"Compose": {
"inputs": {
"device1": 24,
"device2": 25,
"device3": 26
},
"runAfter": {},
"type": "Compose"
},
"Convert_To_Array_Method_1_step_1": {
"inputs": "#substring(string(outputs('Compose')),1,sub(lastIndexOf(string(outputs('Compose')),'}'),1))",
"runAfter": {
"Compose": [
"Succeeded"
]
},
"type": "Compose"
},
"Convert_To_Array_Method_1_step_2": {
"inputs": "#array(split(string(outputs('Convert_To_Array_Method_1_step_1')),','))",
"runAfter": {
"Convert_To_Array_Method_1_step_1": [
"Succeeded"
]
},
"type": "Compose"
},
"Convert_To_Array_Method_2_step_1": {
"inputs": "#replace(string(outputs('Compose')),'{','[')",
"runAfter": {
"Convert_To_Array_Method_1_step_2": [
"Succeeded"
]
},
"type": "Compose"
},
"Convert_To_Array_Method_2_step_2": {
"inputs": "#replace(string(outputs('Convert_To_Array_Method_2_step_1')),'}',']')",
"runAfter": {
"Convert_To_Array_Method_2_step_1": [
"Succeeded"
]
},
"type": "Compose"
},
"Final_Formated_JSON": {
"inputs": "#variables('formatedArray')",
"runAfter": {
"For_each": [
"Succeeded"
]
},
"type": "Compose"
},
"Final_Values": {
"inputs": "#variables('Required Values')",
"runAfter": {
"For_each_2": [
"Succeeded"
]
},
"type": "Compose"
},
"For_each": {
"actions": {
"Append_to_array_variable": {
"inputs": {
"name": "formatedArray",
"value": "#outputs('Formated_JSON')"
},
"runAfter": {
"Formated_JSON": [
"Succeeded"
]
},
"type": "AppendToArrayVariable"
},
"Extract_Value": {
"inputs": "#substring(item(),add(indexOf(item(),':'),1),sub(length(item()),add(indexOf(item(),':'),1)))",
"runAfter": {},
"type": "Compose"
},
"Formated_JSON": {
"inputs": {
"deviceName": "#substring(item(), 0, indexOf(item(), ':'))",
"value": "#outputs('Extract_Value')"
},
"runAfter": {
"Extract_Value": [
"Succeeded"
]
},
"type": "Compose"
}
},
"foreach": "#outputs('Convert_To_Array_Method_1_step_2')",
"runAfter": {
"Initialize_variable_to_store_the_formatted_Json_": [
"Succeeded"
]
},
"type": "Foreach"
},
"For_each_2": {
"actions": {
"Condition": {
"actions": {
"Append_to_array_variable_2": {
"inputs": {
"name": "Required Values",
"value": "#items('For_each_2')"
},
"runAfter": {},
"type": "AppendToArrayVariable"
}
},
"expression": {
"and": [
{
"greaterOrEquals": [
"#int(items('For_each_2')['value'])",
25
]
}
]
},
"runAfter": {},
"type": "If"
}
},
"foreach": "#body('Parse_JSON')",
"runAfter": {
"Initialize_variable_to_store_required_values": [
"Succeeded"
]
},
"type": "Foreach"
},
"Initialize_variable_to_store_required_values": {
"inputs": {
"variables": [
{
"name": "Required Values",
"type": "array"
}
]
},
"runAfter": {
"Parse_JSON": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Initialize_variable_to_store_the_formatted_Json_": {
"inputs": {
"variables": [
{
"name": "formatedArray",
"type": "array"
}
]
},
"runAfter": {
"Convert_To_Array_Method_2_step_2": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Parse_JSON": {
"inputs": {
"content": "#variables('formatedArray')",
"schema": {
"items": {
"properties": {
"deviceName": {
"type": "string"
},
"value": {
"type": "string"
}
},
"required": [
"deviceName",
"value"
],
"type": "object"
},
"type": "array"
}
},
"runAfter": {
"Final_Formated_JSON": [
"Succeeded"
]
},
"type": "ParseJson"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"parameters": {},
"triggers": {
"manual": {
"inputs": {
"schema": {}
},
"kind": "Http",
"type": "Request"
}
}
},
"parameters": {}
}
In these situations, I find it much easier to write an Azure Function that does the work.
It'll ultimately keep your LogicApp cleaner than it would otherwise be with a whole heap of functionality to work around (perceived) limitations.
In the Azure Portal, go to the Azure Functions blade and create a new .NET HttpTrigger function with the following code ...
#r "Newtonsoft.Json"
using System.Net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
public static async Task<IActionResult> Run(HttpRequest req, ILogger log)
{
string thresholdString = req.Query["threshold"];
var threshold = int.Parse(thresholdString);
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
var jObject = JObject.Parse(requestBody);
var filteredObject = new JObject(jObject.Properties().ToList().Where(x => (int)x.Value >= threshold));
return new OkObjectResult(filteredObject);
}
... it assumes the JSON you pass in is along the lines of what you provided so be aware of that.
Now call it from your LogicApp like and you'll get the response you desire ...
Action
Result

Logic apps - Read XML response from web service and store parsed data in a database

I am trying to use Logic Apps to accomplish something I have done with Pentaho in the past. I would like to build a Logic App with a Recurrence trigger, which starts an HTTP step to post to a web service and receive an XML reply. I would like to parse that XML reply (known format) and store the result in an Azure SQL Server database.
I have successfully tested the HTTP step and received the reply XML. I have the destination table completed in the SQL database. What I do not know how to do with Logic Apps is parse the XML reply into something like a CSV format that I can pass to a SQL query to input a new table row.
I have looked through several tutorials and other threads, but the steps either assume a greater level of experience than I possess, or are very basic intros to Logic Apps.
I think it would be helpful to hear something like the following:
Is this considerably more challenging than I anticipate? I'm good with SQL, Pentaho, R and other tools, but am somewhat new to HTTP calls / responses, and have very little XML experience.
What Logic Flow connectors I should be considering, and are they part of the free offering, or some paid package?
Thanks in advance for any help getting started.
Its much simpler if you convert the XML into a JSON object as well after parsing. Both of this can be done by using the the xml and json functions.
Also, since you know the format of the XML, you will know the format of the converted JSON as well letting you use the Parse JSON action to get simple tokens to use in the rest of the Logic App.
You can then use these tokens directly in the SQL query .
Here is a Logic App that show cases this (without the SQL and HTTP steps)
and its definition to be clear
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"CSV_Data": {
"inputs": {
"variables": [
{
"name": "random_data_csv",
"type": "String",
"value": "#{body('Parse_JSON')?['data']?['name']},#{body('Parse_JSON')?['data']?['awesome']}"
}
]
},
"runAfter": {
"Parse_JSON": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Parse_JSON": {
"inputs": {
"content": "#json(xml(variables('random_data_xml')))",
"schema": {
"properties": {
"data": {
"properties": {
"awesome": {
"type": "string"
},
"name": {
"type": "string"
}
},
"type": "object"
}
},
"type": "object"
}
},
"runAfter": {
"XML_Data": [
"Succeeded"
]
},
"type": "ParseJson"
},
"XML_Data": {
"inputs": {
"variables": [
{
"name": "random_data_xml",
"type": "String",
"value": "<data>\n<name>Azure Logic Apps</name>\n<awesome>true</awesome>\n</data>"
}
]
},
"runAfter": {},
"type": "InitializeVariable"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"parameters": {},
"triggers": {
"manual": {
"inputs": {
"schema": {}
},
"kind": "Http",
"type": "Request"
}
}
}
}

Resources