Send mail

I would like to get a list of mail accounts, process them in my own way, then send an email to my address with rich text and attachments using one of the accounts (theaddress).

I cannot work out how in the Mail dictionary except the following, and I know ‘content’ is of type ‘rich text’, which supposedly can contain any rich text object/attachment.

tell application "Mail"
	activate
	 tell (make new outgoing message with properties {subject:my subject, content:myrichtext})--i prefer 'visible' to remain as its default false
		make new to recipient at the end of to recipients with properties {name:myname, address:myaddress}
	end tell

end tell

I would like the rich text to come from an NSTextView using RTFDFromRange:{0,???}, and what is the length of the range to get the whole of the text?

Any help greatly appreciated! :slight_smile:

{0, textView’s textStorage()'s |length|()}

(where textView is your NSTextView)

Regards,

Thank you!

So now I have

on subemailsend_(sender)
	tell application "Mail"
		activate
		tell (make new outgoing message with properties {subject:valemailsubject, content:(valwinemailbody's RTFFromRange_({0,(valwinemailbody's textStorage()'s |length|())})) as rich text})-- or without coercion
			make new to recipient at the end of to recipients with properties {name:byname, address:myaddress}
			send
		end tell
	end tell
end subemailsend_

It works when content is a string, it just understandably doesn’t like using NSData. I’m not sure how else to do it, I could use NSText to write a temporary RTFD and then send it as an attachment, but I’d prefer the string to be honest. Perhaps cocoa has a way to send an email?

Not forgetting my last reply… I currently have this as far as plain text goes:

tell application "Mail"
	activate
	tell (make new outgoing message with properties {sender:(valwinemailfrom's titleOfSelectedItem()) as string, subject:valemailsubject, content:(valwinemailbody's |string|()) as string})
		make new to recipient at the end of to recipients with properties {name:myname, address:myaddress}
		tell me to log 1
		send
		tell me to log 2
	end tell
end tell

The email sends perfectly AFAIK but this is all the script logs:

*bangs head on table

I haven’t tried this but the NSAttributedString method initWithRTFD:documentAttributes: converts RTFD data to an attributed string (you can pass missing value for the documentAttributes parameter).

Ric

After edit: I wasn’t able to get rich text into mail directly with the above method – I’m not sure why it doesn’t work, but I don’t get anything in the body of the message. I was able to get it to work by copying the text view’s contents to the clipboard and then pasting it into the mail message with the following code. It seems like there should be a more elegant method than using GUI scripting to do the pasting, but I couldn’t find it off hand. In this example, tv is the IBOutlet for my text view, and makeMail_ is the IBAction for a button.

on makeMail_(sender)
		tv's selectAll_(me)
		tv's copy_(me) -- copies the contents of the text view to the clipboard
		tell application "Mail"
			activate
			set newMessage to make new outgoing message with properties {visible:true, subject:"Test", content:""}
			tell newMessage to make new to recipient with properties {name:"<a name>", address:"<an email address>"}
		end tell
		tell application "System Events"
			keystroke "v" using {command down} -- paste the clipboard contents into the mail message
		end tell
	end makeMail_

Ric

Thanks! I wanted it to be not visible but I guess I have no choice if I want rich text; not sure if I will.

Is there anyway to use mail’s ‘rich text’ class to create the rich text? I don’t particularly want colour or fonts, just images… it does also have an attachments class and I’ve seen scripts through googling this which tell the message to set attachments from file.

Then I’m speaking having currently not tried your script, when yours might already handle images, then again a different way which perhaps passes the body through the ‘content’ key of the mail tell would mean i can keep the message invisible.

You might have more luck with RTF than RTFD, coercing the result to rich text.

The other option is to put it on the clipboard using NSPasteboard, and then extract it using AS’s “the clipboard” – that at least dodges UI scripting.

Shane,

I tried using AS’s “the clipboard” command either as the value for the content parameter in the message creation line (posted above) or with the line “tell newMessage to set the content to the clipboard” both of which worked, but both took about 1 minute to do it after I just typed one word into my text view. The GUI scripting method did it immediately even with text and an image. Any ideas on what is going on here?

Ric

Are you using a suitable as parameter with the clipboard?

No, I didn’t. I can’t find the right format to include an “as” parameter. If I log clipboard info I get “<NSAppleEventDescriptor: ‘rtfd’>” as one of the items, but I don’t know the right syntax to use to get that data alone.

Ric

You probably want:

 as «class RTF »

Running “clipboard info” should tell you what’s available.

I did run clipboard info, but it reports it in a different format.

I tried "tell newMessage to set the content to (the clipboard as «class RTFD») but that won’t compile.
I also tried "log (the clipboard as «class RTFD») and that wouldn’t compile either

Ric

I was running it in a script editor. I’m stuck on my iPad for a while, though…

Richard,

If you’re more interested in sending attachments with some text, the following code works for a regular string, and with the visible set to false.

on makeMail_(sender)
		set theBody to tv's textStorage()'s |string|() as string
		tell application "Mail"
			set newMessage to make new outgoing message with properties {visible:false, subject:"Test7", content:theBody}
			tell newMessage
				make new to recipient with properties {name:"John Doe", address:"john.doe@gmail.com"}
				tell the content to make new attachment with properties {file name:"/Users/<your user name>/Desktop/IMG_2946.JPG"} at after the last paragraph
			end tell
			send newMessage
		end tell
	end makeMail_

Ric

Thanks shane and rdelmar, yes I had that last one up my sleeve, and looks like my best option at the moment, helpful to see it done properly. It would be great to see the rtfd done properly! :slight_smile: But looking at your great work I don’t quite understand why we need to envolve the clipboard when we are setting the content, I mean why (textview->clipboard->content) when it could just be (textview->content), would be easier to script too, I would like the use of a visible message to be plan B, whether that’s what you’re doing with the clipboard or not. I tried using ‘as rich text’ before so I’m also not sure why it needs to be as «class RTF », but anyway I’m over my head with you gurus…

Thanks,

Richard

I don’t understand either – I can’t get anything to work as the value for the content other than applescript text. Even an NSString doesn’t seem to work, it needs to be coerced to an applescript string first.

I don’t know what happens when you paste data from the clipboard – you can paste in RTF or RTFD including images, so why you can’t add those directly to the content is a mystery to me. I’m guessing that applescript does some kind of coercing of what it finds on the clipboard into something it can use.

Ric

Wait a minute! Now I’m back home and took a second look at your script, I notice that when you set the attachment you give it a location, could I take the location of each attachment in my text view and then manually reattach them to the message there? :open_mouth: I just need to know how to get the file’s location in the text view. :slight_smile:

How are you getting the files into your text view? Are the actual file contents in your text view or just a reference (the path) to the file?

It would be helpful if you could give a little more detail on what you are trying to accomplish – what are you putting in your text view? and do you want everything in the text view put into the mail message?

Ric

It is like my own help contact window for my application, I want to manage the message my self so that they can’t change the subject and ruin my master plan to use mail rules to sort them :slight_smile: I want to attach both -files they add to the textview- and -files (logs etc.) I send automatically (so long as they tick the box), these would be temporary files-.

--
-- HelpAndContactController.applescript, HelpAndContactController.scpt
-- Dialog Maker
--
-- Created by Richard Birkett on 10/7/2011.
-- Copyright 2011 Richard Birkett. All rights reserved.
--

script HelpAndContactController
	--parent
	property parent : class "NSObject"
	--app classes
	property Dialog_MakerAppDelegate : missing value
	--windows
	property winemail : missing value --window
	--IB objects
	property valwinemailsubject : missing value --label
	property valwinemailfrom : missing value --popup
	property valwinemailbody : missing value --text view
	property valwinemaildata : missing value --checkbox
	--globals
	property valemailsubject : ""	
	
	on subemailbugreport_(sender)
		set valemailsubject to "Bug Report for Dialog Maker"
		subemailcompose()
	end subemailbugreport_
	
	on subemailenhancementrequest_(sender)
		set valemailsubject to "Enhancement Request for Dialog Maker"
		subemailcompose()
	end subemailenhancementrequest_
	
	on subemailhelp_(sender)
		set valemailsubject to "Help for Dialog Maker"
		subemailcompose()
	end subemailhelp_
	
	on subemailcompose() --prepare the window for open
		valwinemailsubject's setStringValue_("Subject: " & valemailsubject)
		valwinemailbody's setString_("")
		valwinemaildata's setState_(false)
		tell application "Mail" --set the popup to mail's account list 
			activate
			set valsenderlist to every account
			set valsendernamelist to {}
			repeat with valsender in valsenderlist
				set valsendernamelist to valsendernamelist & name of valsender
			end
		end tell
		tell me to activate
		valwinemailfrom's removeAllItems()
		valwinemailfrom's addItemsWithTitles_(valsendernamelist)
		winemail's makeKeyAndOrderFront_(me)
	end subemailcompose
	
	on subemailattach_(sender)
		-- an additional aid for users to insert their own stuff
	end subemailattach_
	
	on subemailsend_(sender)
		-- not implemented: if the check box is checked then gather data, create a plist, and after sending delete it
		tell application "Mail"
			activate
			tell (make new outgoing message with properties {sender:(valwinemailfrom's titleOfSelectedItem()) as string, subject:valemailsubject, content:(valwinemailbody's |string|()) as string})
				make new to recipient at the end of to recipients with properties {name:"Richard Birkett", address:"dev.richard@me.com"}
				tell me to log 1
				send
				tell me to log 2
			end tell
		end tell
		winemail's performClose_(me)
	end subemailsend_
	
end script

Oh while waiting for a reply and doing various plist related code for the attachments I add I remembered… the OSA can be accessed by Obj-C can’t it? So could we do this more easily that way?..