mcpField
A
automating-calendar

automating-calendar

github.com/spillwavesolutions生产力4852 次安装10 周前更新
代码仓库

关于 automating-calendar

面向 macOS 日历事件与日历操作的自动化技能,指导开发者通过 AppleScript 探索术语,并使用 JXA、PyXA 和 EventKit 查询;还包含验证与错误处理实践。

主要功能

  1. 01探索 Calendar 脚本术语
  2. 02使用 JXA 和 AppleScript 自动化
  3. 03使用 PyXA 与 EventKit 桥接
  4. 04批量读取事件并查询日期
  5. 05验证访问权限和事件结果

适用场景

  1. 01用 JXA 或 PyXA 创建日历事件
  2. 02通过 EventKit 查询事件
  3. 03检查事件创建结果和日历访问权限
  4. 04处理时区与重复事件

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/spillwavesolutions/automating-mac-apps-plugin --skill automating-calendar

安装后在 Claude Code 中输入/automating-calendar确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
calendar-advanced.md
calendar-basics.md
calendar-dictionary.md
calendar-pyxa-api-reference.md
calendar-recipes.md
eventkit-create.md
eventkit-exceptions.md
eventkit-occurrence-cancel.md
eventkit-query.md
eventkit-timezones.md
scripts/
calendar_summary.py
create_calendar_event.py
delete_calendar_events.py
find_free_slots.py
list_upcoming_events.py
set_up_calendar_automation.py
set_up_calendar_automation.sh

详细介绍

自动化日历(JXA 与 AppleScript 探索)

目录

与 macOS 自动化技能的关系

  • 使用 automating-mac-apps 处理通用应用权限、Shell 命令、UI 脚本和跨应用自动化模式。
  • 本技能专注于日历事件、日历和 EventKit 桥接功能。
  • **PyXA 安装:**如需在本技能中使用 PyXA 示例,请参阅 automating-mac-apps 技能中的安装说明(PyXA 安装部分)。

核心思路

  • 日历词典以 AppleScript 为主;在 Script Editor 中进行探索
  • JXA 提供逻辑、数据处理和 ObjC/EventKit 桥接访问
  • PyXA 提供语法更简洁的现代 Python 替代方案

**实现说明:**参阅 automating-calendar/references/calendar-basics.md

工作流(默认)

  1. 在 Script Editor 中探索日历词典术语。
  2. 编写最精简的 AppleScript 命令原型。
  3. 添加防御性错误处理,并移植到 JXA。
  4. 实现批量读取(避免使用开销较大的 .whose())。
  5. 添加 EventKit 桥接,以支持高级查询。
  6. 使用示例事件进行测试,并验证结果。
错误处理
  • 使用 try-catch 块包装操作
  • 验证日历访问权限:Calendar.calendars.length > 0
  • 检查事件创建结果:if (!event.id()) throw new Error('Event creation failed')
  • 记录操作日志以便调试
验证清单
  • 已授予日历权限(System Settings > Privacy & Security > Calendars)
  • 已确认可访问日历:Calendar.calendars.length > 0
  • 已使用有效的开始和结束日期创建事件
  • 保存后,事件会显示在 Calendar UI 中
  • EventKit 桥接查询返回预期结果
  • 所有操作均由错误处理代码包装
  • 输出符合预期的事件属性

核心示例

创建基本事件(JXA - 旧版):

const Calendar = Application("Calendar");
const event = Calendar.calendars[0].events.push(Calendar.Event({
  summary: "Meeting",
  startDate: new Date(),
  endDate: new Date(Date.now() + 3600000)
}));

创建基本事件(PyXA - 推荐):

import PyXA
from datetime import datetime, timedelta

calendar = PyXA.Calendar()

# Get first calendar
work_calendar = calendar.calendars()[0]

# Create event
event = work_calendar.events().push({
    "summary": "Meeting",
    "start_date": datetime.now(),
    "end_date": datetime.now() + timedelta(hours=1),
    "location": "Conference Room A"
})

print(f"Created event: {event.summary()}")

使用 EventKit 的 PyObjC(高级):

from EventKit import EKEventStore, EKEvent, EKCalendar
from Foundation import NSDate, NSTimeInterval
import objc

# Initialize event store
store = EKEventStore.alloc().init()

# Request access (async in real implementation)
# store.requestAccessToEntityType_completion_(EKEntityTypeEvent, None)

# Get default calendar
calendars = store.calendarsForEntityType_(EKEntityTypeEvent)
if calendars:
    default_calendar = calendars[0]

    # Create event
    event = EKEvent.eventWithEventStore_(store)
    event.setTitle_("Meeting")
    event.setStartDate_(NSDate.date())
    event.setEndDate_(NSDate.dateWithTimeIntervalSinceNow_(3600))  # 1 hour
    event.setCalendar_(default_calendar)

    # Save event
    error = objc.nil
    success = store.saveEvent_span_error_(event, EKSpanThisEvent, error)

    if success:
        print(f"Event created: {event.title()}")
    else:
        print(f"Error creating event: {error}")

EventKit 桥接查询(JXA - 旧版):

ObjC.import('EventKit');
const store = $.EKEventStore.alloc.init;
// See 'eventkit-query.md' for full predicate implementation

EventKit 桥接查询(PyObjC - 现代):

from EventKit import EKEventStore, EKEntityTypeEvent, NSPredicate
from Foundation import NSDate

store = EKEventStore.alloc().init()

# Get events for today
start_date = NSDate.date()  # Today
end_date = NSDate.dateWithTimeIntervalSinceNow_(86400)  # Tomorrow

calendars = store.calendarsForEntityType_(EKEntityTypeEvent)
predicate = store.predicateForEventsWithStartDate_endDate_calendars_(
    start_date, end_date, calendars)

events = store.eventsMatchingPredicate_(predicate)

for event in events:
    print(f"Event: {event.title()}, Start: {event.startDate()}")

不适用场景

  • 跨平台日历自动化(使用 Google Calendar API 或 CalDAV)
  • iCloud 同步操作(直接使用 EventKit)
  • 非 macOS 平台
  • 简单的 AppleScript 独立任务(无需 JXA)
  • 日历共享或权限管理(使用 Calendar UI)

应加载的内容

  • Calendar JXA 基础知识:automating-calendar/references/calendar-basics.md
  • 操作指南(事件、提醒、重复规则):automating-calendar/references/calendar-recipes.md
  • 高级模式(时区、批量读取、EventKit 桥接):automating-calendar/references/calendar-advanced.md
  • 词典翻译表:automating-calendar/references/calendar-dictionary.md
  • PyXA API 参考(完整的类和方法文档):automating-calendar/references/calendar-pyxa-api-reference.md
  • EventKit 查询示例:automating-calendar/references/eventkit-query.md
  • 使用重复规则创建 EventKit 事件:automating-calendar/references/eventkit-create.md
  • EventKit 时区示例:automating-calendar/references/eventkit-timezones.md
  • EventKit 异常/发生项:automating-calendar/references/eventkit-exceptions.md
  • EventKit 取消发生项示例:automating-calendar/references/eventkit-occurrence-cancel.md

评论

支持 Markdown