AppleScript changes to Outlook messages are not saved - macos

I am forced to use Outlook for Mac connected to corporate Exchange at work and I have pieced together a small AppleScript to alter subject lines of incoming email messages from our monitoring system. By default they are of an ungodly length and not human readable. I am attempting to fix that.
The script works, but for some strange reason everything is working great when I send test messages myself, however all changes are reverted back when the real messages from the monitoring system come in! When message arrives into my mailbox the subject is exacly how I want it, but within 3-5 seconds it reverts back to the original subject!
I do not know anything about AppleScript and have no idea where to beging troubleshooting something like this.
Would anyone please take a look and tell me if what I am attempting to do is doable?
on replaceText(find, replace, subject)
set prevTIDs to text item delimiters of AppleScript
set text item delimiters of AppleScript to find
set subject to text items of subject
set text item delimiters of AppleScript to replace
set subject to "" & subject
set text item delimiters of AppleScript to prevTIDs
return subject
end replaceText
tell application "Microsoft Outlook"
set theMessages to the current messages
end tell
repeat with theMsg in theMessages
tell application "Microsoft Outlook"
set mysubject to get the subject of theMsg
if mysubject contains "[Subscription:Spectrum CTO] SPECTRUM - " then
set mysubject to my replaceText("[Subscription:Spectrum CTO] SPECTRUM - ", "", mysubject)
set mysubject to my replaceText("Alarm Title: ", "", mysubject)
set mysubject to my replaceText("Severity: ", "", mysubject)
set mysubject to my replaceText("Model Name:", "-", mysubject)
set subject of theMsg to the mysubject as string
end if
end tell
end repeat

Since the only line that alters the message is
set subject of theMsg to the mysubject as string
it seems that it might be an issue with Exchange. Have you tried simply setting the subject of another email when it arrived?

Ok, The problem was solved by adding
delay(3)
right before
set subject of theMsg to the mysubject as string

Related

One click forward marked messages. AppleScript

I have an AppleScript whose task is to forward flagged messages to another email (in the standard Apple Mail application), but it does not work as I need. I added this script to the Automator as a service.
I have to
1) flag the message.
2) go to the services and select the "Forward marked messages" service that I need, and only then they are forwarded all at once.
My idea is to auto forward a incoming message to the assistant immediately after marked the message with a flag.
Could someone correct my AppleScript?
Or am I mistaken in introducing it into services?
Help me please!
set toAddress to "alex#example.com"
set toName to "Alex"
tell application "Mail"
repeat with _acct in imap accounts
--Look For Flagged Messages in the INBOX
set _acct_name to name of _acct
set _inbox to _acct's mailbox "INBOX"
set _msgs_to_capture to (a reference to ¬
(every message of _inbox ¬
whose flagged status is true))
repeat with _msg in _msgs_to_capture
set _fwdmsg to forward _msg with opening window
tell _fwdmsg
make new to recipient at end of ¬
to recipients with properties {name:toName, address:toAddress}
end tell
activate
send _fwdmsg
end repeat
end repeat
end tell

Applescript Mail Attachment Not Sending

The following Applescript sends an email successfully but does not attach the wav file. Can you tell me what I'm doing wrong? Thank you.
tell application "Mail"
set theSubject to "Voicemail"
set theContent to read (the POSIX path of "/private/tmp/voice.tgCrnv/BODY.txt")
set theAddress to "me#example1.com"
set theSender to "me#example2.com"
set theAttachmentFile to (POSIX file "/private/tmp/voice.tgCrnv/msg_1bb3b4f2-c6b1-4012-89c0-a19177cc6ca2.wav") as string
set msg to make new outgoing message with properties {subject:theSubject, content:theContent, visible:false, sender:theSender}
tell msg to make new to recipient at end of every to recipient with properties {address:theAddress}
tell msg to make new attachment with properties {file name:theAttachmentFile as alias}
send msg
end tell
This work for me
set theSubject to "Voicemail"
set theContent to read "/private/tmp/voice.tgCrnv/BODY.txt"
set theAddress to "me#example1.com"
set theSender to "me#example2.com"
set theAttachmentFile to "/private/tmp/voice.tgCrnv/msg_1bb3b4f2-c6b1-4012-89c0-a19177cc6ca2.wav" as POSIX file as alias
tell application "Mail"
set msg to make new outgoing message with properties ¬
{subject:theSubject, content:theContent, visible:false, sender:theSender}
tell msg
make new to recipient at end of every to recipient with properties {address:theAddress}
make new attachment at end of last character of content with properties ¬
{file name:theAttachmentFile}
end tell
delay 1
send msg
end tell
I've slightly adjusted your script that I believe will work if you first try it as it is before making any edits of your own to suit your own coding style (obviously, fill in the appropriate email addresses).
The significant functional changes are setting visible to true when declaring a new outgoing message; and targetting the content of the outgoing message in order to attach the file.
The variable declarations I moved to outwith the tell application block just for good coding practice (there's no need to tell Mail to set those variables, so don't).
And, finally, I reformatted the text of the code to what I'm more accustomed to for improved readability.
set theSubject to "Voicemail"
set theContent to read "/private/tmp/voice.tgCrnv/BODY.txt"
set theAddress to "me#example1.com"
set theSender to "me#example2.com"
set theAttachmentFile to POSIX file "/private/tmp/voice.tgCrnv/msg_1bb3b4f2-c6b1-4012-89c0-a19177cc6ca2.wav" as alias
tell application "Mail" to tell (make new outgoing message with properties ¬
{subject:theSubject, content:theContent, visible:true, sender:theSender})
make new to recipient at end of to recipients ¬
with properties {address:theAddress}
tell its content to make new attachment at after the last paragraph ¬
with properties {file name:theAttachmentFile}
send
end tell
Let me know how it goes.
FWIW: larger files need longer delays. 10mb - I know, too huge, but ... - needed upward of 8 second delay.

How do I stop AppleScript from selecting all messages in a Mail.app conversation when I only want one from the group?

Here's my itch: I want to add emails to Reminders.app as todo items. I figured that part out. My next goal was to be able to select multiple emails and have Reminders.app create todos for each email selected. I figured that part out.
The problem: When I select an email that is part of a conversation ALL messages from that conversation are added as individual reminders/todos. This part may be confusing but I'll try to be as detailed as possible in describing how I'm selecting messages. In Mail.app I'm selecting a message in the far right-side pane where all emails that part of the conversation are presented in a scrollable list. It's this area where I'm selecting a particular message. So even though I'm selecting one message from a conversation, all messages in that conversation are added to my AppleScript list variable and, subsequently, turned into reminders/todos.
If I turn off 'Organize by Conversation' in Mail.app the problem goes away. I like the cleanliness of organizing my emails by conversation so if there's a scripting solution to this problem I'd prefer that route. However, I can't think of any way to fix this so I'm hoping someone here has some thoughts.
Here's my script:
property defaultList : "Parking Lot"
on newReminder(theBody, theTitle)
tell application "Reminders"
tell list defaultList
make new reminder with properties {body:theBody, name:theTitle}
end tell
end tell
end newReminder
tell application "Mail"
set selectedMessages to {}
set selectedMessages to selection
if (count of selectedMessages) is 0 then
return "Please select a message in Mail.app and try again."
else
repeat with i from 1 to (count of selectedMessages)
tell item i of selectedMessages
set messageid to message id
set urlText to "message://" & "%3c" & messageid & "%3e"
set theSender to extract name from sender
set theSubject to subject
my newReminder((theSender & " " & urlText), theSubject)
end tell
end repeat
end if
end tell
The AppleScript property selection for the Mail application appears to ignore whether a single message from a conversation is highlighted in the preview pane (the rightmost pane in OS X Lion's layout). The selection is determined solely by which messages are selected in the message list (the middle pane). If you want to utilize selection in your AppleScript for a single message of a conversation, you'll have to select the single message from the message list,
instead of the preview pane.

Why does my AppleScript program say iTunes is playing a track when iTunes isn't actually doing so?

I'm trying to make an AppleScript that tells iTunes to play a certain track. Here's my code. I'm baffled, because when I set "theCommand" to "play Shake Up Christmas by artist Train" the script works when I right-click a test e-mail and click "Apply Rules." However, it doesn't work when I tell it to play what the e-mail tells it to play.
using terms from application "Mail"
on perform mail action with messages messageList for rule aRule
tell application "Mail"
repeat with thisMessage in messageList
try
set theCommand to content of thisMessage as string
on error errMsg
display alert errMsg
end try
end repeat
end tell
tell application "iTunes"
if theCommand contains "play" then
if theCommand is equal to "play" then
play
else
set prevTIDs to text item delimiters of AppleScript
set text item delimiters of AppleScript to "play "
set subject to text items of theCommand
set text item delimiters of AppleScript to ""
set subject to "" & subject
set AppleScript's text item delimiters to " by artist "
set delimitedList to every text item of subject
set theTrack to the first item of delimitedList
try
set theArtist to the second item of delimitedList
set artistIsDefined to true
on error
set artistIsDefined to false
end try
set AppleScript's text item delimiters to prevTIDs
if artistIsDefined is true then
try
play (every track in playlist 1 whose artist is theArtist and name is theTrack)
say "Playing " & theTrack
on error errMsg
say errMsg
end try
else
play (every track in playlist 1 whose name is theTrack)
end if
end if
else if theCommand is equal to "pause" then
pause {}
else if theCommand is equal to "stop" then
stop {}
end if
end tell
end perform mail action with messages
end using terms from
The Mac will respond to an e-mail by saying "Playing (track)," but it won't play the track. The fact that the file is on a Time Capsule shouldn't matter, as iTunes can access it. (iTunes would have shown an exclamation mark to the left of the track name if it couldn't.)
My guess is that you need to change the word "every" to "first" in this command...
play (every track in playlist 1 whose artist is theArtist and name is theTrack)
I didn't test my theory, but I think by using the word "every" you get a list of tracks from that command (even if only 1 track is in the list). And iTunes doesn't know how to play a list. iTunes can play a track. So by using "first" you will get the first track found and thus it should work. Alternatively you could get the first item of the list... play (item 1 of (every track...)).

Get message in compose window from Mail.app

I am trying to make a script that will get the contents of an email message that I'm composing in Mail, do something with the data, and then send the message. I know how to make and send a new message from scratch with AppleScript, but I can't find a way to get a message that I'm already writing. I don't care what language is used, and I would be open to trying a different email client. Thanks for your help!
Mail has huge limitations with regards to Applescript and dealing with its content area is a major one. The best bet is to use GUI scripting to tab to the content area, type cmd-C, and then work off the data in the clipboard.
Sadly from what I can see Applescript has not been improved at all in Lion.
It's actually pretty easy to do what you need.
If you want to run some kind of an inline processing (assigned to, say, a hotkey (in Mail, e.g. Cmd+D is not occupied), or "just" listed in the Services menu, accessible after selecting something), you can simply use Automator. A demo Automator script reading the current selection, making some changes (here, converting some ASCII char+number combinations to some accented characters) and, finally, returning the modified text is as follows:
on run {input, parameters}
set myText to replaceText("a1", "á", (input as text))
set myText to replaceText("e1", "é", myText)
set myText to replaceText("i1", "í", myText)
return myText
end run
on replaceText(find, replace, someText)
set prevTIDs to text item delimiters of AppleScript
set text item delimiters of AppleScript to find
set someText to text items of someText
set text item delimiters of AppleScript to replace
set someText to "" & someText
set text item delimiters of AppleScript to prevTIDs
return someText
end replaceText
Make sure you enable the "Replaces selected text", should you want to overwrite the original content with the returned one.
if you want to write an external script not invoked from the local Services menu (or via a hotkey), you'll also need to add clipboard handling. A solution similar to the above with additional clipboard copy/paste:
on replaceText(find, replace, someText)
set prevTIDs to text item delimiters of AppleScript
set text item delimiters of AppleScript to find
set someText to text items of someText
set text item delimiters of AppleScript to replace
set someText to "" & someText
set text item delimiters of AppleScript to prevTIDs
return someText
end replaceText
tell application "Mail"
activate
tell application "System Events"
tell process "Mail"
click menu item "Select All" of menu "Edit" of menu bar 1
click menu item "Copy" of menu "Edit" of menu bar 1
end tell
end tell
end tell
tell application "Mail"
set textclip to (the clipboard)
end tell
set myText to replaceText("a1", "á", textclip)
set myText to replaceText("e1", "é", myText)
set myText to replaceText("i1", "í", myText)
set the clipboard to myText
tell application "Mail"
activate
tell application "System Events"
tell process "Mail"
click menu item "Paste" of menu "Edit" of menu bar 1
end tell
end tell
end tell
Note that the latter script selects (and, then, overwrites) the entire window contents. It should be easy to work on the current selection only.
It's possible, but painful. Painful enough that I'm still trying to work out exactly how to do something similar but in Safari. I've gotten to the point where I can find the textarea, but the documentation I've found for getting the content isn't working. (Unfortunately, that's pretty much par for the course for AppleScript; every program does stuff just a little bit differently from the next program.)
EDIT: ok, have some horrible evil which hopefully can be adapted to work with Mail: http://www.ece.cmu.edu/~allbery/edit_textarea.script
This is striaghtforward if we make two reasonably weak assumptions: that the message you're working on is frontmost, and that the subject of all draft messages is unique. Then, before running the script, save the message you're working on; this will place it in the drafts mailbox. Then, since the subject of the message is the name of the window, we can easily access it; and since we can easily access the drafts mailbox, we can combine the two. This gives us:
tell application "Mail"
set msgs to messages of drafts mailbox ¬
whose subject is (name of window 1 as string)
if (count of msgs) = 1 then
-- Do whatever
else
-- Error, disambiguate, whatever
end if
end tell
It's probably possible to make the script save the frontmost window, and it wouldn't surprise me if a freshly-saved message is always the first item of the drafts mailbox, but these are left as an exercise for the reader :-)
So I came across this in 2020 and with this Apple Script it is (now?) possible (whenever its still a bit hacky since I have to use the clipboard for this):
activate application "Mail"
tell application "System Events"
tell process "Mail"
set initialClipboardContent to (the clipboard as text)
set composeWindow to (first window whose title does not contain "Inbox")
set value of attribute "AXFocused" of UI element 1 of scroll area 1 of composeWindow to true
delay 0.05
# CMD + A
key code 0 using command down
delay 0.1
# CMD + C
key code 8 using command down
delay 0.1
set message to (the clipboard as text) as string
log message
set the clipboard to initialClipboardContent
end tell
end tell
Here a proof of concept:

Resources