You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在NodeJS服务器中调用官方iCloud Calendar API?

基于NodeJS访问iCloud Calendar的官方解决方案

你可以通过两种官方支持的方式实现需求:CalDAV协议(通用日历协议,iCloud原生支持)或CloudKit JS(苹果官方JS库)。以下是具体步骤和代码示例,均为官方合规方案,无需担心账号封禁。

一、优先选择:CalDAV协议(适合个人/单用户自动化)

iCloud完全支持标准CalDAV协议,可通过应用专用密码进行Basic Auth认证,无需依赖网页Cookie或非官方接口。

前置准备

  1. 生成Apple ID应用专用密码:登录Apple ID管理页面,进入「安全」选项,点击「应用专用密码」生成,保存好该密码(仅显示一次)。
  2. 安装依赖:
npm install axios xml2js ical.js

NodeJS代码示例

const axios = require('axios');
const xml2js = require('xml2js');
const ICAL = require('ical.js');

// 配置信息
const APPLE_ID = '你的Apple ID邮箱';
const APP_SPECIFIC_PASSWORD = '你的应用专用密码';
const CALDAV_SERVER = 'https://caldav.icloud.com';

// 1. 获取用户主资源URL
async function getPrincipalUrl() {
  const response = await axios({
    method: 'PROPFIND',
    url: CALDAV_SERVER,
    auth: { username: APPLE_ID, password: APP_SPECIFIC_PASSWORD },
    headers: { 'Depth': 0 },
    data: `<?xml version="1.0" encoding="UTF-8"?>
<D:propfind xmlns:D="DAV:">
  <D:prop><D:current-user-principal/></D:prop>
</D:propfind>`
  });
  const parser = new xml2js.Parser();
  const result = await parser.parseStringPromise(response.data);
  return result['D:multistatus']['D:response'][0]['D:propstat'][0]['D:prop'][0]['D:current-user-principal'][0]['D:href'][0];
}

// 2. 获取日历列表
async function getCalendars(principalUrl) {
  const response = await axios({
    method: 'PROPFIND',
    url: `${CALDAV_SERVER}${principalUrl}`,
    auth: { username: APPLE_ID, password: APP_SPECIFIC_PASSWORD },
    headers: { 'Depth': 1 },
    data: `<?xml version="1.0" encoding="UTF-8"?>
<D:propfind xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
  <D:prop><D:displayname/><D:href/></D:prop>
</D:propfind>`
  });
  const parser = new xml2js.Parser();
  const result = await parser.parseStringPromise(response.data);
  return result['D:multistatus']['D:response'].map(item => ({
    name: item['D:propstat'][0]['D:prop'][0]['D:displayname'][0],
    url: item['D:href'][0]
  }));
}

// 3. 获取指定日期的日历事件
async function getEventsForDate(calendarUrl, targetDate) {
  const start = new Date(targetDate.getFullYear(), targetDate.getMonth(), targetDate.getDate()).toISOString();
  const end = new Date(start);
  end.setDate(end.getDate() + 1);

  const response = await axios({
    method: 'REPORT',
    url: `${CALDAV_SERVER}${calendarUrl}`,
    auth: { username: APPLE_ID, password: APP_SPECIFIC_PASSWORD },
    headers: { 'Content-Type': 'application/xml; charset=utf-8' },
    data: `<?xml version="1.0" encoding="UTF-8"?>
<C:calendar-query xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
  <D:prop><D:getetag/><C:calendar-data/></D:prop>
  <C:filter>
    <C:comp-filter name="VCALENDAR">
      <C:comp-filter name="VEVENT">
        <C:time-range start="${start}" end="${end.toISOString()}"/>
      </C:comp-filter>
    </C:comp-filter>
  </C:filter>
</C:calendar-query>`
  });

  const parser = new xml2js.Parser();
  const result = await parser.parseStringPromise(response.data);
  return result['D:multistatus']['D:response'].map(item => {
    const icalData = item['D:propstat'][0]['D:prop'][0]['C:calendar-data'][0];
    const jcal = ICAL.parse(icalData);
    const event = new ICAL.Event(jcal[2][0]);
    return {
      title: event.summary,
      start: event.startDate.toJSDate(),
      end: event.endDate.toJSDate(),
      description: event.description
    };
  });
}

// 主执行逻辑
async function main() {
  try {
    const principalUrl = await getPrincipalUrl();
    const calendars = await getCalendars(principalUrl);
    
    // 选择目标日历(比如第一个日历)
    const targetCalendar = calendars[0];
    console.log(`正在读取日历:${targetCalendar.name}`);
    
    // 获取指定日期的事件(示例:明天)
    const targetDate = new Date();
    targetDate.setDate(targetDate.getDate() + 1);
    const events = await getEventsForDate(targetCalendar.url, targetDate);
    
    console.log(`目标日期事件:`, events);
  } catch (err) {
    console.error('请求失败:', err.response?.data || err.message);
  }
}

main();

二、CloudKit JS方案(适合多用户/苹果生态集成)

如果你的应用需要支持多用户登录,可使用苹果官方CloudKit JS库,通过Apple Sign In获取用户授权后访问日历数据。

核心步骤

  1. 在苹果开发者后台创建CloudKit容器,关联你的App ID并开启iCloud服务。
  2. 初始化CloudKit JS,通过Apple Sign In获取用户的认证令牌。
  3. 调用CloudKit API读取日历私有数据库中的事件数据。

该方案需遵循苹果的OAuth 2.0授权流程,适合面向用户的Web/桌面应用,个人自动化脚本推荐使用CalDAV方案。

对之前尝试方法的补充说明

  • 网页Cookie抓包:属于临时会话认证,苹果不支持长期使用,会话过期后需重新登录,不适合自动化场景。
  • 开发者账号密钥:CloudKit的服务器密钥仅用于访问公共数据库,私有日历数据需用户授权,因此CalDAV的应用专用密码更直接。
  • 非开源第三方库:未经过苹果官方认证,存在账号封禁风险,优先使用官方支持的CalDAV或CloudKit方案。

内容的提问来源于stack exchange,提问作者Manuela Garcia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 11:55:40