Trying to extract certain data from an email and add it to a Sharepoint list - power-automate

I'm trying to extract only Name, Age and Salary from the following data, and create a new row in a Sharepoint List for each:
I've linked the inbox and the Sharepoint list and tried a bunch of text manipulation, but can't figure it out. Even my first part of splitting the text up, returns an error:
Tried:
split(triggerOutputs()?['body/body'],'\n')[0]
Expecting:
The body of the email to be split into an array of strings, each index of the array being another line. Then I could try and split each index based on ':' as a delimiter. Not sure if it's even a good approach.
Error: Unable to process template language expressions in action
'Create_item' inputs at line '0' and column '0': 'The template
language expression 'split(triggerOutputs()?['body/body'],'\n')1'
cannot be evaluated because array index '1' is outside bounds (0, 0)
of array. Please see https://aka.ms/logicexpressions for usage
details.'.
Raw output from trigger in PA:
Record ID: 4067055\r\nName: Smith, Erin Rachelle\r\nTotal Hours: 7.5\r\nCreated Date: 17-JAN-2023\r\nEscalation Date: 31-JAN-2023\r\nEscalated to you By:"
JSON Output from initial email trigger (Sorry, I didn't know I could do that):
{
"headers": {
"Pragma": "no-cache",
"Transfer-Encoding": "chunked",
"Retry-After": "3600",
"Vary": "Accept-Encoding",
"x-ms-request-id": "4411aed8-30d9-4f63-a11c-d0d051ecc3ae;5e807a75-caa1-40e1-a697-cb6d993923d3",
"Strict-Transport-Security": "max-age=31536000; includeSubDomains",
"X-Content-Type-Options": "nosniff",
"X-Frame-Options": "DENY",
"Cache-Control": "no-store, no-cache",
"Location": "https://australia-001.azure-apim.net/apim/office365/shared-office365-16c3af54-48d7-478e-adaf-b3aee0bd4b11/v3/Mail/OnNewEmail?folderPath=Inbox&importance=Any&fetchOnlyWithAttachment=false&includeAttachments=false&subjectFilter=timelog&LastPollInformation=eyJMYXN0UmVjZWl2ZWRNYWlsVGltZSI6IjIwMjMtMDItMDdUMDI6MjE6NTQrMDA6MDAiLCJMYXN0Q3JlYXRlZE1haWxUaW1lIjoiMjAyMy0wMi0wN1QwMjoyMTo1NCswMDowMCIsIkxhc3RNZXNzYWdlSWQiOiJBQU1rQURWa01USm1ZVEJqTFRrNFptVXRORFJsTXkwNFpqaGtMVGc1TVRZMlpqY3lNbU5oTVFCR0FBQUFBQUNTZWpPejdpU2RRYl92am56UGFfeWpCd0NpYTY2RHc1dGxTYi1tSTcwOXJscERBQUFBQUFFTUFBQ2lhNjZEdzV0bFNiLW1JNzA5cmxwREFBQUdNRmdOQUFBPSIsIkxhc3RJbnRlcm5ldE1lc3NhZ2VJZCI6IjxTWUJQUjAxTUI0Mzc5NjYyNkVENDg2MDk0MzhFOTRFOUNCMERCOUBTWUJQUjAxTUI0Mzc5LmF1c3ByZDAxLnByb2Qub3V0bG9vay5jb20%2bIn0%3d",
"Set-Cookie": "ARRAffinity=75eb715df977f9cc8747c6e93018236935309083a7acad6cd06cb0ebad592e80;Path=/;HttpOnly;Secure;Domain=office365-ase.azconn-ase.p.azurewebsites.net,ARRAffinitySameSite=75eb715df977f9cc8747c6e93018236935309083a7acad6cd06cb0ebad592e80;Path=/;HttpOnly;SameSite=None;Secure;Domain=office365-ase.azconn-ase.p.azurewebsites.net",
"Timing-Allow-Origin": "*",
"x-ms-apihub-cached-response": "true",
"x-ms-apihub-obo": "false",
"Date": "Tue, 07 Feb 2023 02:22:12 GMT",
"Content-Type": "application/json; charset=utf-8",
"Expires": "-1",
"Content-Length": "1944"
},
"body": {
"id": "AAMkADVkMTJmYTBjLTk4ZmUtNDRlMy04ZjhkLTg5MTY2ZjcyMmNhMQBGAAAAAACSejOz7iSdQb_vjnzPa_yjBwCia66Dw5tlSb-mI709rlpDAAAAAAEMAACia66Dw5tlSb-mI709rlpDAAAGMFgNAAA=",
"receivedDateTime": "2023-02-07T02:21:54+00:00",
"hasAttachments": false,
"internetMessageId": "<SYBPR01MB43796626ED48609438E94E9CB0DB9#SYBPR01MB4379.ausprd01.prod.outlook.com>",
"subject": "timelog",
"bodyPreview": "Record ID: 4067055\r\nName: Smith, Erin Julia\r\nTotal Hours: 7.5\r\nCreated Date: 17-JAN-2023\r\nEscalation Date: 31-JAN-2023\r\nEscalated to you By:",
"importance": "normal",
"conversationId": "AAQkADVkMTJmYTBjLTk4ZmUtNDRlMy04ZjhkLTg5MTY2ZjcyMmNhMQAQAPGPmzZrjddNiZO7kqeXB4I=",
"isRead": false,
"isHtml": true,
"body": "<html><head>\r\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"><meta name=\"Generator\" content=\"Microsoft Word 15 (filtered medium)\"><style>\r\n<!--\r\n#font-face\r\n\t{font-family:\"Cambria Math\"}\r\n#font-face\r\n\t{font-family:Calibri}\r\np.MsoNormal, li.MsoNormal, div.MsoNormal\r\n\t{margin:0cm;\r\n\tfont-size:11.0pt;\r\n\tfont-family:\"Calibri\",sans-serif}\r\nspan.EmailStyle17\r\n\t{font-family:\"Calibri\",sans-serif;\r\n\tcolor:windowtext}\r\n.MsoChpDefault\r\n\t{font-family:\"Calibri\",sans-serif}\r\n#page WordSection1\r\n\t{margin:72.0pt 72.0pt 72.0pt 72.0pt}\r\ndiv.WordSection1\r\n\t{}\r\n-->\r\n</style></head><body lang=\"EN-AU\" link=\"#0563C1\" vlink=\"#954F72\" style=\"word-wrap:break-word\"><div class=\"WordSection1\"><div><div><p class=\"MsoNormal\"><span style=\"font-size:10.0pt; font-family:"Arial",sans-serif; color:black\">Record ID: 4067055<br>Name: Smith, Erin Julia<br>Total Hours: 7.5<br>Created Date: 17-JAN-2023<br>Escalation Date: 31-JAN-2023<br>Escalated to you By:</span></p></div></div></div></body></html>",
"from": "email#email.com",
"toRecipients": "email#email.com",
"attachments": []
}
}
Thanks in advance for any help

Firstly, with the JSON you provided, there's no doubt that the easiest way to process the data is to use the bodyPreview property, not the body property.
That property gives you a much more cut down, easier view of your data.
Now on that, if it were me, I'd be doing the following.
Firstly, I created a variable with your entire payload so I could use it in later steps.
Next, the Initialize Body Preview step in the results below uses the following expression ...
variables('Trigger Data')?['body/bodyPreview']
Next, you can split up that string by line break. This is where you need to do some trickery though.
This is the expression that you need to enter ...
split(variables('Body Preview Data'), '\r\n')
... the issue is, if you enter that into the expression editor, it'll actually store the expression like this ...
split(variables('Body Preview Data'), '\\r\\n')
... but that won't work for you. To overcome this, go into the Code View and change the expression to remove the double backslashes.
That will then give you the following result.
From here, you can loop over the array and split it up again by colon and process each item as you need.

Related

Query specific value in array from a metadata entity in Dynamics 365

I'm trying to avoid iterating through this array, but I imagine that is the only way to handle this. Just seeing if there is a way to directly query this value in the array from the Web API URI.
This is the URI example:
https://example.crm.dynamics.com/api/data/v9.0/GlobalOptionSetDefinitions(f4a9de67-1d00-ea11-a811-000d3a33f702)
And this is an example of the response:
{
"#odata.context": "https://example.crm.dynamics.com/api/data/v9.0/$metadata#GlobalOptionSetDefinitions/Microsoft.Dynamics.CRM.OptionSetMetadata/$entity",
"MetadataId": "f4a9de67-1d00-ea11-a811-000d3a33f702",
"Options": [
{
"Value": 799680006,
"Color": "#0000ff",
"IsManaged": false,
"ExternalValue": "",
"ParentValues": [],
"MetadataId": null,
"HasChanged": null,
"Label": {
"LocalizedLabels": [
{
"Label": "ABC123",
"LanguageCode": 1033,
"IsManaged": false,
"MetadataId": "b4eb2c69-b500-ea11-a811-000d3a33fe19",
"HasChanged": null
}
],
"UserLocalizedLabel": {
"Label": "ABC123",
"LanguageCode": 1033,
"IsManaged": false,
"MetadataId": "b4eb2c69-b500-ea11-a811-000d3a33fe19",
"HasChanged": null
}
}
}
]
}
Basically, I have the "Value": 799680006 which is what I want to somehow add to the URI query parameters, so that I can ultimately get "Label": "ABC123".
Any suggestions or is iterating through the array of objects with if Value = x really the only option?
Let me clarify two things:
Querying metadata like you are using GlobalOptionSetDefinitions to get all the localized labels if you have multiple language packs or for verifying customizations or for Devops deployment purpose is one thing
Getting the label for the selected picklist value in one of the transaction database record is another purpose
If you simply need for second purpose, you can get it by selecting the Formatted value, after adding a header in web api request. Read more in my SO answer
Another way to inspect the label is using stringmap entity.
https://crmdev.crm.dynamics.com/api/data/v9.1/stringmaps?$filter=objecttypecode eq 'account' and attributename eq 'accountclassificationcode' and attributevalue eq 1

Get the list of action items from Google Drive API

Hi, everyone.
I have been trying to use Google Drive API for getting a list with the action items assigned in all files (docs or spreadsheets) in my company's domain using Spring Boot and the google-api-services-drive, but I have faced some issues:
Looks like there is nothing about action items on the API.
Comments are the closest I could get, but they don't include action item information. They only have the emails of people who were mentioned.
Documentation looks broad and not precise. For instance, here they say files resources include an indexableText property, but it is not present on the response.
As explained in Term for followup, looking for actionitems you can apply a query for getting the files with action items. Why is the fullText field not available in the response, or some other equivalent attribute to see the actual content and use it as a workaround to get the action items?
I just need to know who was assigned to the action item from the comment.
Any ideas?
Retrieve the action items with Comments: list specifying fields as comments/replies/action
I agree with you that it is not straightfoward, but there is a way to retrieve the full comment content including action items.
Use Files:list specifying q as fullText contains 'followup:actionitems', just as in the post you mentioned
For each of the retrieve items, use the fileId for the method Comments: list
For better understadning specify first the fields for Comments:list as * - this will return you the complete reponse looking as following:
{
"kind": "drive#commentList",
"comments": [
{
"kind": "drive#comment",
"id": "AAAAGlyxwAg",
"createdTime": "2020-06-08T09:04:34.907Z",
"modifiedTime": "2020-06-08T09:05:07.279Z",
"author": {
"kind": "drive#user",
"displayName": "XXX",
"photoLink": "//ssl.gstatic.com/s2/profiles/images/silhouette96.png",
"me": true
},
"htmlContent": "+\u003ca href=\"mailto:YYY#YYY.com\" data-rawHref=\"mailto:YYY#YYY.com\" target=\"_blank\"\u003eYYY#YYY.com\u003c/a\u003e Could you please check the spelling?",
"content": "+YYY#YYY.com Could you please check the spelling?",
"deleted": false,
"resolved": true,
"quotedFileContent": {
"mimeType": "text/html",
"value": "Hello"
},
"anchor": "kix.94ksxclyqix",
"replies": [
{
"kind": "drive#reply",
"id": "AAAAGlyxwAo",
"createdTime": "2020-06-08T09:05:02.999Z",
"modifiedTime": "2020-06-08T09:05:02.999Z",
"author": {
"kind": "drive#user",
"displayName": "YYY",
"photoLink": "//ssl.gstatic.com/s2/profiles/images/silhouette96.png",
"me": false
},
"htmlContent": "Will do!",
"content": "Will do!",
"deleted": false
},
{
"kind": "drive#reply",
"id": "AAAAGlyxwAs",
"createdTime": "2020-06-08T09:05:07.279Z",
"modifiedTime": "2020-06-08T09:05:07.279Z",
"author": {
"kind": "drive#user",
"displayName": "YYY",
"photoLink": "//ssl.gstatic.com/s2/profiles/images/silhouette96.png",
"me": false
},
"deleted": false,
"action": "resolve"
}
]
}
]
}
This response contains the following information:
The quoted file content (the text to which the comment refers)
The content of the initial comment and the replies
The user to whom the comment was assigned
The reply of the user including his user name
And finally, the action taked by the user
Now, if you are not interested in all fields but only in the action, you can see that action is a resources nested in comments/replies
To query for action, replace the * in fields with comments/replies/action
as for your question about indexableText, the documentation specifies that it is a property of contentHints and
contentHints
Additional information about the content of the file.
These fields are never populated in responses.
A way to make indexableText "useful" is e.g. apply it in queries like
Files:list with q : fullText contains 'indexableText'
The good new are that if you not happy with the way how actions are retrieved now and can think of a better method to implement it, you can file a Feature request on Google's Public Issue Tracker. If enough users show interest in the feature, Google might implement it in the future.

Loop through non-repeated elements in Tibco Designer

I am working with JSON data in Tibco Designer whose variable list is unknown over time, such as the below:
{
"d":
{
"FileSystemObjectType": 0,
"Id": 28,
"ServerRedirectedEmbedUri": null,
"ServerRedirectedEmbedUrl": "",
"ContentTypeId": "0x0100B1C6D289C2D47E44A2BA609B1F830824",
"Title": "Title 5",
"ComplianceAssetId": null,
"Personal_x0020_Details_x007c_Fir": "Name",
"Personal_x0020_Details_x007c_Mid": "Name",
"Personal_x0020_Details_x007c_Las": "Name",
"Personal_x0020_Details_x007c_Dat": "2000-01-01",
"Personal_x0020_Details_x007c_Gen": "Male",
"Personal_x0020_Details_x007c_Ema": "name#email.com",
"Personal_x0020_Details_x007c_Nat": "National",
"Personal_x0020_Details_x007c_Pre": null,
"Personal_x0020_Details_x007c_KRA": null,
"ID": 28,
"Modified": "2018-09-14T12:39:41Z",
"Created": "2018-09-14T12:39:41Z",
"AuthorId": 1073741822,
"EditorId": 1073741822,
"OData__UIVersionString": "1.0",
"Attachments": false,
"GUID": "f4f0bef9-3a5d-4a61-813d-8b5973b24316"
}
}
So, is there a way I can loop over the fields after Parsing the data into XML dynamically, given the fields are non-repeating, such that I get a "key:value" pair which I can use for other purposes?
If you do not want to use a particular java code (json xml) you can try to tokenize the input JSON string based on "}", ":", and "," into hierarchical string arrays (no strict typing in JSON). You can use regexp (I use a java function jar to extend the xpath mapper) to make the basic "{ ... }" recursive splitting and then tokenize by ":" and finally strip off leading and trailing '"'. If you invoke the splitting recursively you also get the hierarchical string array you want to have to represent the hierarchical JSON. I'd prefer using a java code for this.

jmeter json path Conditional Extraction at peer level

I'm using jmeter v2.13 and jp#gc - JSON Path Extractor.
Here is my JSON sample:
{
"views": [{
"id": 9701,
"name": " EBS: EAS: IDC (EAS MBT IDC)",
"canEdit": true,
"sprintSupportEnabled": true,
"filter": {
"id": 55464,
"name": "Filter for EBS: EAS: IDC & oBill Boar",
"query": "project = \"EBS: EAS: IDC\"",
"owner": {},
"canEdit": false,
"isOrderedByRank": true,
"permissionEntries": [{
"values": [{
"type": "Shared with the public",
"name": ""
}]
}]
},
"boardAdmins": {}
},
{}
]
}
Is it possible to extract views[x].id where there exists an entry views[x].filter.permissionEntries[*].values[*].type that equals Shared with the public?
How would I do it?
Thanks
JSON Query would look like this (I admit I didn't try it in JMeter)
$.views[?(#.filter[?(#.permissionEntries[?(#.values[?(#.type == "Shared with the public")])])])].id
Explanation:
We expect under root ($) to have views and for it to have property id. The rest (in []) are conditions to select only views items based on predefined condition. Hence $.views[conditions].id
Conditions in this case are coming one within the other, but main parts are:
We define condition as a filter ?(...)
We ask filter to look under current item (#) for a specific child item (.child), child may have its own conditions ([...]). Hence #.child[conditions]. That way we move through filter, permissionEntries, values
Finally we get to field values and filter it for a child type field with particular value Shared with the public. Hence #.type == "Shared with the public"
As you see it's not very intuitive, and JSON path is a bit limited. If this is a repetitive issue, and your JSON is even more complicated, you ay consider investing into a scriptable pre-processor (similar to the one explained here.

Filter video list by tag

Goal
Get videos, ordered by date, and filtered by tag from a specific YouTube channel. I need only the videos that have that unique tag. I understand I can get the latest uploaded videos, then one by one query YouTube API for each video and determine if it has the tags I need. But I find that too lengthy and wonder if there's a single API request than can handle that filter for me.
Tried
Reading this API documentation I understood the snippet was supposed to have a snippet.tags:
snippet.tags[]
list
A list of keyword tags associated with the video. Tags may contain spaces. The property value has a maximum length of 500 characters. Note the following rules regarding the way the character limit is calculated:
The property value is a list, and commas between items in the list count toward the limit.
If a tag contains a space, the API server handles the tag value as though it were wrapped in quotation marks, and the quotation marks count toward the character limit. So, for the purposes of character limits, the tag Foo-Baz contains seven characters, but the tag Foo Baz contains nine characters.
Using the following (search/list)
https://www.googleapis.com/youtube/v3/search?part=snippet&channelId=CHANNEL_ID&maxResults=10&order=date&type=video&key=MY_GOOGLE_CONSOLE_KEY
I get:
{
"kind": "youtube#searchResult",
"etag": "\"cbz3lIQ2N25AfwNr-BdxUVxJ_QY/MO86DiShKKJ483oXkFJdDmvBd5M\"",
"id": {
"kind": "youtube#video",
"videoId": "jMywJTXhkVs"
},
"snippet": {
"publishedAt": "2017-09-16T15:28:40.000Z",
"channelId": "UC4GRKWUEhUvsCqD-yNQpxQw",
"title": "Real Time - Gesture Drawing 7 (5.10 mins time)",
"description": "Join me in gesture drawing practice from photo reference. :) References (in order of drawing) - Thank you to SenshiStock (https://senshistock.deviantart.com/) ...",
"thumbnails": {
"default": {
"url": "https://i.ytimg.com/vi/jMywJTXhkVs/default.jpg",
"width": 120,
"height": 90
},
"medium": {
"url": "https://i.ytimg.com/vi/jMywJTXhkVs/mqdefault.jpg",
"width": 320,
"height": 180
},
"high": {
"url": "https://i.ytimg.com/vi/jMywJTXhkVs/hqdefault.jpg",
"width": 480,
"height": 360
}
},
"channelTitle": "Chayemor",
"liveBroadcastContent": "none"
}
}
The snippet only includes publishedAt, channelId, title, and description, certainly no tags.
Looking into /search/list documentation I see that it has another parameter that I might be able to use:
q
string
The q parameter specifies the query term to search for.
Your request can also use the Boolean NOT (-) and OR (|) operators to
exclude videos or to find videos that are associated with one of
several search terms. For example, to search for videos matching
either "boating" or "sailing", set the q parameter value to
boating|sailing. Similarly, to search for videos matching either
"boating" or "sailing" but not "fishing", set the q parameter value to
boating|sailing -fishing. Note that the pipe character must be
URL-escaped when it is sent in your API request. The URL-escaped value
for the pipe character is %7C.
So I use the tag "sketching" that I know is set in various videos. (A way to determine if a single video's tags is through https://www.googleapis.com/youtube/v3/videos?key=GOOGLE_KEY&fields=items(snippet(title,description,tags))&part=snippet&id=video_id )
https://www.googleapis.com/youtube/v3/search?q=%22sketching%22&part=snippet&channelId=CHANNEL_ID&maxResults=25&order=date&type=video&key=GOOGLE_KEY
That yields this:
{
"kind": "youtube#searchListResponse",
"etag": "\"cbz3lIQ2N25AfwNr-BdxUVxJ_QY/hPC7YXbOHVWNEk_6UiC5Jzdh5Zs\"",
"regionCode": "ES",
"pageInfo": {
"totalResults": 10,
"resultsPerPage": 25
},
"items": []
}
Nothing else. It says there are 10 results, but I don't see them, I do't know what they are. I tried sending the request without the "" but it returned the same result. Messing around I saw that when searching within a channel's videos from YouTube (as a browser client, through GUI, not API), it uses the parameter 'query'. So out of not having any more ideas I decided to substitute q for query.
https://www.googleapis.com/youtube/v3/search?query=sketching&part=snippet&channelId=UC4GRKWUEhUvsCqD-yNQpxQw&maxResults=25&order=date&type=video&key=GOOGLE_KEY
That query did yield results, but not of those videos who had that unique tag, but rather any video that had that tag or that word used in the title or description.
{
"kind": "youtube#searchListResponse",
"etag": "\"cbz3lIQ2N25AfwNr-BdxUVxJ_QY/xjWZRnm0X7B_csQX4KEu9nv_qdQ\"",
"regionCode": "ES",
"pageInfo": {
"totalResults": 24,
"resultsPerPage": 25
},
"items": [ ... ]
}
Any suggestions?

Resources