tags:

views:

526

answers:

4

I'm looking for a way to create a HTML formatted email from a OS X Cocoa application.

My preferred workflow would be: The user selects a menu item and the default mail application opens with a pre-filled new email in the foreground.

I'm able to do this with mailto and -[NSWorkspace openURL] for plain text emails, but this doesn't work for HTML emails.

+3  A: 

There's no standard way to do complex interactions with arbitrary email clients. You would have to tackle each application you want to support separately, and see if it has a way to set the email format--most likely via Applescript--and then detect what the default mailto handler is and run the appropriate code. For some email clients, it may not be possible (just as some clients have no supported way to open a new email with an attachment).

smorgan
I pretty much came to the same conclusion after doing extensive searches on the Internet. I'm currently trying a Mail.app only solution via the Scripting Bridge, but so far I'm unsuccessful setting a rich text/html as the mail content. If I ever find a solution I'll add it to this question.
Markus Müller
+3  A: 

I was interested in this too, so two days of reverse engineering Safaris 'Mail Contents of This Page' feature and I got it working.

UPDATE: I improved the code and put it on GitHub

- (void)mailWebArchive:(WebArchive *)webArchive title:(NSString *)aTitle URL:(NSString *)aURL {
NSString *bundleID = @"com.apple.mail";
NSData* targetBundleID = [bundleID dataUsingEncoding:NSUTF8StringEncoding];
NSAppleEventDescriptor *targetDescriptor = nil;
NSAppleEventDescriptor *appleEvent = nil;

targetDescriptor = [NSAppleEventDescriptor descriptorWithDescriptorType:typeApplicationBundleID
                   data:targetBundleID];
appleEvent = [NSAppleEventDescriptor appleEventWithEventClass:'mail'
               eventID:'mlpg'
            targetDescriptor:targetDescriptor
              returnID:kAutoGenerateReturnID
            transactionID:kAnyTransactionID];
[appleEvent setParamDescriptor:[NSAppleEventDescriptor descriptorWithDescriptorType:'tdta'
                      data:[webArchive data]]
     forKeyword:'----'];
[appleEvent setParamDescriptor:[NSAppleEventDescriptor descriptorWithString:aTitle]
     forKeyword:'urln'];
[appleEvent setParamDescriptor:[NSAppleEventDescriptor descriptorWithString:aURL]
     forKeyword:'url '];


NSAppleEventDescriptor *replyDescriptor = nil;
NSAppleEventDescriptor *errorDescriptor = nil;
AEDesc reply = { typeNull, NULL }; 

// Send the AppleEvent
OSStatus status = AESendMessage([appleEvent aeDesc],
     &reply,
     kAEWaitReply,
     kAEDefaultTimeout);
if(status == noErr)
{
 replyDescriptor = [[[NSAppleEventDescriptor alloc] initWithAEDescNoCopy:&reply] autorelease];
 errorDescriptor = [replyDescriptor paramDescriptorForKeyword:keyErrorNumber];
 if(errorDescriptor != nil)
  status = [errorDescriptor int32Value];

 if(status != noErr)
  NSLog(@"%s error %d", _cmd, status);
}
}

This code doesn't check if Mail is running, so it's only working when Mail is already started.

catlan
Thanks Chris. What goes into the baseURL in the ATMailHelper method?
lostInTransit
A file that is used to resolve relative URLs within the document. You need this in case your html mail as images that are not downloaded from the web.
catlan
I don't have any images. What do i put in then? Noticed that without the baseURL, the WebResource is not created
lostInTransit
The path to the dictionary where the html is out, if you generate the html on fly, try just the any valid path (bundle resource or so).
catlan
A: 

Dustin Bachrach posted an elegant (but incomplete) solution here

It needs a bit of apple script, so you would have to create a different script for each mail app you want to support, but it seems like an easy thing to do.

You would also need to find the users default mail app which can be done by constructing a mailto: url then use LaunchServices LSGetApplicationForURL(): to return the default email client.

gargantaun
A: 

Does ATMailHelper still work? I try using it and the only thing that happens is Mail gets a new draft (one that only shows up when you quit) with no content at all.

Michael Dupuis