mail messages to word documents

Hi,

(20+ year Developer, but complete and utter Applescript newbie)

I’m trying to automate the following process:

pseudocode:

for each mail message in folder X
extract subject of email
extract content of email
create new MS Word document consisiting of content of email
save MS Word document with name 'subject of email]
move email message to folder Y
end for

I suspect that this would be relatively simple for an applescript, but Applescript is completely foreign to me. Any pointers and help is greatly appreciated.

Thx,
Mike

Mike:

I am an average scripter, but I believe I can help get you started, at least. First off, there are some free sources of Applescript basic information out there. A popular document can be found here. It is pretty basic, but will at least help you get some of the syntax issues cleared up. We have an excellent list of books and other resources right here at MacScripter, if you have any kind of budget or interest for texts. Don’t forget to cruise by our links page as well. You can also search this forum and find all kinds of threads on pertinent topics to get you started.

Anyway, I threw this together from a couple of scripts that I use for similar issues. IT HAS NOT BEEN TESTED. I know the Word section works just fine, but I haven’t ensured that the Mail part is correct, but it should be, or at least awfully close:

using terms from application "Mail"
	on perform mail action with messages The_Messages
		tell application "Mail" to repeat with This_Message in The_Messages
			set the_content to This_Message's content
			set the_subject to This_Message's subject
			my MakeWordDoc(the_content, the_subject)
		end repeat
	end perform mail action with messages
end using terms from

on MakeWordDoc(con, sub)
	set desk_path to path to desktop as Unicode text
	tell application "Microsoft Word"
		set newDoc to make new document
		insert text con at end of text object of newDoc
		save as newDoc file name (desk_path & sub) --This saves it to the desktop, the default without the path saves in the Office 2004 folder.  For another location, you need to address the path directly, and add it to the [sub] so it is directed to save there instead.
	end tell
end MakeWordDoc

To make this work, you need to save it in your Scripts folder, and use a Mail rule to call it, whenever an email arrives that fits the parameters you desire for the script. You should be able to do this part:

with a Mail rule as well.

Good luck, and I will try to test this out myself over the next couple of days just to see if it works.

Thanks Craig! The script doesn’t do exactly what I want but it’s quite close and very workable. I’ll see about refining it somewhat - have to learn more about that strange beast, AppleScript, though. :slight_smile:

Thanks again.

Mke:

Glad to hear it. Don’t be shy about posting more details concerning exactly what you need for this. We have some fabulous scripters that stop in here occasionally and you may get some incredible assistance.

Well, Craig, since you asked… :smiley:

The way this works currently is that it kicks in (via the rule) when an appropriate email hits the INBOX. And that is workable to a degree. What I’d like to be able to do is to apply the script to all messages (or selected messages) in an arbitrary mail folder.

Mike:

That’s actually pretty simple. Once you have a bunch of folders (Mail calls them mailboxes) set up to hold all your messages, you can access them via Applescript pretty easily. I am pretty sure that the messages need to be in a folder to be accessed, not the inboxes.

Anyway, below is the same handler as before that makes the Word documents, the top half simply accesses your mailboxes, lets you choose one, and then processes every message contained therein. You should consider using Smart Mailboxes in Mail to sort all your messages first, then run this.

You will see a line in the top half that will delete every message in the chosen mailbox, after the loop has processed all of them. I was not sure if you wanted to do that, so it is inactivated by the two dashes.

The Word handler also continues to save every document to your desktop; I am sure you don’t want that, so let me know if you need any help putting the documents where you want them.

tell application "Mail"
	set m_boxes to the name of every mailbox
	set this_box to choose from list m_boxes
	repeat with a_mess in (every message in mailbox (item 1 of this_box))
		my MakeWordDoc((a_mess's content), (a_mess's subject))
	end repeat
	--delete every message in mailbox (item 1 of this_box)
end tell

on MakeWordDoc(con, sub)
	set desk_path to path to desktop as Unicode text
	tell application "Microsoft Word"
		set newDoc to make new document
		insert text con at end of text object of newDoc
		save as newDoc file name (desk_path & sub)
	end tell
end MakeWordDoc

I hope this helps,

Hi Craig,

The latest version doesn’t seem to work the way you think it does. :slight_smile:

I think it has something to do with the “(every message in mailbox (item 1 of this_box))” and the commented out ‘delete message’ functionality. My guess is that this would work if the ‘delete’ functionality were retained (but this is something I don’t want to do).

Here’s what I see when I run this script:

(I have 4 messages in the test mailbox)

  1. It presents me with a list of mailboxes (expected)
  2. I select the test mailbox.
  3. The first word doc is created and saved to the desktop (expected)
  4. A second word doc is created, but not saved.

So, I only get the first message saved as a word doc.

Mike:

I found a few issues. Dang. Ok, here they are:

  1. Word freaks when it encounters a slash (/) in the Mail subject and will not continue on with the save portion of the script. I have not found any other special characters it does not like, but that may be enough, depending on what your subjects are in your box.

  2. Word is a little slow. That is easily fixed with the delay I put in after the handler loop, see script below. I also put in a [close every document] command to clean it up a bit.

  3. I cannot seem to see the Smart Mailboxes when I run the script on my system. That may be a non-issue, since I just created one immediately before running the script as a quick check. It may be that if I quit Mail and restart, it will see the Smart Box.

  4. The script also quits whenever it encounters a document with the same name as one it has already saved.

I changed a few other things around in the script, like instead of just filling up your desktop, it saves to a folder entitled “Mail.” If you like it, you need to make the folder before you run it again.

The main issue, I believe, is in the subject section. You may need to reconsider using the full subject line as the name of the documents, or we may need to figure out a way to filter each one first for both the slash (/) characters, and whether or not a document already exists with that name.

Here is the revised script:

set desk_path to ((path to desktop as Unicode text) & "Mail:")
global desk_path
tell application "Mail"
	set m_boxes to the name of every mailbox
	set this_box to choose from list m_boxes
	repeat with a_mess in (every message in mailbox (item 1 of this_box))
		my MakeWordDoc((a_mess's content), (a_mess's subject))
	end repeat
	--delete every message in mailbox (item 1 of this_box)
end tell

on MakeWordDoc(con, sub)
	set file_nm to (desk_path & sub)
	tell application "Microsoft Word"
		set newDoc to make new document
		insert text con at end of text object of newDoc
		save as newDoc file name file_nm
		close every document
	end tell
	delay 5
end MakeWordDoc

Take a look at your subjects of your messages, and let me know which of these issues seems to be the biggest deal, then let’s decide how to proceed.

Hi Craig,

We seem to have regressed further. :slight_smile:

I’ve created a ‘Mail’ folder on my Desktop (and in $HOME just in case). My test mail folder is called ‘DJTest’. I have 3 emails in that folder, and the only non-alpha characters in the subjects are colons and commas (i.e. $SUBJECT = “Fw: The Truth About Men,” ).

When I run the new script, I select the mailbox, and one Word doc is created, but not saved (it is still called “DocumentN”). No further processing happens. I tried commenting out the ‘close every document’ line but that didn’t change anything. Hmmm.

Not that it should make any difference, but I’m on Tiger and fully up to date with all updates.

[Edit: oh, and Office 2004, fully updated as well]

Oh, and I really appreciate all of your help in this matter. :slight_smile:

Mike:

Jacques is correct, and I should have seen that myself, sorry. Both the slash and colon characters are important in OS X for folders and files, it is not suprising that Word is having fits over them. Here is a quick fix for that, at least. It works on my system, but only tested on a folder with 3 files, none of which have the same string in the subject line. I am still unsure how to deal with that eventuality exactly. I have some ideas, but may not be able to work with them for a day or two.

I have also confirmed that this script will NOT recognize Smart Folders created in Mail. That is upsetting, I believe it must be a bug, since you can see them and script them in iTunes and iPhoto.

Play with this for a bit, and please report:

set desk_path to ((path to desktop as Unicode text) & "Mail:")
global desk_path
tell application "Mail"
	set m_boxes to the name of every mailbox
	set this_box to choose from list m_boxes
	repeat with a_mess in (every message in mailbox (item 1 of this_box))
		my MakeWordDoc((a_mess's content), (my TestFixSubject((a_mess's subject))))
	end repeat
	--delete every message in mailbox (item 1 of this_box)
end tell

on MakeWordDoc(con, sub)
	set file_nm to (desk_path & sub)
	tell application "Microsoft Word"
		set newDoc to make new document
		insert text con at end of text object of newDoc
		save as newDoc file name file_nm
		close every document
	end tell
	delay 5
end MakeWordDoc
-------------------------------------------------
on TestFixSubject(str)
	set fixed_string to {}
	set bad_char to {":", "/"}
	repeat with c from 1 to (count every character in str)
		if bad_char contains (character c of str) then
			set end of fixed_string to "-"
		else
			set end of fixed_string to (character c of str)
		end if
	end repeat
	fixed_string as string
end TestFixSubject

Sorry for the late report - not enough round tuits.

Craig, this is working very well for the purpose my client (i.e. wife) is using it for. Thanks very much for your time!

That’s great, Mike, glad to hear it. I am curious if your wife has had any problems with Word trying to save a file with the same name. You know how sometimes people can email back and forth replies, and the subject never changes. That is really the only danger I see with this script. I would hate to see her lose something important if it was overwritten.

My first idea in that vein is to make yet another handler that would test to see if a document by that name already exists, and if so, simply append the next email content to the end of the document. Of course, if there is no problem, there is no need to fix anything.

Hi Craig,

No, that won’t be a problem. The workflow is such that these are incoming emails only, and the subject lines are guaranteed to be unique, and there are no replies, forwards, etc. Thanks again for your help. Much appreciated!

At some point I’ll have to dig in and learn a bit of Applescript, but I don’t have enough round tuits at the moment…

Hi Craig

I am an even newer newbie, in fact to the whole Mac enviroment. I have run your latest script and it works just fine but I am trying to figure out two things.

The first is how to deal with emails with the same subject as that happens a lot as you said in one of your posts.

The second is where the docs are stored. In my case I want to first check to see if the folder I want is in Documents and if not create it.

Appreciate I am asking very basic questions which may well be out of the province of this forum if so I apologise.

Peter

Peter:

Yeah, I have been thinking about that. I think probably the best solution would be to append the content of the next message to already present content. I have not had time to put something together, and the next two days are pretty hectic for me, but I may be able to get to it if someone else doesn’t come up with something first.

Currently as written, it is supposed to be writing the documents to a folder on the desktop entitled “Mail.” It could very, very easily be altered to write somewhere else. For instance, if you want it in the Documents folder, replace the first line with this line:

set desk_path to ((path to documents folder as Unicode text) & "Mail:")

That is precisely what the forum exists for; so never apologize, just keep trying and learning. A great place to start is a free download book that covers the basics of Applescript. We have a nice books page with some various texts if you want some good reading. This book and this one are my two favorites for ultra beginner information. We also have a Links page that may have sources to help.

Peter:

This modification of my script will append to a file that already exists of the same name in the Mail folder on the Desktop:

set desk_path to ((path to desktop as Unicode text) & "Mail:")
global desk_path
tell application "Mail"
	set m_boxes to the name of every mailbox
	set this_box to choose from list m_boxes
	repeat with a_mess in (every message in mailbox (item 1 of this_box))
		my MakeWordDoc((a_mess's content), (my TestFixSubject((a_mess's subject))))
	end repeat
	--delete every message in mailbox (item 1 of this_box)
end tell

on MakeWordDoc(con, sub)
	set file_nm to (desk_path & sub)
	tell application "Microsoft Word"
		try
			set newDoc to open file name file_nm
			insert text "

" at end of text object of newDoc
		on error
			set newDoc to make new document
		end try
		insert text con at end of text object of newDoc
		save as newDoc file name file_nm
		close every document
	end tell
	delay 5
end MakeWordDoc
-------------------------------------------------
on TestFixSubject(str)
	set fixed_string to {}
	set bad_char to {":", "/"}
	repeat with c from 1 to (count every character in str)
		if bad_char contains (character c of str) then
			set end of fixed_string to "-"
		else
			set end of fixed_string to (character c of str)
		end if
	end repeat
	fixed_string as string
end TestFixSubject

Give it a try and let me know if have any questions or problems.

Craig

Have been traveliing for the last couple of days will try tomorrow anf get back to you in the mantime thanks a lot for all the help.

Peter

Hi Craig

My couple of days proved to be forever after all your help I apologise for that. I only got round to testing the script today and ran into a probelm. The scrip stops at the line

save as newDoc file name file_nm

with the message

Microsoft word got an error: document “document1” doesn’t understand the message.

Trying to understand the script I assume that file_nm is desk_path & sub I do not understand the sub (is it short for subject) so I inserted a display dialog file_nm before the line it stops at to see the name of the file which turned out to be

Macintosh HD:Users:petermitchell:desktop:Mail:Re Josiah

The last bit the suibject of the first email in the Test box. I assume that it is something to do with the colon’s in the name. It looks as though TestFixSubject is designed to replace offending charcaters like colon’s but I cannot see where the result is passed to file_nm.

Can you please help a dummy again.http::frowning:

Peter

Peter:

I am sorry, but I cannot get an error when I run the script, no matter what I try. The only problem I have is when I execute the script before Word has been started up. I then have to go to the Project Gallery screen and click on Cancel, so that the script runs unencumbered from there. We need to figure out why your version of the script is dysfunctional. Here are the best possiblities:

  1. Make sure you have a folder on your desktop entitled ‘Mail’

  2. Try executing the script while Word is already running, and has no documents open.

  3. Be sure you have not altered the script (yet).

To answer your questions about the handlers, look at the repeating line in the Mail tell. That calls the MakeWordDoc handler, sending it two items. The first item is the content of the message, and the second item is the result of the TestFixSubject handler, which examines the subject of the message for offending characters. Although probably not a flawless script, it is pretty clean and tight, and works well for me.

If you are still having difficulties, please email me some screenshots and we will figure this sucker out.

Hi Craig

I did not read the thread properly, I apologise, what I had failed to do is create the Folder “Mail” on the desktop. I did that ran the script and it worked with one exception. I duplicated a message in my test folder because as you know emails often have the same subject and is a matter you discussed in the thread. However it would appear it simple ovewrites the existing folder .

If I could impose further there are 2 other matters I would appreciate help with. One is to insert the date of the message as well the content into the Word document. The other is not to put them into a desktop folder but into a folder in Documents which inm ost cases would have the same name but if it did not exist to be able to create one in that location.

I wrote the following to try and open existing folders in documents but all I get is the route basic structure to select from it does also open “Document”.

tell application “Finder”

set the target_folder to folder "Documents" of home
open folder "Documents" of home
set F_Folder to the name of every folder
set this_folder to choose from list F_Folder

end tell

I tried adding

activate folder “documents” of home

but that did not stop the script but neither did it help I am missing something. Mind you as this was a step to trying to sort out my problem of where I wanted to put the email messages I know I have a long way to go.

If you can help it will be greatly appreciated.

thanks

Peter