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,记录完整错误文本,确认问题发生在邮件对象定位、属性读取还是日期格式化阶段。
备注:内容仅供参考。
