我正在尝试通过 Mail.app 从 Cocoa 应用程序发送 html 电子邮件。我想在 Mail.app 中打开新邮件,包括主题、收件人并添加带有链接和其他内容的 HTML 正文。但是找不到这样做的方法。 我已经尝试过 Scripting Bridge,但是 MailOutgoingMessage 类没有内容类型,我可以在纯文本中添加内容。
试过 AppleScript,像这样:
set htmlContent to read "/Path/index.html"
set recipientList to {"[email protected]"}
tell application "Mail"
set newMessage to make new outgoing message with properties {subject:"qwerty", visible:true}
tell newMessage
make new to recipient at end of to recipients with properties {address:"[email protected]"}
set html content to htmlContent
--send
end tell
end tell
此代码使用 html 发送电子邮件,仅当我更改 --send 为发送时。但我需要稍后发送信件,在用户进行一些更改后。
重述问题:使用 AppleScript 创建包含 HTML 内容的消息以进行 interactive 编辑 不起作用(从 OS X 10.9.2 开始):新消息表单带有 empty 正文.
这应该被认为是一个bug,我鼓励大家在 http://bugreport.apple.com 上让 Apple 知道 - 警告:
html content
message
类属性是 not 在 中定义Mail.sdef
, Mail.app
的 AppleScript 字典,所以官方可能不支持分配 HTML。
有一个解决方法,但它并不漂亮:
稳健地实施这一点具有挑战性,因为需要多种解决方法。不过,下面的代码尽了最大的努力:
注意:由于代码使用 GUI 脚本,因此必须为运行此代码的应用程序启用辅助设备访问(通过
System Preferences > Security & Privacy > Accessibility
)(例如,AppleScript Editor
,或者,如果通过osascript
,Terminal.app
) .
# Example values; use `read someFile` to read HTML from a file.
set htmlContent to "<html><body><h1>Hello,</h1><p>world.</p></body></html>"
set recipientList to {"[email protected]", "[email protected]"}
set msgSubject to "qwerty"
tell application "Mail"
# Create the message *invisibly*, and assign subject text
# as well as the HTML content.
set newMessage to make new outgoing message with properties ¬
{visible:false, subject:msgSubject, html content:htmlContent}
# Add recipients.
# !! Given the workaround below, this is currently pointless.
tell newMessage
repeat with toRcpt in recipientList
make new to recipient at end of to recipients with properties {address:toRcpt}
end repeat
end tell
# Save the current number of drafts messages.
set draftCountBefore to count messages of drafts mailbox
# !! Save the new message as a *draft* - this is necessary
# for the HTML content to actually appear in the message
# body when we open the message interactively later.
save newMessage
# !! Sadly, it takes a little while for the new message
# !! to appear in the drafts mailbox, so we must WAIT.
set newMessageAsDraft to missing value
repeat with i from 1 to 30 # give up after n * 0.1 secs.
set draftCountNow to (count messages of drafts mailbox)
if draftCountNow > draftCountBefore then
set newMessageAsDraft to message 1 of drafts mailbox
exit repeat
end if
delay 0.1 # sleep a little
end repeat
# Abort, if the draft never appeared.
if newMessageAsDraft is missing value then error "New message failed to appear in the drafts mailbox within the timeout period."
# Open the new message as a *draft* message - this ensures that
# the HTML content is displayed and editable in the message body.
# !! The ONLY solution I found is to use `redirect`, which, unfortunately,
# !! *wipes out the recipients*.
# !! It does, however, ensure that the draft is deleted once the message is sent.
redirect newMessageAsDraft with opening window
# Activate Mail.app and thus the draft message's window.
activate
# !! Since the recipients have been wiped out, we need to
# !! add them again - unfortunately, the only way we can do that is to
# !! *GUI scripting* - simulating invocation of a menu command or
# !! sending keystrokes.
tell application "System Events"
# We must make sure that the target window is active before
# we can perform GUI scripting on it.
set newMessageWindow to missing value
repeat with i from 1 to 30 # give up after n * 0.1 secs.
tell (first window of (first process whose frontmost is true) whose subrole is not "AXFloatingWindow")
if name is msgSubject then
set newMessageWindow to it
exit repeat
end if
end tell
delay 0.1 # sleep a little
end repeat
if newMessageWindow is missing value then error "New message failed to become the active window within the timeout period."
# Turn the list of recipients into comma-delimited *string* for pasting into the To field.
set {orgTIDs, AppleScript's text item delimiters} to {AppleScript's text item delimiters, {","}}
set recipientListString to (recipientList as text)
set AppleScript's text item delimiters to orgTIDs
# Save the current clipboard content.
set prevClipboardContents to the clipboard
# Cursor is in the "To:" field, so use GUI scripting to send the Edit > Paste command now.
# NOTE: Access for assistive devices must be enabled via System Preferences > Security & Privacy > Accessibility.
set the clipboard to recipientListString
my pasteFromClipboard("")
# Restore the previous clipboard content.
# !! We mustn't do this instantly, as our temporary content may not have
# !! finished pasting yet. It would be non-trivial to determine
# !! when pasting has finished (examining `count of to recipients` doesn't work),
# !! so we take our chances with a fixed, small delay.
delay 0.1
set the clipboard to prevClipboardContents
# Place the cursor in the message *body*.
# !! This works as of Mail.app on OS X 10.9.2, but may break in the future.
try
tell newMessageWindow
tell UI element 1 of scroll area 1
set value of attribute "AXFocused" to true
end tell
end tell
end try
end tell
end tell
(*
Pastes form the clipboard into the active window of the specified application (process) using GUI scripting
rather than keyboard shortcuts so as to avoid conflicts with keyboard shortcuts used to invoke this handler.
Specify "" or `missing value` to paste into the currently active (frontmost) application.
The target process may be specified by either name or as a process object.
CAVEAT: While this subroutine IS portable across *UI languages*, it does make an assumption that will hopefully hold for
all applications: that the "Edit" menu is the *4th* menu from the left (Apple menu, app menu, File, Edit).
Examples:
my pasteFromClipboard("") # paste into frontmost app
my pasteFromClipboard("TextEdit")
*)
on pasteFromClipboard(targetProcess)
tell application "System Events"
if targetProcess is missing value or targetProcess = "" then
set targetProcess to first process whose frontmost is true
else
if class of targetProcess is text then
set targetProcess to process targetProcess
end if
-- Activate the application (make it frontmost), otherwise pasting will not work.
set frontmost of targetProcess to true
end if
tell menu 1 of menu bar item 4 of menu bar 1 of targetProcess
-- Find the menu item whose keyboard shortcut is Cmd-V
set miPaste to first menu item whose value of attribute "AXMenuItemCmdChar" is "V" and value of attribute "AXMenuItemCmdModifiers" is 0
click miPaste
end tell
end tell
end pasteFromClipboard
不清楚你在找什么,但我会尽力提供一些帮助。
如果您留下
send
评论,那么消息应该已经在Mail.app中打开,等待进一步编辑和发送。
通过添加行
save newMessage
,它将被保存到草稿文件夹中。用户可以随时打开它并继续编辑。如果你真的想从你的申请中发送草稿,使用:
set sendMessage to first message of drafts mailbox
send sendMessage
祝你好运!
我没有看到您需要在发送前编辑消息,所以我之前的回答是错误的。这次应该没错了
基本上
代码如下:
set textSubject to "HTML Test"
set toAddress to "[email protected]"
set toName to "John Doe"
tell application "Mail"
do shell script "cat ~/Documents/RTF\\ File.rtf | textutil -stdin -stdout -convert rtf | pbcopy"
set refMessage to make new outgoing message with properties {name:toName, address:toAddress, subject:textSubject, visible:true}
tell refMessage
make new to recipient at end of to recipients with properties {name:toName, address:toAddress}
end tell
end tell
tell application "System Events"
tell application process "Mail"
set frontmost to true
set value of attribute "AXFocused" of scroll area 4 of window textSubject to true
end tell
keystroke "v" using {command down}
end tell
再次,这在 Snow Leopard 上运行良好
希望有所帮助。
如果 HTML 文件的内容是真正的 HTML,则以下脚本将在 Mail.app 中创建外发消息及其内容。不涉及 GUI 脚本。发送给自己后,您可以确认链接和其他丰富的内容已保留。
use framework "Foundation"
use framework "AppKit"
use scripting additions
-- classes, constants, and enums used
property NSUTF8StringEncoding : a reference to 4
property NSSharingServiceNameComposeEmail : a reference to current application's NSSharingServiceNameComposeEmail
property NSAttributedString : a reference to current application's NSAttributedString
property NSString : a reference to current application's NSString
property NSSharingService : a reference to current application's NSSharingService
set messageSubject to "Sending the message with html file contents."
set recipientAddresses to {"[email protected]"} -- I will send to myself, to test
set htmlContent to read (POSIX path of (choose file))
set theSource to NSString's stringWithString:htmlContent
set theData to theSource's dataUsingEncoding:NSUTF8StringEncoding
set anAttributedString to NSAttributedString's alloc()'s initWithHTML:theData documentAttributes:{}
-- USE THE MAIL SHARING SERVICE TO CREATE A NEW MAIL MESSAGE
set aSharingService to NSSharingService's sharingServiceNamed:(NSSharingServiceNameComposeEmail)
if aSharingService's canPerformWithItems:recipientAddresses then
set aSharingService's subject to messageSubject
set aSharingService's recipients to recipientAddresses
tell aSharingService to performSelectorOnMainThread:"performWithItems:" withObject:{anAttributedString} waitUntilDone:false
end if