从可可发送HTML邮件与Mail.app [英] Send HTML Mail from Cocoa with Mail.app
问题描述
我想从可可应用程序发送HTML格式的电子邮件,通过Mail.app。我想打开Mail.app新的消息,包括主题,收件人,并添加HTML机身采用链接及其他内容。但无法找到这样做的方式。
我已经尝试过脚本桥接,但MailOutgoingMessage类不具有内容类型,我可以在纯文本添加内容。
I'm trying to send html email from Cocoa app, through Mail.app. I want to open new message in Mail.app, include subject, recipient and add HTML Body with links and other content. But can't find the way to do this. I already tried Scripting Bridge, but MailOutgoingMessage class doesn't have content type i can add content in plaintext.
尝试AppleScript的,是这样的:
tried AppleScript, something like this:
set htmlContent to read "/Path/index.html"
set recipientList to {"mail@mail.com"}
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:"mail@s.com"}
set html content to htmlContent
--send
end tell
end tell
这code发送电子邮件,HTML,只是如果我改变--SEND发送。但我需要稍后发送信函,之后用户做出了一些改变。
this code send email with html, only if I'm changing --send to send. But i need to send letter later, after user made some changes.
推荐答案
要回顾一下这个问题:使用AppleScript创建具有HTML内容的消息的交互的修改不起作用的(如OS X 10.9.2的):新的消息的形式出现用的空的身体
To recap the problem: Using AppleScript to create a message with HTML content for interactive editing does not work (as of OS X 10.9.2): the new-message form comes up with an empty body.
这应该算是一个错误并我鼓励大家让苹果知道的http:// bugreport.apple.com - 的警告的:在 HTML内容
的消息
类属性的不的在 Mail.sdef
,定义Mail.app </ code>的AppleScript字典,所以分配HTML可能无法正式支持。
This should be considered a bug and I encourage everyone to let Apple know at http://bugreport.apple.com - caveat: the html content
message
class property is not defined in Mail.sdef
, Mail.app
's AppleScript dictionary, so assigning HTML may not be officially supported.
有一个解决方法,但它不是pretty:
There is a workaround, but it ain't pretty:
- 创建消息无形的
- 保存它的为草稿的
- 打开的草案的消息,此时HTML内容的将会的出现。
- Create the message invisibly.
- Save it as a draft.
- Open the draft message, at which point the HTML content will appear.
实现这个强劲是具有挑战性的,因为需要多个解决方法。下面code尝试最难的,虽然:
Implementing this robustly is challenging, because several workarounds are required. The following code tries its hardest, though:
请注意:由于code使用GUI脚本,必须启用辅助设备的访问(通过系统preferences&GT;安全与隐私权&GT;辅助功能
)运行该code中的应用程序(例如,的AppleScript编辑器
或者,如果通过运行 osascript
, Terminal.app </ code>)。
Note: Since the code uses GUI scripting, Access for Assistive Devices must be enabled (via System Preferences > Security & Privacy > Accessibility
) for the application running this code (e.g., AppleScript Editor
or, if run via 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 {"person1@example.com", "person2@example.com"}
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
这篇关于从可可发送HTML邮件与Mail.app的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!