Efficiently Delete Emails

I’m trying to delete a large number of messages from Mail.app using AppleScript. I’ve been able to identify the messages and get them into a list, but I’m having trouble deleting them efficiently. Right now, I’m looping through the list as follows:


tell application "Mail"
	 repeat with msg in toDelete --This is the list of messages.
	 	 delete msg --or: move msg to mailbox "Trash"
	 end repeat
end tell

This works perfectly (whether I delete or merely move to Trash), but it takes about 0.6s per message—fast enough if I’m deleting 10-20 messages, but not so much if I’m deleting 10,000-20,000.

I’ve read that AppleScript should be able to move a list of messages all at once, but I can’t seem to get it to work. Any ideas?

Model: MacBook Pro 16,1
AppleScript: 2.7
Browser: Safari 605.1.15
Operating System: macOS 11.2.3

Hi. Putting messages in a variabilized list dereferences them and necessitates looping, and iterating through 20K items takes however long it takes. You could use a whose clause—which has its own time overhead to filter the items—or just specify by range to affect multiples. This assumes the account is the only or the first:

tell application "Mail" to delete (account 1's mailbox "INBOX"'s messages whose subject contains "on sale!")

–or

tell application "Mail" to delete (account 1's mailbox "INBOX"'s messages 1 thru 20)

Edited for typo

Thanks, Fredrik. I also love Smart Mailboxes, but it never occurred to me to use them in this way. Is there a way to create a smart mailbox that would show all but one of every set of duplicates?

Thanks!

Thanks, Marc. I know I saw someone saying it was possible to delete a list en masse, but perhaps that person was mistaken. I appreciate your feedback!

It will not be possible to create a useful smart mailbox to display only originals.

It is much easier to let the script mark the duplicates with some colored flag. Then you can see with your own eyes in the message viewers which messages are flagged and delete them at your discretion. Most duplicates are usually found in the “Archive” mailbox.

The following script marks duplicates in Green. Then, you create manually smart mailbox with condition “Message has flag” , where you can select all its contents and delete at once, or one by one.


set {IDs, Duplicates} to {{}, 0}

tell application "Mail"
	repeat with anAccount in (accounts)
		repeat with aMailbox in (mailboxes of anAccount)
			try
				set aMessages to messages of aMailbox
				repeat with aMessage in aMessages
					set aMessageID to id of aMessage
					if (IDs contains aMessageID) then
						set flag index of aMessage to 3 -- Green color
						set Duplicates to Duplicates + 1
					else
						set end of IDs to aMessageID
					end if
				end repeat
			end try
		end repeat
	end repeat
	
end tell

display dialog "----   " & Duplicates & "  Duplicate Messages Flagged  with Green   ----"

Oooh! I like that! Thanks for the awesome idea!