referencing a message with only "message id" in "Mail"

Hey, everyone.

I may be divulging my ignorance by asking the question, but here I go anyway…

I’m working on several scripts that ultimately will do the following…

It takes a mail message from Mail and creates several things:

  1. a task in Entourage;
  2. an applescript file;
  3. a link from the new task to that applescript.

Then, when I get to the task in my workflow, I select the link in Entourage with runs the applescript which opens the original message in “Mail”.

I’ve got most of it done, but I’m to the point where I want to open the message from the applescript. The trick is that between creating the task and opening the message back up, I’ve probably moved the message within my folder structure, so the only thing that I’m sure would still be the same is the original “message id”. However, I can’t figure out how to reference a message when I have only the “message id”.

How would I do that?

Or is there another unique, unchaning identifier that I could use to call up the message in the future.

David

OK, me again.

Anybody know how to create a link from a task in Entourage to a file? I can link it to another item in Entourage, but not a file, yet.

Thanks for any help!

David

Model: Powerbook G4
AppleScript: Applescript 1.9.3
Browser: Firefox 1.0
Operating System: Mac OS X (10.4)

Hi David,

I’m afraid I can’t help with the Entourage question, but this should get you the message from Mail if you have a current message id.

--Once you have messageID
--call searchMail handler from outside mail.app
set myMessage to searchMail(messageID)
tell application "Mail" to open myMessage

on searchMail(messageID)
	tell application "Mail"
		repeat with a in accounts
			repeat with mb in mailboxes of a
				set x to (messages whose message id is messageID) of mb
				if length of x is greater than 0 then return (item 1 of x)
			end repeat
		end repeat
		repeat with mb in mailboxes
			set x to (messages whose message id is messageID) of mb
			if length of x is greater than 0 then return (item 1 of x)
		end repeat
	end tell
end searchMail

Best wishes

John M

John, It’s a beautiful thing. Thanks so, so much. Is there a way to make sure that it doesn’t time out? I’ve got many messages to search through and sometimes the script is timing out.

David

Any takers on linking an Entourage Task to a file? Thanks all!

The only way that springs to mind, David, is to search through the messages in each mailbox until the id turns up. Depending on the number of Mail’s messages and mailboxes, it may take a while.

This somewhat unlikely and convoluted one-liner works here:

tell application "Mail" to open (first message of (first mailbox where messageID is in id of messages) whose id is messageID)

Edit:
You’d obviously need to amend that if you’re looking for a message’s message id (the unique message ID string) - rather than its id (the unique identifier of the message). Searching for the latter seems to work significantly faster here.

kai,

That looks really slick and clean. I’d love to use the simplest code possible. However, the script won’t run with just “id.” If I make it “message id,” the script runs but then times out and locks up “Mail.” Any ideas?

David

Yeah - I just edited my last message to try and avoid the confusion - but you beat me to it! :wink:

A message’s message id is a string, while its id is an integer. Searching for the id is faster - but then you might be using the message id for something else in your routine. Is that the case - or is it just used to retrieve the message in Mail at the end of the script?

Oh - something else we’d better check before we go much further (just in case we run into version issues)… Which OS are you running? (10.4.2 here.)

If the message is moved between folders the ‘id’ changes, but the ‘message id’ stays the same. (confusing terminology)

This only works for mailboxes not contained by accounts (ie not in any account’s inbox, drafts, sent messages, deleted messages or junk mailboxes).

I’m sorry my original script times out for you David. You could possibly get around this by extracting some properties of every message into an array and use some fast list manipulation.

John M

Thanks, John. That would at least explain why there are a couple of id classes. (I wasn’t moving messages around, so the difference didn’t bite me.) :wink:

It might also be prudent to put the whole shooting match inside a hefty timeout block:

on searchMail(messageID)
	with timeout of weeks seconds
		tell application "Mail"
			
			(* rest of handler *)
			
		end tell
	end timeout
end searchMail

Just as a footnote to this thread, I thought that I might have come up with an alternative (faster) method for doing this. The idea was based on an assumption that, when a file is moved in Mail, the same move is echoed in the files/folders on disk. If that were true, it should be feasible to initially locate the file on disk and store a reference to it as an alias. Then, if the file were moved to a new location in Mail, that would be reflected in Finder, which could help to ‘track’ the alias.

Sounds reasonable enough, right?

Wrong. Firstly, there appears to be no simple way of locating a message’s file on disk. (It should be possible, via a Mail document - but at present, it’s evidently not.) So an alternative method would be to establish where in Mail’s folder hierarchy the message is - to try and get a fix on the source file. However, there’s also a bug that seems to prevent getting a message’s container folder…

That’s not all.

The real sting in the tail is that the corresponding file on disk is not actually moved - but is apparently copied to the new location. The original file stays put for a while, and is eventually deleted a short time later (presumably when Mail does its housework during idle periods). That means the alias can’t be tracked - because it’s firmly stuck in the same place it started out. Bummer. :frowning:

While it’s (just) possible to get over the first couple of hurdles, this last one leaves the whole notion writhing in the dust. (D’you ever get the feeling that an app is out to get you?) :confused:

Nevertheless, I thought I’d post the script anyway, just in case it might be useful for some other purpose (even if it’s just to warn others who might imagine Mail to be in any way co-operative). :wink: Ho hum…


on getMessageFile(m)
	tell application "Mail"
		set l to {}
		repeat until m is it
			tell m as record
				set {«class want»:w, «class seld»:l's beginning} to it
				set m to (it as list)'s end
			end tell
		end repeat
		if w is account then
			set f to account (l's beginning)'s account directory & "/" & l's item 2 & ¬
				".mbox/Messages/" & l's end & ".emlx"
		else
			set f to POSIX path of (path to library folder from user domain) & ¬
				"Mail/Mailboxes/" & l's beginning & ".mbox/Messages/" & l's end & ".emlx"
		end if
	end tell
	POSIX file f as alias
end getMessageFile

(* at start of script, get the target email in your usual way. This is purely for testing... *)
tell application "Mail" to set messageFile to my getMessageFile((get selection)'s item 1)

(* continue with main part of script - possibly moving the file*)

(* then use this to reopen the message *)
tell application "Finder" to open messageFile