Mail.app script works in Script Ed, but not as Mail Rule

Here’s a Mail Rule I wrote to do the following:

  1. Check all incoming messages for attachments
  2. For every new message with attachments, create a new folder named
    for the message’s subject and date. Save the attachments in the
    folder.
  3. Save the message’s body text in the same folder, as a .txt file.
  4. Send an outgoing email reporting the name(s) and file size(s) of
    the saved attachments.
  5. Open the Finder window(s) of the newly made folder(s).

It all works perfectly when run from the Script Editor. But when run as a
Mail Rule, it only does steps 1 and 2. If anyone can tell me how to
fix it, I will mail you a can of soup!

I know this script doesn’t have a real nifty structure - I would also appreciate any tips for general streamlining.

NOTE: It helps to set Mail’s prefs to always display messages as plain text,
not HTML. This requires a change to the plist file which is in the
intro comments.

(*Mail attachment save script by Luke Jaeger [url=http://www.trickfilm.org]www.trickfilm.org[/url]

This script will mine a list of Mail messages for attachments and save them to a destination you choose. 
The script creates a subfolder for each message with attachments, named with the subject of the message and its date sent. All 
attachments are saved with their original names. Messages without attachments are ignored.

After running, the script will send a mail message detailing what was saved.

The script is ready to use as a rule action in Mail - just fill in the specifics of your destination folder and recipient.

I wrote this script to deal with large art files sent to me via Mail. Hope you find it useful!

NOTE: Saving message text as .txt file works best if you set Mail to always display plain text. 
Here's how: in Terminal, paste this text -->     defaults write com.apple.mail PreferPlainText -bool TRUE

*)


--comment the first two lines ("using terms." and "on perform.") and their accompanying "end" statements when testing. Uncomment them to use this script as a Mail rule function.

using terms from application "Mail"
	on perform mail action with messages theMessages for rule UploadEm
		tell application "Mail"
			--comment the following line when running this script as a Mail.app rule function - uncomment it for testing
			
			--set theMessages to selection
			
			set theGoodName to ""
			set theFileList to ""
			set theFolderList to {}
			set theTextFileName to ""
			set theTextFileContents to ""
			
			tell application "Finder"
				mount volume "afp://myserver" as user name "username" with password "password"
				set theParentFolder to folder "Folder" of disk "Server Volume"
			end tell
			
			
			
			
			repeat with thisMessage in theMessages
				
				--does the message have attachments? if not, then skip it
				if (every mail attachment of thisMessage) ≠ {} then
					
					--make a subfolder for each message, named by subject & date sent
					set theBadName to (subject of thisMessage) & " | " & ((date sent of thisMessage) as string)
					
					
					--delete colons from subfolder name so Finder doesn't choke on them!
					set myChars to every character of theBadName
					
					repeat with i from 1 to (count of myChars)
						if item i of myChars ≠ ":" then
							set theGoodName to theGoodName & item i of myChars
						else
							set theGoodName to theGoodName & "."
						end if
					end repeat
					
					--does subfolder already exist? If not, create it
					
					tell application "Finder"
						if (exists folder theGoodName of theParentFolder) then
							
							set theSubFolder to ((theParentFolder as string) & (theGoodName as string)) as alias
						else
							set theSubFolder to (make new folder at theParentFolder with properties {name:theGoodName})
						end if
						
					end tell
					
					--save the attachment(s) to the subfolder
					set theAttachments to (every mail attachment of thisMessage)
					repeat with thisAttachment in theAttachments
						set thePath to (theSubFolder as string) & (name of thisAttachment)
						
						
						--if same named file already exists in subfolder, skip it and display error message	
						--otherwise, save it and get its size		
						
						try
							save thisAttachment in thePath
							
							if file size of thisAttachment > 1000000 then
								set mySize to (((round ((file size of thisAttachment) / 10240)) / 100) as string) & " MB"
							else
								set mySize to (((round (file size of thisAttachment) / 1024) + 4) as string) & " KB"
							end if
							set theFileList to theFileList & return & (name of thisAttachment) & tab & tab & (mySize)
						on error
							display dialog "Could not save " & (name of thisAttachment) & " to " & thePath & " because of an error (probably because a file with that name already exists)."
						end try
						
						
						
					end repeat
					
					--build a list of newly created folders for Finder to open at the end
					set theFolderList to theFolderList & (theSubFolder as alias)
					
					--save the message text as a .txt file in the subfolder
					set theTextFileName to "Message_" & (id of thisMessage as string) & ".txt"
					set theTextFileContents to content of thisMessage
					
					tell application "Finder"
						set theTextFile to (make new file at theSubFolder with properties {name:theTextFileName}) as alias
						open for access theTextFile with write permission
						write theTextFileContents to theTextFile
						close access theTextFile
					end tell
					
					set read status of thisMessage to true
					
					--make a new message to notify art department, if anything was uploaded
					if theFileList ≠ "" then
						tell (make new outgoing message with properties {subject:"Files Received - " & (subject of thisMessage), content:"File(s) for " & (subject of thisMessage) & " were uploaded on " & (current date) & "." & return & return & "Name" & tab & tab & "Size" & return & theFileList & return})
							make new to recipient at end of to recipients with properties {address:"somebody@somewhere.com"}
							send
						end tell
					end if
				end if
				
			end repeat
			
			--open the newly created folders in Finder
			
			tell application "Finder"
				activate
				open theFolderList
			end tell
		end tell
		
	end perform mail action with messages
end using terms from

Model: Intel iMac
AppleScript: 1.10.7
Browser: Firefox 2.0.0.7
Operating System: Mac OS X (10.4)

misterfriendly,

I haven’t gotten to test yet but…

One major flaw of mail scripting is that you can’t have any user interaction So Where you are displaying a dialog I would suggest writing it to a log instead. Also when you make the new message make sure it’s visible is false

I let you know if I find something

mm

UPDATE: I changed a few things around in the script (see below).

It now works fine whenever run from Script Editor (as it did before), and it works fine as a Mail rule … but it only works ONCE (!) after I re-connect to it in the Mail prefs. Then it seems to revert to working halfway (uploading the attachment files, but not saving the message text to a file or sending email notification that the script ran). When I re-select the script in the Mail prefs, it works again, once. Etc.

Is some variable not being flushed from one run to the next? How to trace and fix this?

Thanks everybody.

(*Mail attachment save script by Luke Jaeger [url=http://www.trickfilm.org]www.trickfilm.org[/url]

This script will mine a list of Mail messages for attachments and save them to a destination you choose. 
The script creates a subfolder for each message with attachments, named with the subject of the message and its date sent. All 
attachments are saved with their original names. Messages without attachments are ignored.

After running, the script will send a mail message detailing what was saved.

The script is ready to use as a rule action in Mail - just fill in the specifics of your destination folder and recipient.

I wrote this script to deal with large art files sent to me via Mail. Hope you find it useful!

NOTE: Saving message text as .txt file works best if you set Mail to always display plain text. 
Here's how: in Terminal, paste this text -->     defaults write com.apple.mail PreferPlainText -bool TRUE

*)


--comment the first two lines ("using terms." and "on perform.") and their accompanying "end" statements when testing. Uncomment them to use this script as a Mail rule function.

using terms from application "Mail"
	on perform mail action with messages theMessages for rule UploadEm
		set theGoodName to ""
		set theFileList to ""
		set theFolderList to {}
		set theTextFileName to ""
		set theTextFileContents to ""
		
		tell application "Mail"
			--comment the following line when running this script as a Mail.app rule function - uncomment it for testing
			
			--	set theMessages to selection
			tell application "Finder"
				mount volume "afp://myservername" as user name "user" with password "password"
				set theParentFolder to folder "some folder" of disk "Server Volume"
			end tell
			
			
			
			
			repeat with thisMessage in theMessages
				
				--does the message have attachments? if not, then skip it
				if (every mail attachment of thisMessage) ≠ {} then
					
					--make a subfolder for each message, named by subject & date sent
					set theBadName to (subject of thisMessage) & " | " & ((date sent of thisMessage) as string)
					
					
					--delete colons from subfolder name so Finder doesn't choke on them!
					set myChars to every character of theBadName
					
					repeat with i from 1 to (count of myChars)
						if item i of myChars ≠ ":" then
							set theGoodName to theGoodName & item i of myChars
						else
							set theGoodName to theGoodName & "."
						end if
					end repeat
					
					--does subfolder already exist? If not, create it
					
					tell application "Finder"
						if (exists folder theGoodName of theParentFolder) then
							
							set theSubFolder to ((theParentFolder as string) & (theGoodName as string)) as alias
						else
							set theSubFolder to (make new folder at theParentFolder with properties {name:theGoodName})
						end if
						
					end tell
					
					--save the attachment(s) to the subfolder
					set theAttachments to (every mail attachment of thisMessage)
					repeat with thisAttachment in theAttachments
						set thePath to (theSubFolder as string) & (name of thisAttachment)
						
						
						--if same named file already exists in subfolder, skip it and display error message	
						--otherwise, save it and get its size		
						
						--try
						save thisAttachment in thePath
						-- calculate attachment sizes for the notification message
						if file size of thisAttachment > 1000000 then
							set mySize to (((round ((file size of thisAttachment) / 10240)) / 100) as string) & " MB"
						else
							set mySize to (((round (file size of thisAttachment) / 1024) + 4) as string) & " KB"
						end if
						set theFileList to theFileList & return & (name of thisAttachment) & tab & tab & (mySize)
						--	on error
						--display dialog "Could not save " & (name of thisAttachment) & " to " & thePath & " because of an error (probably because a file with that name already exists."
						--	end try
					end repeat
					--try
					--build a list of newly created folders for Finder to open at the end
					set theFolderList to theFolderList & (theSubFolder as alias)
					
					--save the message text as a .txt file in the subfolder
					set theTextFileName to "Message_" & (id of thisMessage as string) & ".txt"
					set theTextFileContents to content of thisMessage
					--	on error e number n
					--		ErrorLogger(e, n)
					--	end try
					tell application "Finder"
						set theTextFile to (make new file at theSubFolder with properties {name:theTextFileName}) as alias
						open for access theTextFile with write permission
						write theTextFileContents to theTextFile
						close access theTextFile
					end tell
					
					set read status of thisMessage to true
					
					--make a new message to notify art department, if anything was uploaded
					if theFileList ≠ "" then
						tell (make new outgoing message with properties {subject:"Files Received - " & (subject of thisMessage), content:"File(s) for " & (subject of thisMessage) & " were uploaded on " & (current date) & "." & return & return & "Name" & tab & tab & "Size" & return & theFileList & return})
							make new to recipient at end of to recipients with properties {address:"somebody@somewhere.com"}
							send
						end tell
						set theFileList to ""
					end if
				end if
				
			end repeat
			
			--open the newly created folders in Finder
			
			tell application "Finder"
				
				open alias theFolderList
			end tell
		end tell
		
	end perform mail action with messages
end using terms from

Model: Intel iMac
AppleScript: 1.10.7
Browser: Firefox 2.0.0.7
Operating System: Mac OS X (10.4)