Parse and Find strings in an email address using AppleScript with Outlook - email

I am trying to create custom rules for received emails in Outlook 2016 on a Mac. I need to examine the recipients to check for some addresses. I have the following code, but I am stuck when it comes time to look at the address for debugging purposes
tell application "Microsoft Outlook"
set theMessages to messages of folder "Inbox" of exchange account "myact"
repeat with aMessage in theMessages
set sSubject to subject of aMessage as text
set sSender to address of (get aMessage's sender)
set tContent to content of aMessage as text
repeat with i from 1 to count of to recipients of aMessage
set sTo to email address of (get aMessage's to recipient i) as text
display dialog sTo
end repeat
end repeat
end tell

I was able to fix this by replacing
set sTo to email address of (get aMessage's to recipient i) as text
with
set sTo to address of (get (aMessage's cc recipient i)'s email address)

Related

How to download an attachment from mail via applescript and mail rules?

I automatically receive a lot of vcards via email and I want to import them automatically into my contacts.
I coded an AppleScript that will open the vcard file and import the contact. But first I need to download the file, right?
But how can I download an attachment file from an email using AppleScript and rules in mail?
Thank you.
Cheers,
Chris
The script bellow saves the files attached in a selection of emails into a destination folder. you can then use these files to add them in Address Book.
set Dest to ((path to desktop folder) as string) & "FMail:" -- the folder to save attached files
tell application "Mail"
activate
set ListMessage to selection -- take all emails selected
repeat with aMessage in ListMessage -- loop through each message
set AList to every mail attachment of aMessage
repeat with aFile in AList --loop through each files attached to an email
if (downloaded of aFile) then -- check if file is already downloaded
set Filepath to Dest & (name of aFile)
save aFile in Filepath as native format
end if
end repeat -- next file
end repeat -- next message
end tell
I added many comments to make it clear. then you will be able to adapt it to your needs.
For Mail Version 8.2 (2104) in macOS 10.10.5, you need to download to the download folder. Thus, I change the first line of pbell's solution to
set Dest to ((path to home folder) as string) & "Downloads:" -- the folder to save attached files
(*
Mail Version 8.2 (2104) year 2015
macOS 10.10.5
*)
set Dest to ((path to home folder) as string) & "Downloads:" -- the folder to save attached files
log "Dest is " & Dest
tell application "Mail"
activate
set ListMessage to selection -- take all emails selected
repeat with aMessage in ListMessage -- loop through each message
set AList to every mail attachment of aMessage
repeat with aFile in AList --loop through each files attached to an email
if (downloaded of aFile) then -- check if file is already downloaded
set Filepath to Dest & (name of aFile)
log "Filepath is " & Filepath
save aFile in Filepath as native format
end if
end repeat -- next file
end repeat -- next message
end tell

How can I perform actions on a mail created with redirect?

I have written - with the help of various sources of course -, this script to redirect mail in bulk: it redirects all mail selected in the mail app. There seems to be nothing special going on.
tell application "Mail"
set AppleScript's text item delimiters to ""
set theRedirectRecipient to "redirectmail#mail.mail"
set theRedirectSender to "Sender"
set theMessages to the selection
repeat with thisMessage in theMessages
tell application "Mail"
set theRedirectedEmail to redirect thisMessage with opening window
tell theRedirectedEmail
if subject of thisMessage is "" then
set subject of theRedirectedEmail to "Mails zonder subject"
end if
make new to recipient at beginning of to recipients with properties {address:theRedirectRecipient}
#delete bcc recipients
#delete cc recipients
end tell
#delay 2
#send theRedirectedEmail
end tell
end repeat
end tell
As above, the script runs fine: it creates the redirect mail, and if I press the send button, it works like I need it to.
But there are 3 lines commented out that do not work. The delete lines and the send line. I'm not really sure I care about the delete ones, but I have included them in case someone can see a pattern.
Uncommenting one of those lines gives me this error:
error "Mail got an error: Can’t get every cc recipient of outgoing
message id 18." number -1728 from every cc recipient of outgoing
message id 18
Again, this does create a message-window that I can send successfully if done by hand.
Uncommenting the 'send' line introduces the following error:
error "Mail got an error: outgoing message id 19 doesn’t understand
the “send” message." number -1708 from outgoing message id 19
So what I have concluded is that the created message doesn't behave as a message 'should'. I have seen this thread about an 'outgoing message' that seems to display this behaviour.
What is going on with this message called theRedirectEmail? How can I send messages to this object, like delete and send?
I noticed this same issue. Here's the workaround I came up with. In some ways, it's actually easier:
tell application "Mail"
set AppleScript's text item delimiters to ""
set theRedirectRecipient to "redirectmail#mail.mail"
set theRedirectSender to "Sender"
set theMessages to the selection
repeat with thisMessage in theMessages
redirect thisMessage with opening window
tell application "System Events"
tell application process "Mail"
tell window 1
--wait for mail message to appear before continuing
repeat while not (text field "To:" exists)
end repeat
set value of text field "To:" to theRedirectRecipient
set value of text field "Cc:" to ""
if text field "Bcc:" exists then
set value of text field "Bcc:" to ""
end if
if value of text field "Subject:" is equal to "" then
set value of text field "Subject:" to "Mails zonder subject"
end if
end tell
tell application "Mail" to activate
click menu item "Send" of menu 1 of menu bar item "Message" of menu bar 1
end tell
end tell
end repeat
end tell
You have to tell Mail to activate, because Mail doesn't allow the sending of email when it's in the background, probably to prevent evil-doers from spamming your entire contacts list in the background, without your knowledge, using AppleScript. This may be related to the strange behavior of mail regarding outgoing messages too, though I can't be sure...

applescript - copy paste sender's email address to numbers

is it possible that when a new email message is received to run applescript to copy sender’s email address to clipboard and paste it to next empty cell in column e in numbers, I've been trying with this, but it doesn't select the first message
thanks in advance :)
property workFlowPath : quoted form of ("/Users/pl 1/Library/Application Scripts/com.apple.mail/accepted.workflow") --CHANGE THIS TO YOUR FULL WORKFLOW FILE PATH example "/Users/pl 1/Library/Application Scripts/com.apple.mail/accepted.workflow"
using terms from application "Mail"
on perform mail action with messages theMessages for rule theRule
repeat with eachMessage in theMessages
(*Get the email Subject *)
set input_Argument to subject of eachMessage
(*Run subroutine for workflow *)
my runAutomator(input_Argument)
end repeat
end perform mail action with messages
end using terms from
(*Workflow Subroutine *)
on runAutomator(input_Argument)
(*Path to workflow *)
(*Setup and Run the unix command *)
set command to "/usr/bin/automator -i " & quoted form of input_Argument & space & workFlowPath
do shell script command
end runAutomator
on run {input, parameters}
tell application "Numbers"
tell application "Finder"
set theFile to POSIX file “/Users/pl 1/Google Drive/Publication Submission Tracker2.numbers"
open theFile
end tell
end tell
return input
end run
________pause for 5 seconds______
tell application "Mail"
reopen
activate
set theSenderList to {}
set theMessages to the first message of message viewer 0
repeat with aMessage in theMessages
set oneAddress to extract address from sender of aMessage
set end of theSenderList to oneAddress
end repeat
set the clipboard to (theSenderList as string)
end tell
return
end run
________pause for 5 seconds______
tell application "Numbers"
reopen
activate
tell application "System Events" to tell process "Numbers"
set currentCell to "e2"
keystroke "v" using {command down}
end tell
end tell
end run
It is best not to use UI scripting here. You want to set this up as a trigger in mail.app. Your script can pull the sender email address and then programmatically add it to the first empty cell in a row. Here's a script to get you started:
using terms from application "Mail"
on perform mail action with messages theMessages for rule theRule
tell application id "com.apple.iWork.Numbers"
activate
-- can also tell Numbers to open a specific document
end tell
tell application "Mail"
repeat with eachMessage in theMessages
set fromAddress to extract address from reply to of eachMessage
tell application id "com.apple.iWork.Numbers"
tell document 1
tell the active sheet
tell table 1
tell column "E" -- change to preferred column
-- find the last empty row in this column
set r to (address of row of first cell whose value is missing value)
set value of cell r to fromAddress
set r to r + 1
end tell
end tell
end tell
end tell
end tell
end repeat
end tell
end perform mail action with messages
end using terms from
Edit: I edited the script to check for the next cell with a 'missing value' (instead of the cell value > 0) so that it can handle numbers and dates, such as:
set value of cell r to date "12/5/15"

Trying to get the contents of an email message in AppleScript without added characters

Okay, I need to add some emails to my Daylite tasks automatically based on certain criteria, so I set up a Mail.app rule and an AppleScript to accomplish this. There's only one problem: when the AppleScript gets the content of the message, it adds an 'a' at the end (and makes a beep as well, letting me know it tried some keystroke that apparently wasn't allowed).
Here's what the AppleScript looks like:
using terms from application "Mail"
on perform mail action with messages theMessages for rule theRule
tell application "Mail"
repeat with eachMessage in theMessages
try
set this_subject to subject of eachMessage
set this_body to content of eachMessage
if this_subject is "" then error
on error
set this_subject to "No subject."
end try
activate application "Daylite"
tell application "System Events"
keystroke "t" using {command down, shift down}
keystroke this_subject
keystroke tab
keystroke this_body
keystroke "s" using command down
end tell
end repeat
end tell
end perform mail action with messages
end using terms from
This results in me getting a new task in Daylite, where the task title is the email Subject, and is displayed correctly, but the attached note, which is the email's body, is not displayed correctly.
So, if I receive an email that matches my rule, and the email is:
From: Hypothetical Wife
Subject: Don't forget to take out the trash!
Body: If you forget one more time, I'm filing for a divorce.
That ends up with a task that looks like this:
☐ Don't forget to take out the trash!
If you forget one more time, I'm filing for a divorce.a
… making my hypothetical wife in this scenario sound like a barely literate Canadian. (Plus there's an system alert sound, letting me know it apparently tried to type something that's not allowed.)
If the body has multiple lines of text, it also annoyingly removes the line-breaks.
I know I could set it to:
set the clipboard to this_body
and then replace
keystroke this_body
with
keystroke "v" using command down
…but that's a really inelegant solution and I don't want to replace whatever's in my clipboard every time the rule runs.
What am I doing wrong here? I've tested this in TextEdit as well, and the same problem occurs there too, so it's not a Daylite problem. I've also tried appending "as Unicode text" or "as string" or "as «class UTF8»" to the end of the "set this_body…" line, but none of those fixed the problem either.
Please, explain it to me like I'm a complete idiot because, as a complete idiot, that's the only way I'll understand you. Thanks.
One of the basic mistakes many people make is telling an application to do things that the application does not know how to do. You should only tell an application to do things that you can find in its applescript dictionary because that's really all the application knows how to do... besides some basic general purpose applescript stuff like performing a repeat loop.
You have fallen into this trap. You are telling Mail to tell Daylight and System Events to do things because all of that code is inside the "tell application Mail" block of code. This type of error often leads to problems that are very difficult to track down.
As such, my first suggestion would be to stop telling Mail to do unnecessary things. Here's how I would write your code to separate the different application commands from each other.
using terms from application "Mail"
on perform mail action with messages theMessages for rule theRule
repeat with eachMessage in theMessages
tell application "Mail"
set this_subject to subject of eachMessage
set this_body to content of eachMessage
end tell
if this_subject is "" then set this_subject to "No subject."
activate application "Daylite"
delay 0.2
tell application "System Events"
tell process "Daylite"
keystroke "t" using {command down, shift down}
delay 0.2
keystroke this_subject
delay 0.2
keystroke tab
delay 0.2
keystroke this_body
delay 0.2
keystroke "s" using command down
end tell
end tell
end repeat
end perform mail action with messages
end using terms from
You'll also notice I added a small delay between some of your code. Sometimes the code runs more quickly than the computer interface can handle, so that too may be a source of your error. You can also try increasing the length of the delay if needed (any delay over 1 second is overkill and shouldn't be necessary).
If these changes and a longer delay don't work then a simple solution would be to check if the text ends with "a" and just remove it. Something like this between the keystroke tab and keystroke this_body lines...
if this_body ends with "a" then set this_body to text 1 thru -2 of this_body
Good luck!
EDIT: the "keystroke" process doesn't seem to like the return characters from the email. I believe that's what causing the noise... when it hits a return character it beeps. Anyway, you can try something like this. Just open a blank TextEdit document and select an email in Mail and run the code in AppleScript Editor. You can incorporate this idea in your Daylight script.
tell application "Mail"
set eachMessage to item 1 of (get selection)
set this_subject to subject of eachMessage
set this_body to content of eachMessage
end tell
set bodyList to paragraphs of this_body
activate application "TextEdit"
tell application "System Events"
tell process "TextEdit"
repeat with i from 1 to count of bodyList
keystroke (item i of bodyList)
keystroke return
end repeat
end tell
end tell

Gnus: How to archive emails according to the account they were written from? [gcc-self not working as expected]

I have two mail accounts, foo.bar#uni.edu and foo.bar#gmail.com. I would like to archive messages I send from either one in a corresponding "sent mail" folder (nnimap+foo.bar#uni.edu:Sent Items and foo.bar#gmail.com:[Google Mail]/Sent Mail).
I tried to set
(setq gnus-message-archive-group
'(("uni" "nnimap+foo.bar#uni.edu:Sent Items")
("gmail" "nnimap+foo.bar#gmail.com:[Google Mail]/Sent Mail")
))
but that does not set Gcc (new messages don't have a Gcc; any solution here?). I thus went back to (setq
gnus-message-archive-group "nnimap+foo.bar#uni.edu:Sent Items") which sets Gcc
correctly (for the main account foo.bar#uni.edu) if I open a new message in *Group* via m.
I then tried to use gcc-self via gnus-parameters to archive the sent mails correctly:
(setq gnus-parameters
`((,(rx "nnimap+foo.bar#uni.edu")
(gcc-self . "nnimap+foo.bar#uni.edu:Sent Items"))
(,(rx "nnimap+foo.bar#gmail.com")
(gcc-self . "foo.bar#gmail.com:[Google Mail]/Sent Mail"))))
The manual (http://www.gnus.org/manual/gnus_28.html) says that if gcc-self is
a string, it is simply inserted literally as Gcc header. I made the following
experience: Wherever I start a new message in *Group* via C-u m (with m, Gcc
is "nnimap+foo.bar#uni.edu:Sent Items" as mentioned before), Gcc is taken to be
the name the point was on in *Group* before m was hit. So if the point is on
nnimap+foo.bar#gmail.com:Drafts, Gcc will be Gcc:
nnimap+foo.bar#gmail.com:Drafts (instead of foo.bar#gmail.com:[Google
Mail]/Sent Mail). How can this be fixed and messages archived in the corresponding sent mail folders if written via C-u m? In other words, why are the Gcc's not set correctly?
[this is on Emacs 24.3.50.1, Gnus v5.13]
I had exactly the same issue as you. Even though I was adding in a gcc-self parameter to be "INBOX.Sent" when I sent the message it was ending up in "nnfolder+archive:sent.YYYY-MM"
My setup is that I have a default account (home) and a secondary account (work) both imap (but not Gmail, hopefully this answer still applies)
Through a lot of trial and error I managed to get it functioning as I wanted: work emails to be saved in the work sent folder, home emails to be saved in the home sent folder.
In the gnus-parameters I simply changed my gcc-self param to gcc and it worked! However, only for the secondary address.
For the default address I set gnus-message-archive-group
A cut down of my ~/.gnus file
(setq gnus-select-method
'(nnimap "home"
(nnimap-address "mail.homeaddress.com")
(nnimap-server-port 143)
(nnimap-stream starttls)
(nnimap-inbox "INBOX")
))
(setq gnus-secondary-select-methods
'((nnimap "work"
(nnimap-address "mail.workaddress.com")
(nnimap-server-port 143)
(nnimap-stream starttls)
(nnimap-inbox "INBOX"))))
(setq gnus-parameters
'(
("work"
(posting-style
(address "me#workaddress.com")
(gcc "nnimap+work:INBOX.Sent")))))
(setq gnus-message-archive-group "nnimap:INBOX.Sent")
Notice that I don't have any posting-styles for home.
I hope this helps.
Emacs Version 24.3.1, Gnus v5.13
I have encountered the same problem during my Gnus setup. I use Gmail for personal stuff and Outlook for work. My goal is to compose/reply messages using the corresponding account that I am currently working on in Gnus. Based on the suggestions from robsearles, I managed to achieve this goal using gnus-posting-styles. Here is the sample code I use.
;; Archive outgoing email in Sent folder on imap.gmail.com
(setq gnus-message-archive-method '(nnimap "imap.gmail.com")
gnus-message-archive-group "[Gmail]/Sent Mail")
;; Set return email address based on incoming email address
(setq gnus-posting-styles
`((".*"
(address "foo.bar#gmail.com")
(name "Foo Bar")
("X-Message-SMTP-Method" "smtp smtp.gmail.com 587 foo.bar#gmail.com")
)
("^nnimap[+]outlook:.*"
(address "foo.bar#outlook.com")
(name "Foo Bar")
("X-Message-SMTP-Method" "smtp smtp-mail.outlook.com 587 foo.bar#outlook.com")
(gcc "\"nnimap+outlook:Sent Items\"")
)
)
)
The gnus-message-archive-method and gnus-message-archive-group set the default archiving behavior which archives messages to my Gmail Sent folder. The gcc tag in gnus-posting-styles instructs Gnus to archive messages to my Outlook Sent folder when I am working with the Outlook account. I also get the benefit of automatically selecting the outgoing mail server depending on the email account I am working on with the X-message-SMTP-Method tag. Outlook seems to automatically archives a message to the Sent folder whenever it is sent, so I used (gcc nil) in my actual setup to avoid duplicates. You can of course change outlook to whatever mail service you are using.