【问题标题】:Copying .rtf text into the body of an email with AppleScript使用 AppleScript 将 .rtf 文本复制到电子邮件正文中
【发布时间】:2026-01-28 18:40:02
【问题描述】:

我有一个 AppleScript 应用程序,它创建一封电子邮件(在 Mail.app 中),其中包含我通过对话框选择的选项的附件。文本模板以.rtf 格式存储,因此非程序员可以根据自己的意愿更改文本模板。

我能够从 .txt 纯文本文件创建电子邮件,但是当我导入 .rtf 文本文件时,它会导入格式化命令,我不希望在邮件中出现这些命令。

这是一个将.rtf 导入电子邮件的示例:

{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf360 {\fonttbl\f0\fswiss\fcharset0 Helvetica-Light;} {\colortbl;\red255\green255\blue255;} \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural\pardirnatural

\f0\fs24 \cf0 面向英语使用者的技术邮件\

这是我的脚本的一部分:

-- Import the .rtf file and store content in the mycontent variable    
set mycontent to (read "/Users/kiara/Desktop/mailer/technology/tech-en-content.rtf")
…
…
-- create mail from values stored in variables
tell application "Mail"
    set theMessage to make new outgoing message with properties {visible:true, subject:mysubject, content:mycontent}
    tell content of theMessage
        make new attachment with properties {file name:this_file} at after last paragraph
    end tell
end tell

是否可以将 .rtf 文件中的格式化文本导入新邮件而无需格式化代码(我选择 rtf 是因为大多数粗体和颜色用于格式化文本)?

【问题讨论】:

    标签: applescript rtf


    【解决方案1】:

    这是另一种方法:

    set the clipboard to (read "/Users/kiara/Desktop/mailer/technology/tech-en-content.rtf" as «class RTF »)
    
    tell application "Mail"
        activate
        set theMessage to make new outgoing message with properties {visible:true, subject:"mysubject"}
    end tell
    
    tell application "System Events"
        tell process "Mail"
            repeat until focused of UI element 1 of scroll area 4 of window 1
                keystroke tab
            end repeat
            keystroke "v" using command down
        end tell
    end tell
    

    【讨论】:

    • 刚刚保存了我的培根,多年来一直在与 Mail 的愚蠢模板“功能”作斗争。非常感谢!
    • 这似乎是现在唯一的方法,因为看起来苹果删除了将内容设置为 html 的能力。请参阅上述答案的最终 cmets。
    【解决方案2】:

    我认为 Mail 以纯文本或 html 格式发送电子邮件,而不是 rtf。因此,您需要将电子邮件作为 html 而不是 rtf 发送。请注意,通过 applescript 使用 Mail 发送 html 电子邮件有一个技巧。由于某种原因,您不能将新消息的可见属性设置为 true。这样做是不行的。

    这是如何帮助您的。您可以使用命令行工具 textutil 将 rtf 转换为 html,然后将其作为电子邮件发送。请注意,我在命令中使用“tidy”来确保 html 代码是干净的。

    所以您需要做的就是将收件人的电子邮件地址和主题放入此脚本并运行它...

    set emailAddress to "someone@somewhere.com"
    set theSubject to "My converted rtf to html"
    
    set rtfFile to choose file with prompt "Choose the RTF file to email as HTML:" without invisibles
    set theHTML to do shell script "/usr/bin/textutil " & " -stdout -format rtf -convert html " & quoted form of POSIX path of rtfFile & " | /usr/bin/tidy -b -utf8"
    
    tell application "Mail"
        set newMessage to make new outgoing message at end of outgoing messages with properties {visible:false}
        tell newMessage
            make new to recipient at end of to recipients with properties {address:emailAddress}
            set subject to theSubject
            set html content to theHTML
            send
        end tell
    end tell
    

    【讨论】:

    • 很好——我不知道没有记录的“html 内容”(提醒人们应该始终检查对象属性而不是依赖字典)。不过要注意两点:设置visible:false 不是必需的——省略该属性也可以工作(除了visible:true 之外的任何东西,一个怀疑);并且使用tiny -bare 将不会优雅地处理ASCII 范围之外的字符——除了退出非零(这将导致do shell script 出错)之外,它会给你留下臭名昭著的“förmatting”版本的UTF-8 文本。使用tiny -rawtiny -utf8 会得到更好的结果。
    • 感谢 cmets kopischke。我已经更新了代码以使用您关于整洁的建议。这是一个很好且必要的改进。
    • 在原始源代码视图中检查了邮件,发现“Content-Type: text/html”,所以是的,富文本以 HTML 结尾。我硬编码了一个 rtf 文件的路径并删除了发送命令,因为我的用户必须能够在发送前最后一次检查邮件。我现在面临的问题是邮件显示时没有正文中的内容。你知道如何让内容出现在正文中吗?
    • 如果您想在发送之前查看电子邮件,我认为您必须先保存不可见的电子邮件并关闭它,这样它才会变成草稿。然后您可以从草稿邮箱打开草稿。我没有任何代码,但它应该可以工作。
    • 显然,属性“html content”不再存在(在 Mac OSX Yosemite 中)。
    【解决方案3】:

    adayzdone 答案对我有用 - 或多或少。 在 Mac os X 10.15.6 、 Mail 13.4 下,滚动区域位于另一个位置/索引处。 而不是使用keystroke tab 来获取内容区域,另一种方法是

    set value of attribute "AXFocused" of UI element of scroll area 1 of window 1 to true
    

    如果您需要查找滚动区域或识别其他 UI 元素 - 您可能需要使用

    on FindScrollAreas()
        set Indices to {}
        set the clipboard to "hello World"
        tell application "System Events"
            tell process "Mail"
                activate
                set i to 1
                repeat with UIElement in UI elements of front window
                    -- button, text field, scroll area, static text
                    if class of UIElement is scroll area then
                        set end of Indices to i
                    end if
                    set i to i + 1
                end repeat
            end tell
        end tell
        return Indices
    end FindScrollAreas
    

    还有使用 Automator watch me do 获取菜单项的绝妙方法: see this post
    (您必须将事件从 Automator 复制粘贴到某个文本编辑器才能获得相应的 applescript)

    还有 Xcode -> Xcode(menu) -> Open Developer Tool -> Accessibility Inspector - 但我发现很难将信息传输到 applescript

    希望有帮助,最好的 -tom

    【讨论】: