AppleScript error: "Mail got an error: Can’t set text item delimiters to {"+", "@"}."

AppleScript error: "Mail got an error: Can’t set text item delimiters to {"+", "@"}."

我编写了一个 AppleScript,只要收到包含“+”的电子邮件,它就会被邮件规则激活。

为什么?我托管自己的邮件服务器,允许地址标记。这意味着,例如,当我在一家商店时,他们要我的电子邮件地址,以便他们可以通过电子邮件发送收据,我可以像这样给他们我的电子邮件地址:whatmyemailnormallyis+nameofstore@domain.com。然后 applescript 应该获取“+”和“@”字符之间的字符串,创建一个名为“nameofstore”的邮箱并将邮件移动到其中。除了出现以下错误外,一切正常:

“邮件出现错误:无法将文本项分隔符设置为 {"+"、"@"}。”

这是我的脚本:

tell application "Mail"
    set unreadmessages to the first message of mailbox "INBOX" of account "Account"
    set theEmail to extract address from sender of item 1 of unreadmessages
    set mystring to theEmail
    set text item delimiters to {"+", "@"}
    set textlist to text items of mystring
    set mylist to {}
    repeat with i from 2 to count of textlist by 2
        set end of mylist to item i of textlist
    end repeat
    get mylist
    set mailboxName to mylist
    set messageAccount to account of (mailbox of item 1 of unreadmessages)
    set newMailbox to make new mailbox at (end of mailboxes of messageAccount) with properties {name:mailboxName}
    repeat with eachMessage in unreadmessages
        set mailbox of eachMessage to newMailbox
    end repeat
end tell

当我 运行 只有脚本的文本提取部分时它工作正常:

set mystring to "whatmyemailnormallyis+nameofstore@domain.com"
set text item delimiters to {"+", "@"}
set textlist to text items of mystring
set mylist to {}
repeat with i from 2 to count of textlist by 2
    set end of mylist to item i of textlist
end repeat
get mylist

结果:

{"nameofstore"}

如有任何帮助,我们将不胜感激。如果任何比我拥有更好 AppleScript 技能的人可以在其他方面改进脚本,我们也将不胜感激。

这是一个继承问题。 属性 (text item delimiters) 是 current application (AppleScript) 实例的 属性,但它在 tell application 块中被不合格引用将命令定向到目标应用程序并枚举其属性,在本例中为 Mail.

可能会想将 text item delimiters 设置在 tell 块之外,方法是将其从当前行位置移动到块声明之前。这是合理的,但我认为你已经完美地定位了它,因为跟踪这个 属性 以确保它始终被适当地设置是很重要的(也是良好的做法),更重要的是,永远不会不恰当地未设置。执行此操作的最可靠方法,也使其他人更容易遵循,是按照您所做的去做,即将 属性 设置在它施加影响的任何语句之前(即,任何时候 list 被强制转换为 text,或者 text 被拆分为 text items)。

因此,为了避免乱码,我们需要让编译器清楚我们引用的 属性 不属于 application "Mail",但是对于顶级脚本对象,最典型的是 current application。执行此操作的三种方法是:

  • set AppleScript's text item delimiters to ...

  • set the current application's text item delimiters to ...

  • set my text item delimiters to ...

在风格上,我赞成最后一个选项。但是,my 不是 current application 的同义词,也不是 AppleScript 的同义词,而是对脚本的父级。除非在您的脚本中明确声明 parent 属性,否则它将默认为 current application。但是,有些人可能会选择分配不同的值,在这种情况下,只有上述三个选项中的第一个或第二个可行。


这里对您的脚本稍作修改,恐怕您必须测试一下,以代替我购买新的 MacBook。我注意到你有些奇怪:

  • 您在收件箱中收到 first message,但在下一行中,引用 item 1...,我想您认为会是 list消息,但实际上是单个 message class 对象。

  • 这个 message 对象是您的脚本用来处理发件人电子邮件地址的唯一消息。然而,稍后,您再次循环遍历您期望的收件箱消息集合,如果是的话,可能并不都具有相同的 + 标签。

  • 您循环遍历通过拆分电子邮件地址生成的 text items,并且相当巧妙地从索引 2 开始,并跳过列表中的所有其他项目。但是,此列表中只有三个项目,因此永远不会进行任何循环,您可以简单地使用 text item 2.

  • 在创建新邮箱时,您没有先检查邮箱是否已经存在。我不确定 Mail 是否会抛出错误,或者默默地忽略它。但是我重新起草了先检查的行,然后在必要时创建。

  • 最后,鉴于 unreadmessages 不是列表(因此实际上可能会抛出错误),目前不需要最后的重复循环。所以我删除了循环结构,但在其他方面保持原样。我不确定 messagemailbox 属性 是否可以设置,即它可能是只读的。如果是这种情况,将引发错误,您必须调用 move 命令才能将邮件移动到新邮箱。不过,我可能是错的,它可能会按照您的预期工作。

tell application "Mail"
    set firstInboxMessage to the first message in the inbox
    set theEmail to extract address from sender of the firstInboxMessage

    set my text item delimiters to {"+", "@"}
    -- Since the script will trigger only when an email address
    -- contains "+", we know text item 2 will always exist and
    -- will always represent the slice of text we're after
    set mailboxName to text item 2 of theEmail

    set messageAccount to account of mailbox of the firstInboxMessage
    tell the messageAccount to if the name of its mailboxes does not contain ¬
        the mailboxName then make new mailbox at the end of its mailboxes ¬
        with properties {name:mailboxName}
    set newMailbox to the mailbox named mailboxName in the messageAccount
    set the mailbox of the firstInboxMessage to the newMailbox
end tell

实际上,如果您将此脚本作为邮件规则调用,您可能希望将其包含在可以在 Mail 中查找的特殊处理程序中脚本字典,叫做 on receiving messages <messages> for mailbox rule <rule>