I think I've tried every avenue for faceless, scriptable email sending that ever existed. All were a bust until I found "pony," which is a RubyGem library. It has worked perfectly for me for many months now. Full documentation for the "pony" command is available online and is easy to find with a google search.
Since Ruby and RubyGems are already installed on the Mac, you just need to install the "pony" gem with this Terminal command, which will prompt for an admin password:
(The documentation says you don't need the 'sudo' part, but it only works for me if I include it.)
With that installed, below is the code I wrote to send an email from an AppleScript. I've included every option that I've ever needed, such as 'cc', 'bcc', and 'reply_to'. You can remove any that you don't need. I use googlemail via SMTP, but you can check the "pony" documentation for help with other configurations.
Take note that I'm using Ruby's "general delimited strings" capability to avoid certain quoting problems for many of the instruction strings—all the ones preceded by "%^" and followed by "^". Second, because it's Ruby, we need to convert any AS lists into Ruby arrays, thus the 'rubyizeListToArray' handler.
Stan C.
-- define email parameters
set mailSubject to "Error notification"
set mailBody to "Now is the time for all good men to come to the aid of their country."
set mailCC to ""
set mailBCC to "Stan Cleveland <
email@hidden>"
-- send me a copy set replyTo to "Stan Cleveland <
email@hidden>"
-- I get any replies set mailAuthUID to "email@hidden" -- use scripting email account credentials
set mailAuthPword to "password" -- use scripting email account credentials
-- escape quotation marks in subject and body
set mailSubject to escapeDoubleQuotes(mailSubject)
set mailBody to escapeDoubleQuotes(mailBody)
-- concatenate first portion of shell script
set cmdBase to ("ruby -rubygems -e \"gem 'pony' ; " & ¬
"require 'pony' ; Pony.mail(" & ¬
":subject => %^" & mailSubject & "^, " & ¬
":body => %^" & mailBody & "^, " & ¬
":to => " & prepEmailAddresses(mailTo) & ", " & ¬
":from => %^" & mailFrom & "^, " & ¬
":reply_to => %^" & replyTo & "^, ")
-- if used, append 'cc' and/or 'bcc' instructions
if mailCC is not in {"", {}} then
set preppedMailCC to prepEmailAddresses(mailCC)
set cmdBase to (cmdBase & ":cc => " & preppedMailCC & ", ")
end if
if mailBCC is not in {"", {}} then
set preppedMailBCC to prepEmailAddresses(mailBCC)
set cmdBase to (cmdBase & ":bcc => " & preppedMailBCC & ", ")
end if
-- complete and execute shell script
set cmdResult to do shell script (cmdBase & ¬
":charset => 'utf-8', " & ¬
":via => :smtp, :via_options => {" & ¬
":address => '" & mailSMTP & "', " & ¬
":user_name => '" & mailAuthUID & "', " & ¬
":password => '" & mailAuthPword & "', " & ¬
":authentication => :plain, " & ¬
":port => '587', " & ¬
":enable_starttls_auto => true, " & ¬
"})\"")
on escapeDoubleQuotes(theText)
set oldTIDs to AppleScript's text item delimiters
if theText contains "\\\"" then
set AppleScript's text item delimiters to ("\\\"") -- escaped backslash, escaped quote mark
set textParts to text items of theText
set AppleScript's text item delimiters to ("\"") -- escaped quote mark
set theText to textParts as text
end if
if theText contains "\"" then
set AppleScript's text item delimiters to ("\"") -- escaped quote mark
set textParts to text items of theText
set AppleScript's text item delimiters to ("\\\"") -- escaped backslash, escaped quote mark
set theText to textParts as text
end if
set AppleScript's text item delimiters to oldTIDs
return theText
end escapeDoubleQuotes
on prepEmailAddresses(addressOrAddresses)
if class of addressOrAddresses is list then
return rubyizeListToArray(addressOrAddresses)
else if class of addressOrAddresses is text then
return quoted form of addressOrAddresses
else
return ""
end if
end prepEmailAddresses
on rubyizeListToArray(aList)
set oldTIDs to AppleScript's text item delimiters
set AppleScript's text item delimiters to "^, %^"
set lst to aList as text
set AppleScript's text item delimiters to oldTIDs
return ("[%^" & lst & "^]") as string
end rubyizeListToArray