cancel
Showing results for 
Search instead for 
Did you mean: 
Reply
Anonymous
Not applicable

Read email content from body of the email, extract and create conditions or actions

I would love to be able to create a flow that can read the body of the email not just subject or attahcments names.  Once it can read the body of the text and find key words, extract some of this content. Identify if its a date or string and create a calendar event, etc. 

 

1 ACCEPTED SOLUTION

Accepted Solutions
v-xida-msft
Community Support
Community Support

Hi @Anonymous,

 

Could you please share an example about your scenario?

Do you want to extract content from body of the email?

 

I assume that the details of your incoming email as below and you want to extract the Subject and End time content from Body of the email:2.JPGI have made a test on my side and please take a try with the following workaround:

  • Add a "When a new email arrives" trigger.
  • Add a "Html to text" action, Content field set to Body dynamic content of the trigger.
  • Add a "Compose" action, Inputs set to following formula:
  • length(body('Html_to_text'))
    Add a "Compose 2" action, Inputs set to following formula:

 

add(indexOf(body('Html_to_text'),'End time'),10)
  • Add a "Compose 3" action, Inputs set to following formula:
  • substring(body('Html_to_text'),outputs('Compose_2'),sub(outputs('Compose'),outputs('Compose_2')))
    Add a "Compose 4" action, Inputs set to following formula:
  • add(indexOf(body('Html_to_text'),'Subject'),9)
    Add a "Compose 5" action, Inputs set to following formula:
  • indexOf(body('Html_to_text'),'Start time')
    Add a "Compose 6" action, Inputs set to following formula:
  • substring(body('Html_to_text'),outputs('Compose_4'),sub(outputs('Compose_5'),outputs('Compose_4')))
    Add a "Create event (V1)" action, specify Calendar id, End time field set to output of "Compose 3" action, Start time field set to following formula:
utcNow()

Subject field set to output of "Compose 6" action.

 

Image reference:3.JPG

 

4.JPG

The flow works successfully as below:5.JPG7.JPG

 

6.JPG

 

Best regards,

Kris

 

 

 

 

 

 

 

 

Community Support Team _ Kris Dai
If this post helps, then please consider Accept it as the solution to help the other members find it more quickly.

View solution in original post

18 REPLIES 18
v-xida-msft
Community Support
Community Support

Hi @Anonymous,

 

Could you please share an example about your scenario?

Do you want to extract content from body of the email?

 

I assume that the details of your incoming email as below and you want to extract the Subject and End time content from Body of the email:2.JPGI have made a test on my side and please take a try with the following workaround:

  • Add a "When a new email arrives" trigger.
  • Add a "Html to text" action, Content field set to Body dynamic content of the trigger.
  • Add a "Compose" action, Inputs set to following formula:
  • length(body('Html_to_text'))
    Add a "Compose 2" action, Inputs set to following formula:

 

add(indexOf(body('Html_to_text'),'End time'),10)
  • Add a "Compose 3" action, Inputs set to following formula:
  • substring(body('Html_to_text'),outputs('Compose_2'),sub(outputs('Compose'),outputs('Compose_2')))
    Add a "Compose 4" action, Inputs set to following formula:
  • add(indexOf(body('Html_to_text'),'Subject'),9)
    Add a "Compose 5" action, Inputs set to following formula:
  • indexOf(body('Html_to_text'),'Start time')
    Add a "Compose 6" action, Inputs set to following formula:
  • substring(body('Html_to_text'),outputs('Compose_4'),sub(outputs('Compose_5'),outputs('Compose_4')))
    Add a "Create event (V1)" action, specify Calendar id, End time field set to output of "Compose 3" action, Start time field set to following formula:
utcNow()

Subject field set to output of "Compose 6" action.

 

Image reference:3.JPG

 

4.JPG

The flow works successfully as below:5.JPG7.JPG

 

6.JPG

 

Best regards,

Kris

 

 

 

 

 

 

 

 

Community Support Team _ Kris Dai
If this post helps, then please consider Accept it as the solution to help the other members find it more quickly.

View solution in original post

Anonymous
Not applicable

Kris,

 

My apologies for the late reply. I appreciate how creative the proposed solution is!

 

 

Thank you,

 

JP 

Thanks for the detailed desciption, I tried to run it as described above but hot the following error;

 

The string was not recognized as a valid DateTime. There is an unknown word starting at index 10. clientRequestId: c7e6674c-5d20-458b-b65a-c692c6fef136

WillPage
Impactful Individual
Impactful Individual

@v-xida-msft I know this is an old thread, but I found it while looking for a solution to the same problem.

 

The difference with mine is the data I'm looking for doesn't match a nice pattern that can be easily defined by say.. add(indexof ......), 10

 

For example the email has this data:

 

Enquiry from: Firstname Lastname
Email: user@gmail.com
Phone Number: 0299999876
First Night: Thursday, 17 January 2019
Number of Nights: 2

 In each of these lines the number of characters to add to the indexof is different for each email.

 

How can I use a function to grab everything between the colon and the new line, trim it and place it in a variable?

 

I will also put this in a new thread.

Hi @Kris

 

Can you explain how to convert this example if the details repeated, how to loop through all iterations? I have a similar case, the number of items per email does very.

 

Outlook Calendar event details as below

Subject: FirstTestEvent
Start Time: 4/20/2019
End Time: 4/21/2019

 

Subject: SecondTestEvent
Start Time: 4/21/2019
End Time: 4/22/2019

 

Subject: ThirdTestEvent
Start Time: 4/22/2019
End Time: 4/23/2019

 

 

 

WillPage
Impactful Individual
Impactful Individual

@HallieGUse the Split() expression to split on 'Subj' and then run the resulting array through a for-each.

Did you find any solutions to this? I'm trying to figure the same thing out. How to do this for data that might be a bit unstructured. For example, how do I grab whatever is between a "$" and ":" sign?

Hi! Did you ever find out how to do this? I'm facing the same issue.....

Anyone know how to do it as said in last posts here?

WillPage
Impactful Individual
Impactful Individual

@Yanger @Brammers & @sxt173 Yes I have solved this. A long time ago I wrote a lengthy response in this thread with detailed steps and an explanation of how it all works. I spotted some typos, then did a couple of edits to fix them and it disappeared pending moderation. It has never re-appeared.

 

Probably enough time has passed to get over this immense frustration and I can re-do it. Maybe this weekend if I remember.

WillPage
Impactful Individual
Impactful Individual

A somewhat abridged version of my original deleted reply:

 

Starting with this sample data:

Enquiry from: Firstname Lastname
Email: user@gmail.com
Phone Number: 0299999876
First Night: Thursday, 17 January 2019
Number of Nights: 2

To grab any of those fields in Flow you use a formula like this (example grabs the email)

 

trim(substring(body('Html_to_text'),add(indexOf(body('Html_to_text'),'Email: '),7),sub(indexOf(body('Html_to_text'),'Phone Number: '),add(indexOf(body('Html_to_text'),'Email: '),7))))
 
So I'll break it down.
trim(
	substring(
		body('Html_to_text'),
		add(
			indexOf(
				body('Html_to_text'),
				'Email: '
				),
			7),
			sub(
				indexOf(
					body('Html_to_text'),
					'Phone Number: '),
		add(
			indexOf(
				body('Html_to_text'),
				'Email: '
				        ),
			7)
		)
	)
)

The subsstring() function has 3 inputs, 1. the source string, 2. the start index, which is the number of characters into the string to start looking and 3. the length.

 

The objective therefore, is to derive 2. and 3. so we can grab the relevant text no matter how long is it.

 

So firstly we need to know how many characters into the source text to start. This is relatively easy:

add(
	indexOf(
		body('Html_to_text'),
		'Email: '
	   ),
7)

The indexOf() function finds the number of characters into a text string that a string occurs. Here we are calculating the indexOf() the string "Email: " it doesn't matter where in the original message body this occurs, indexOf() will find it and return a number.

 

Now we don't actually want the string "Email: " in the output of this expression so we now add() a number to the output of indexOf() to get the number of characters into the message body the end of "Email: " occurs. We don't calculate this dynamically; it's 7, including the space.

 

So by using indexOf() to find the place in the source string where "Email: " exists, then adding that number of characters to it, we get the point we want to start reading the email address.

 

Next we have to calculate the length of the string, for the 3rd parameter of substring():

sub(
	indexOf(
			body('Html_to_text'),
			'Phone Number: '),
	add(
		indexOf(
			body('Html_to_text'),
			'Email: '
			),
		7)
	)

To do this we use the sub() function to subtract the number we just calculated from the indexOf() the place we want to stop looking. Thus a lot (the second parameter of sub()) of the expression above is similar to the one before - calculating the number of characters into the source string that our relevant text starts.

 

The first parameter of sub() is the place where our relevant text ends - which in this case is the start of the string "Phone Number: ". We don't need to do anything complex with this because it's the start of the string we want the index of, not the end.

 

So we now have our 3 parameters for substring(), the source text, which is body('Html_to_text') in this example, the number of characters into that where we find the start of our substring and lastly length, which is calculated by subtracting the former from the number of characters into the source text where we want to stop looking.

 

Finally, in my example I've wrapped trim() around the whole thing to eliminate any trailing whitespace.

 

You could probably improve upon this by calculating the number of characters where your desired string starts in a compose action, then using that as dynamic content in the expression to simplify it a bit, instead of repeating the same formula twice in the one expression.

@WillPage I want to do exactly the same thing, I need to get an email address from the body of an email and send a new email to that address. My email account is Gmail. Where do I place the code you posted below? (totally new to flow). Obviously my first condition is "When a new email arrives" and I assume the next is where I paste your code but you don't mention what type of action to select. And I also assume my next action is to send a new email but what do I put in the "to" field there?

WillPage
Impactful Individual
Impactful Individual

@pjmarcumStraight after your trigger, add an HTML to Text action and put the body of the email from the trigger in there. Next, add a Compose and put the expression there, using the output of the previous HTML to Text action in the expression.

LOL.... I'm sure this is great feedback but unfortunately way above my expertise. 🙂

Hi @v-xida-msft ,

 

My case is a little different and I want to extract the email address after the From: of a forwarded email. Does the number of Compose change and do I need to change the code for them? 

 

vradley_0-1597937641125.png

 

 

 

WillPage
Impactful Individual
Impactful Individual
amenegatti
New Member

Hello Team,

 

Any recommendations on trying to extract say a reference number that will start with CX but could be anywhere in the email body on any new email. there is no set template and can come through anytime. 

 

Regards, 

 

Andy 

WillPage
Impactful Individual
Impactful Individual

If the reference number is always the same number of characters then you would use substring like this. Assume it's a 8 character reference including the CX (and you want to keep the CX in the substring)

substring(body('HTML_to_Text'),indexOf(body('HTML_to_Text'),'CX'),8)

 

..where body('HTML_to_Text') is the output of your HTML to text conversion action.

 

A few pitfalls: This will always find the first instance of CX in the text. If you have many then it's more complicated finding the right one.

 

Thankfully there are few ordinary words with cx in them but there's a small chance of picking that up too.

 

Another method you could use is this:

 

Split(body('HTML_to_Text'),'CX') to create an array of strings that start at each instance of CX (without the actual CX bit at the front), with the first item being the start of the whole input..

 

Now if your ref numbers are always 8 characters including CX you add a Select action, click the little icon to change from key-value input to JSON input and do this in the expression editor concat('CX',substring(item(),0,6).

 

The resulting array will be a list of possible reference numbers. Not knowing what they look like I can't advise how to filter out invalid ones (the first one will almost certainly be invalid) but at this point you can do further processing to get rid on any bogus elements in the array and hone down to the valid one(s).

 

Helpful resources

Announcements
Process Advisor

Introducing Process Advisor

Check out the new Process Advisor community forum board!

MPA User Group

Welcome to the User Group Public Preview

Check out new user group experience and if you are a leader please create your group

V3_PVA CAmpaign Carousel.png

Community Challenge - Giveaways!

Participate in the Power Virtual Agents Community Challenge

Carousel 2021 Release Wave 2 Plan 768x460.jpg

2021 Release Wave 2 Plan

Power Platform release plan for the 2021 release wave 2 describes all new features releasing from October 2021 through March 2022.

Top Kudoed Authors
Users online (3,310)