When I receive a message with an attachment the rule should
Download the attachment
Process it using do shell script
Forward the original message (but not send it, just create a draft - I will manually add details to this)
Attach the processed file and preferably delete the original attachment.
1-3 works but 4 deletes both the existing attachment (good) as well as the message body (bad).
The code is very simple:
tell theDraft
set outputAlias to POSIX file outputPath as alias
make new attachment with properties {file name:outputAlias}
end tell
How do I attach something to a draft without deleting the existing message body?
Preferably while deleting the existing attachment. I can live with manually deleting the original attachment but I want to preserve the message body. HTML/plain text doesn’t matter.
I have solved this problem now, but it required GUI-scripting, which feels unsatisfactory. Input and feedback on how to improve this is welcome.
Here is a simplified version of the code:
tell application "Mail"
repeat with aMessage in theMessages
set fwdMsg to forward aMessage with opening window
set visible of fwdMsg to true
set draftMessages to (every outgoing message whose visible is true)
if draftMessages is not {} then
set theDraft to item 1 of draftMessages
tell application "System Events"
repeat 4 times -- Focus is on the to-field. Four tabs to get into the body field
delay 0.3
key code 48
end repeat
keystroke "a" using {command down} -- select all
delay 0.3
keystroke "x" using {command down} -- cut, placing the content of the body on the clipboard. The body only consists of the to, from, subject, date values that Mail.app itself includes when you forward a message
delay 0.3
end tell
tell theDraft
set outputAlias to POSIX file outputPath as alias
set content of theDraft to my getClipboardAsRichText()
make new attachment with properties {file name:outputAlias}
save
end tell
end if
end repeat
end tell
The main problem is that the original message doesn’t have any body, and the body of the draft that results from forward a message, i.e., From, To, Date and Subject isn’t (?) accessible programmatically, but I wanted to keep that meta-data.
The solution was to GUI script:
Change focus from To to Body
Select All
Cut
Can (1) be achieved some other way than by sending multiple tabs?
Here is another weird behaviour:
If I inserted the attachment directly after forwarding the message the body was deleted, but if I first cut the body, then paste the body (you would think you where back to the original state after these operations) and finally insert the attachment the body isn’t deleted!?!?
To sum up the complications:
Original message didn’t have any body. The draft that resulted from forwarding just contained some metadata.
Insert an attachment deleted that metadata. However cut’n’pasting the metadata somehow “reset” it, and allowed you to insert the attachment.
Not sure how others are supposed to help without seeing your script.
That said, I took a run at it. It appears to me that the problem lies in how Mail.app forwards messages.
Specifically, if you:
tell application "Mail"
set theMessage to (item 1 of (get selection))
set thefwd to forward theMessage with opening window
tell thefwd
set content to content of theMessage
end tell
end tell
you’ll see that it’s content is empty.
I take this to mean that Mail.app is doing something funky internally, kind of including the original message as ‘ghost’ content that’s not really there. When you add your attachment, the message suddenly has content and the forwarded ‘ghost’ content is cleared.
The workaround I saw was more like:
tell application "Mail"
set theMessage to (item 1 of (get selection))
set thefwd to forward theMessage with opening window
tell thefwd
set content to content of theMessage
delete every attachment
set outputAlias to choose file
tell content
make new attachment at end of attachments with properties {file name:outputAlias}
end tell
end tell
end tell
In other words, directly setting the content of the forwarded message to match that of the original message. Then you can add your attachments.
Here’s a solution as a mail-rule-selectable script. On Sequoia this belongs in ~/Library/Application Scripts/com.apple.mail
I agree with @Camelot reply and forwards are weird. Since you’re already going to have to rebuild the content this script builds a new message copying the necessary properties.
Edit: made desktop path generic
Edit 2: made generic path work
use AppleScript version "2.4"
use scripting additions
property PTTDTFAT : path to the desktop folder as text
using terms from application "Mail"
on perform mail action with messages theMessages for rule theRule
repeat with thisMessage in theMessages
tell application "Mail"
tell thisMessage
set theSender to sender
set theSubject to subject
set theContent to content
set theAttachment to item 1 of mail attachments
tell theAttachment
set attachmentName to name
end tell
end tell
set SavedAttachmentPath to PTTDTFAT & attachmentName
save theAttachment in SavedAttachmentPath as native format
--Process attachement here. Resave in the same path or update code below to your new path
set newMessageReference to make new outgoing message with properties {subject:theSubject, content:(theContent & return)}
tell newMessageReference
make new attachment with properties {file name:SavedAttachmentPath}
make new to recipient with properties {address:theSender}
end tell
end tell
end repeat
end perform mail action with messages
end using terms from
Regarding the content, the original message is empty (it just has an attachment), so the content of the forwarded message is just the metadata of the original message (which is auto generated), something like:
To: a@b.c
From: d@e.f
Date: 2025-04…
Subject: Fwd
(Note that it is quoted)
It might be that this generated content is special when it comes to inserting other/more content into the message body?
But if you reconstruct the message (also see my previous comment - the message body content is “special”) you lose “In-reply-to”, “Thread” (or whatever the mail headers are called), which means that the reconstructed message won’t be “connected” to the correct mail thread etc?