Lester Nelson
Lester Nelson

Reputation: 23

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.

Upvotes: 2

Views: 6191

Answers (1)

regulus6633
regulus6633

Reputation: 19030

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

Upvotes: 2

Related Questions