How Do I Copy 6 Fields of Text From an Email & Paste Into My Notes App?

Rather than just echoing @ccstone's excellent advice, I'll add that how you do this really does depend on how the content of the email is structured. If you've any control on how the data is sent you can make your life considerably easier. Eg:

clientID:56726
clientName:
companyName:Example Inc

...is simpler to parse than:

Client ID
56726
Client Name
Company Name
Example Inc

Any specific advice will depend on the data structure, so you'll need to post examples.

@ccstone @Nige_S Thank you both for the responses. I will be give it a shot in a little while and see where we end up then update this post. Your guidance is very much appreciated.

@Nige_S I do have the option to dictate how the form spits out, I will have it changed to the way that works best. Thank you!

@Nige_S
The email would look like this:

Entity: theChimichanga
CandidateName: Mike Test
ClientName: Company Name
Position: Title
EmployeeID: 1234567

Or any variation you think would be better. I have created variables for each. The Variable cloud would have this info once the information is pulled from the email titled "Email Title":

varEntity - theChimichanga
varName - Mike Test
varClient - Company Name
varClass - Title
varEmpID - 1234567

These variables will then be entered and used for various things - I already got this part down. Copying the email to variable is done, as well, as @ccstone instructed. So all that is now left is to get the information from the email and assigning it to a variable.

I am trying the regex path now.

Before you go too far...

varEntity is a "global variable" (see "Variable Scope") so any value you set will persist across macro invocations. That might be what you want but if one of your regexs fail for any reason the variable will retain its value from before, which is probably wrong for this run of the macro. It shouldn't fail, but we shouldn't rely on "shouldn't" :wink:

You could blank all those variables at the start of the macro, for safety, or make sure the macro aborts on error (but then you could have some variables changed, some not) -- but if you don't need the values to persist then better to scope the variables as "Instance" (available in this instance of this macro and its sub-macros) or "Local" (this instance of this macro).

Ugh, ok. You are correct again. Each variable can be wiped after my. macro ends. Here is the other issue I am facing, I have no clue how to operate the regex codes. I read the websites and kind people explaining it. I am not asking for you to do it, I would prefer to learn. Is there a guide out there that you would recommend? I have gone through a bunch already.

Hey Mike,

Good goal, but It'll take you too long this time around.

Here's an example of what it takes to accomplish your task:

Scraping Email Data with RegEx.kmmacros (7.5 KB)
Keyboard Maestro Export

Learning regular expression well is a time consuming process. You have to have a goal and then study, practice, get frustrated, ask questions, and practice some more.

Learning the basics doesn't take all that long though, and once you start getting them to do what you want they can be fun.

Download BBEdit if you don't have it already. You don't need to buy it. It will revert to a freeware (Lite) version after a demo period, and the lite version has good regex support. (The commercial version has a regex playground which is pretty nice, but you can get a lot of that for free from https://regex101.com).

BBEdit is a good testing ground for regular expressions – although keep in mind that it uses PCRE regex while Keyboard Maestro uses ICU regex.

The good folks at Bare Bones Software have been building BBEdit since 1992, and it's nice to support them by buying the product if it is useful to you – but no pressure.

BBEdit's user manual on regular expressions is decent.

Keyboard Maestro Wiki on RegEx

Look through this topic on the forum:

How Did You Learn RegEx (Regular Expressions)?

This might be worth your time:

The site he's using in the vid:

https://regexr.com

-Chris

1 Like

Laudable -- but one way to learn is by example :wink: While @ccstone's regex is neat, here's one that riffs on his previous "don't be afraid to use more than one action" that you might find both more understandable and easier to maintain.

You start by looking for the pattern(s) you want to match in your input. We're going to do the variables one at a time so, for entity...

"Find the line that starts with Entity: and save everything after that to the end of the line to the variable."

When you are searching a multi-line text block the "flag option" (?m) lets you use ^ and $ as beginning- and end-of-line matches for each individual line respectively (otherwise they match the beginning and end of the entire text). We want the line-start and line-end, so (?m)^...$.

We want to find the line starting with "Entity: ", so (?m)^Entity: ...$.

We want to match every character after : until the end of the line. We don't know of that will be one, ten, or a hundred characters -- or even zero, if they leave the field empty. So we use .* to match "any character (.) zero or more times but as many as possible (*). So (?m)^Entity: ....*...$.

And finally we want to "capture" that last part of the match to put into our variable -- to do that you wrap the pattern to capture with ( and ). Which leaves us with (?m)^Entity: (.*)$.

You do the same with (?m)^CandidateName: (.*)$, and so on.

Putting that all together:

regex test.kmmacros (5.4 KB)

Image

2 Likes

The two of you are unreal. Let me start by thanking you both for taking the time to work through this and making it a lesson while doing it.

I am reading/replying from my phone at the moment... so I won't get to put it together until later. But wow. Thank you. I will update when I get it running.

Mike

1 Like

@ccstone @Nige_S,

Incredible. I understand where this is heading... and using it to guide things in the future, which great. Now the only thing I am stuck on is getting it triggered by an email. I thought I had it figured out. But I don't think I do. There is a process out there that I was using. But it doesn't seem to be working.

What I am trying to do is replace the test command you both set up setting the initial information variable (Chris: sourceData, Nigel: Local_testString, Me: varNHF)

Goal: When an email comes in with the subject line "New Hire Form" (Mac mail) - The body of the email is what we will be parsing using RegEx as you both showed me above. So I want to set the body of the text to varNHF and then parse the information within the variable. Like you guys have both shown above.

If I use Chris' AppleScript above, I would have to select the email each time. The other script I am trying is supposed to trigger the macro and then set the variable. But it's not. ALTHOUGH... I think I just realized something. I think I am saving the subject line as the variable instead of the body. I am posting the script below, will you be able to tell me which lines need to be fixed and the proper terminology needed to grab the body INSTEAD of subject?

I see where it is asking for Subject. I tried changing the KM part to Content like your script has above but it didn't work.

using terms from application "Mail"
   on perform mail action with messages theMessages for rule theRule
      tell application "Mail"
         repeat with eachMessage in theMessages
            set theSubject to subject of eachMessage
         end repeat
      end tell
      
      tell application "Keyboard Maestro Engine"
         make variable with properties {name:"varNHF", value:theSubject}
         do script "E5DF7AD7-BC25-48A3-88CF-0611B5B96AF0"
      end tell
      
   end perform mail action with messages
end using terms from

Yes. If you look at the AppleScript Dictionary for Mail (in Script Editor, File->Open Dictionary... and select Mail from the list) you'll find "Message" along with a list of properties. One is "subject", which you are getting in your script. The one you want is either "content" or "source", depending on the format of the message you are getting -- try both and see which works best.

And again you're using a global variable to pass data. It's generally better to avoid globals unless you have a need for them. In this case, imagine a scenario where you receive two rule-triggering messages. It's possible that the first fires the rule, sets the global, and triggers the macro -- but the second fires the rule and resets the global before the first macro has finished, so the first macro continues but uses values meant for the second...

You can get round that by using parameters -- supply a parameter in your AppleScript call and you can use it in your macro with the %TriggerValue% token. Totally untested (and written verbosely to make things more obvious), but your script would look more like:

using terms from application "Mail"
	on perform mail action with messages theMessages for rule theRule
		tell application "Mail"
			repeat with eachMessage in theMessages
				set theContent to the content of eachMessage -- gets rich text content
				tell application "Keyboard Maestro Engine"
				    do script "E5DF7AD7-BC25-48A3-88CF-0611B5B96AF0" with parameter theContent
				end
			end repeat
		end tell		
	end perform mail action with messages
end using terms from

...and the first action of your macro would then be:

TriggerValue

1 Like


Keyboard Maestro Actions (2).kmactions (2.5 KB)

Alright, I changed Entity to Ent to fix that

It's still not working out. I don't know if it is something I am missing because it's late on a Sunday, or it's just not clicking with me.

using terms from application "Mail"
   on perform mail action with messages theMessages for rule theRule
      
      tell application "Mail"
         repeat with eachMessage in theMessages
            set theSource to source of eachMessage
         end repeat
      end tell
      
      tell application "Keyboard Maestro Engine"
         make variable with properties {name:"varNHF", value:theSource}
         do script "E5DF7AD7-BC25-48A3-88CF-0611B5B96AF0" with parameter theSource
      end tell
      
   end perform mail action with messages
end using terms from

That is what my AppleScript is looking like now. What am I doing wrong? So in Apple Mail, I have it set to run the script when in an email comes in with the subject line "NewHireForm". And then, it is also not triggering the KM macro. I'm lost.

Start by changing your AppleScript so you get the content of eachMessage rather than source -- by my and @ccstone's regex will break if the source is HTML etc rather than plain text. And on't loop through the messages then loop through the macros -- do one macro call per message as I did above.

Are you sure you rule is triggering (add a "Play Sound" action to the rule to test that). Once that's working, disable all the actions in your macro and put in a "Play Sound" action at the beginning -- do you get that sound? If so, the macro is triggering. If not, check that the UUID in the AppleScript still matches the UUID in the macro's trigger.

Once you've got the macro making the sound, put in a single "Display text in a window" action to display %varNHF% -- that way you can compare the text the macro is getting to your regex and see if it will actually work (mine, and I believe Chris's, will both fail if for example you have spaces at the beginning of each line).

You really need to post your macro, not just some actions, for us to help more. It might be that an action before the ones you've shown us is aborting the macro before it gets to this section. If you can't post the whole thing, perhaps it's very long or has some confidential info, create an example macro with only the necessary steps to display the same problem. And a sample of the text your AppleScript is extracting from the email.

You're still using global variables (see above for why this is bad unless you need to use them), and the first two actions you've shown us appear pointless (you don't use Local_testString after setting it and "Trim whitespace" doesn't help in any way) which is why I worry about the rest of the macro...

First part - I added a sound when the macro hits... nothing. I checked to make sure everything in mail rules and AppleScript was spelled correctly. It is. So there is the first issue lol. I have the AppleScript exactly as you have it in yours. I checked the UUID number was accurate (recopied and pasted). Nothing.

What about the bit before that -- adding a "Play Sound" action to the rule to make sure it is actually firing?

It will also help if you let us know your Apple Mail version number so people can try and replicate the issue.

Apple Mail Version: 16.0 (3696.120.41.1.1)

using terms from application "Mail"
	on perform mail action with messages theMessages for rule theRule
		tell application "Mail"
			repeat with eachMessage in theMessages
				

				tell application "Keyboard Maestro Engine"
					do script "E5DF7AD7-BC25-48A3-88CF-0611B5B96AF0" with parameter theContent
					

				end tell
			end repeat
		end tell
	end perform mail action with messages
play sound beep
end using terms from

Ok, the beep is beeping when I send the email.

The email looks like this:

Subject: NewHireForm

Entity: theChimichanga
CandidateName: Mike Test
ClientName: Target
Class: Person working at Target
EmployeeID: 1234567

image

I also followed your instruction and changed the variables to "local" (The variables match in the regex as well... I just took the screen grab of the text part)

You need to post your actual macro -- not the image of your macro. The instructions on how to do that are here.

You've removed the bit of the AppleScript that gets the content of the message. Your script is now likely failing because you are passing an undefined variable as the script parameter. And, unless you've changed it again since posting the image, you aren't even using the parameter in the macro -- you're setting your variable manually to static text.

I didn't post the entire macro for privacy reasons. I thought the image would be enough, sorry. I will change some things and then send the actual macro.

I readied the AppleScript content part. Not sure where it went, must have deleted it in all my meddling.

And then the last part of what you just said... the variable being set manually - I actually have that disabled, it was just a copy and paste part from the test scripts. BUT - for the parameter piece, should it look like this? :

image

I am cleaning up and going to send full macro shortly.

Timesheet Generator copy.kmmacros (24.8 KB)

Here is the macro with some random content. NOTE: I have not yet updated the variables in the rest of the macro because I disabled it all and was waiting until I did the top portion correctly (after working with you). I will update the variables now.

1 Like

Nowhere in that macro are you actually setting the variable varNHF to anything. It's still a global so will be using whatever value it was last set to.

So you aren't using any parameter you are passing in with the AppleScript, whatever does happen has nothing to do with the email you think you are processing. Also -- and this may just be because you are working on a copy -- the macro UUID is not the same as the one you are using in the AppleScript.