PAYATHON 2026

AppleScript 读取 Mail 邮件属性时报错,如何修正?

数据小陈

先通过 Mail 的 date received 取得收件日期,再读取日期值的 date string。遍历时使用邮箱中的 messages,无需为了后续删除邮件而对循环变量使用 a reference to。

原代码中的计数和退出循环写法也需要修正:赋值使用 set counter to counter + 1,退出循环使用 exit repeat。

先修正读取单封邮件的代码

以下示例假设 Mail 中有名为 iCloud 的账户和名为 INBOX 的邮箱:

tell application "Mail"
    set inbox_box to mailbox "INBOX" of account "iCloud"

    if (count of messages of inbox_box) is 0 then
        error "目标邮箱中没有邮件。"
    end if

    set the_message to last message of inbox_box
    set received_date to get date received of the_message
end tell

set received_text to date string of received_date
display dialog received_text

代码分两步处理:先从 Mail 读取邮件的收件日期,再用 AppleScript 将日期转换为可显示的文本。读取属性前无需执行 open the_message。

date string 是 AppleScript 的 date 对象属性。如果将它直接接在 Mail 对象的属性链上,应用可能会收到本应由 AppleScript 处理的属性请求。显式使用 get 可以先求出属性链中的一部分,Apple 官方文档也说明了这种用法:get 的求值规则。

原始材料没有提供 display dialog 对应的完整错误信息,因此不能断定属性求值是出错的唯一原因。分开读取邮件属性和格式化日期,有助于定位错误。

正确遍历最多 10 封邮件

mailbox "INBOX" of account "iCloud" 表示邮箱对象,循环需要读取该邮箱中的邮件列表:

tell application "Mail"
    set message_list to get messages of mailbox "INBOX" of account "iCloud"
end tell

set counter to 0
repeat with each_message in message_list
    set the_message to contents of each_message

    tell application "Mail"
        set received_date to get date received of the_message
    end tell

    log (date string of received_date)

    set counter to counter + 1
    if counter >= 10 then exit repeat
end repeat

邮件不足 10 封时,代码会处理全部邮件;邮箱为空时,不会进入循环。日期通过 log 输出,可以在 Script Editor 的日志中查看。

在 repeat with each_message in message_list 中,循环变量已经是对当前列表项的引用。contents of each_message 取出该项保存的邮件对象说明符,不表示读取邮件正文。这是 AppleScript 列表循环的既定行为,参见 repeat 的列表遍历规则。

为什么不需要额外的 a reference to?

a reference to 用于建立延迟求值的引用,删除邮件并不需要这一步。对这里的循环变量再包装一层引用,既没有解决遍历对象和属性求值的问题,还引入了当前的报错。

通过 set the_message to last message ... 或从邮件列表中取得 the_message 后,变量保存的邮件对象说明符可用于后续 Mail 操作。需要删除时,只要对象仍然有效,就可以执行:

tell application "Mail"
    delete the_message
end tell

这条命令会实际删除目标邮件,应在确认删除条件成立后执行。批量删除时,避免一边按邮箱中的位置索引取邮件,一边删除邮件,因为删除可能改变后续索引。上面的遍历示例先取得邮件列表,便于逐项处理。邮件被移动或删除后,也不要继续依赖旧对象说明符读取属性。

原代码中的其他问题

  • counter = counter + 1 是相等比较,不会更新计数器;应改为 set counter to counter + 1。
  • 结束当前循环使用 exit repeat,不要用 stop 代替。
  • 原代码的第一段没有展示 tell application "Mail"。访问 Mail 的账户、邮箱和邮件时,需要明确应用上下文。
  • last message 表示 Mail 返回顺序中的最后一项,不能仅凭这个表达式认定它是按收件日期排序后的最新邮件。
  • date string 只包含日期部分,显示格式受系统区域设置影响。若还需要时间,可另取 time string,参见 AppleScript 日期属性。

如果分步读取后仍出错,应先单独运行 get date received of the_message,记录完整错误文本,确认问题发生在邮件对象定位、属性读取还是日期格式化阶段。

备注:内容仅供参考。