Forward mail in Mail.app and adding attachment deletes existing message body?

I am writing a script for a Mail.app rule:

When I receive a message with an attachment the rule should

  1. Download the attachment
  2. Process it using do shell script
  3. Forward the original message (but not send it, just create a draft - I will manually add details to this)
  4. 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:

  1. Change focus from To to Body
  2. Select All
  3. 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:

  1. Original message didn’t have any body. The draft that resulted from forwarding just contained some metadata.
  2. Insert an attachment deleted that metadata. However cut’n’pasting the metadata somehow “reset” it, and allowed you to insert the attachment.

Would appreciate suggestions for improvements!

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?