dsh-calendar:給 DSH 接入 CalDAV 日曆工具

前言

在 DSH 智能體場景裏,模型經常需要查詢“今天有哪些日程”“明天上午是否有空”,或者把一條待辦落成日曆事件。如果每次都要人工導出日曆文本、截圖或手寫同步腳本,模型就很難直接參與排期。

dsh-calendar 是一個 DSH 社區插件,通過 CalDAV 讀寫日曆事件,支持 Google、iCloud、Nextcloud 及任意自定義 CalDAV 服務器。DSH 生態強調“一切皆插件”;這裏介紹的是社區插件,不是官方應用商店內置能力。

插件概覽

dsh-calendar 解決的問題很明確:把日曆事件能力封裝成 DSH 可以調用的模型工具。

它提供五個面向模型的工具:

  • calendar_list:列出某時間段內的事件
  • calendar_create:新建事件
  • calendar_update:按 uid 更新事件
  • calendar_delete:按 uid 刪除事件
  • calendar_search:按關鍵詞搜索事件

幾個關鍵事實如下:

  • GitHub 倉庫:https://github.com/STARDUSTLC666/dsh-calendar
  • 許可證:MIT
  • 運行要求:Node >=22
  • 認證方式:Basic 認證,使用應用專用密碼
  • 不支持 Google / iCloud OAuth 登錄流程
  • 無設置頁 UI,配置走 profile 的 cordis.patch.yml
  • 事件穩定標識 uid 使用 CalDAV href

安裝與啓用

先在目標 profile 中安裝插件:

dsh plugin --profile web add dsh-calendar

安裝後重啓 dsh。

默認配置通常沒有填寫任何憑證,此時插件可以正常加載,但工具在調用時會返回中文指引錯誤,提示補全配置。配置位置是當前 profile 的 cordis.patch.yml,按 id 覆蓋 calendar 行的 config。

一個最小示例:

- id: calendar
  config:
    provider: custom
    caldavUrl: https://dav.example.com/calendars/me/work/
    username: me
    password: 你的應用專用密碼

如果不想把密碼寫進 YAML,可以使用環境變量 DSH_CALENDAR_PASSWORD。

卸載命令如下:

dsh plugin --profile web remove dsh-calendar

卸載後重啓 Web 服務。如需徹底清理,可再手動刪除自己 profile cordis.patch.yml 中的對應插件行。

配置字段

所有配置都在 cordis.patch.yml 的 calendar 行裏。常用字段如下:

  • provider:google、icloud、nextcloud、custom
  • caldavUrl:完整日曆集合 URL。custom 和 icloud 必填;google / nextcloud 也可以手動填寫以覆蓋預設
  • username:CalDAV 賬號。Google / iCloud 一般填賬號郵箱
  • password:密碼。Google / iCloud 請使用應用專用密碼
  • proxyUrl:本機代理地址。中國大陸訪問 Google / iCloud 的 CalDAV 端點時可能需要
  • calendarId:Google 專用,日曆 ID,通常可以是你的郵箱
  • host:Nextcloud 專用,例如 https://cloud.example.com
  • user:Nextcloud 專用,CalDAV 用戶
  • calendar:Nextcloud 專用,日曆名

典型用法

Google 日曆

Google 示例如下:

- id: calendar
  config:
    provider: google
    username: you@gmail.com
    calendarId: you@gmail.com
    # 也可以改用 DSH_CALENDAR_PASSWORD
    password: 你的應用專用密碼

Google 的 CalDAV 集合 URL 由插件拼成:

https://apidata.googleusercontent.com/caldav/v2/<calendarId>/events

Google 需要使用應用專用密碼,不能使用 Google 登錄密碼。

iCloud 日曆

iCloud 示例如下:

- id: calendar
  config:
    provider: icloud
    username: you@icloud.com
    caldavUrl: https://caldav.icloud.com/123456789/calendars/<日曆ID>/
    # 也可以改用 DSH_CALENDAR_PASSWORD
    password: 你的應用專用密碼

iCloud 需要手動填寫完整日曆集合 URL,包含用戶 ID 和日曆 ID。插件不做 principal 自動發現,也不做多日曆選擇。

iCloud 同樣需要使用應用專用密碼,不能使用 Apple ID 登錄密碼。

Nextcloud 日曆

Nextcloud 示例如下:

- id: calendar
  config:
    provider: nextcloud
    username: alice
    host: https://cloud.example.com
    user: alice
    calendar: personal
    # 也可以改用 DSH_CALENDAR_PASSWORD
    password: 你的應用專用密碼

插件會拼成類似:

https://cloud.example.com/remote.php/dav/calendars/alice/personal/

自定義 CalDAV

自定義 CalDAV 示例如下:

- id: calendar
  config:
    provider: custom
    caldavUrl: https://dav.example.com/calendars/me/work/
    username: me
    # 也可以改用 DSH_CALENDAR_PASSWORD
    password: 你的應用專用密碼

這種方式適合自建 Radicale、Nextcloud 或其他提供標準 CalDAV 的服務器。

工具行爲

calendar_list

calendar_list 用於列出某時間段內的事件。

支持參數:

  • start / end:ISO 8601 時間
  • expand:是否展開重複事件,默認 true
  • maxOccurrences:重複事件展開數量上限,默認 30,範圍 1-200

默認情況下,calendar_list 會展開重複事件。展開後的實例會帶:

  • isOccurrence: true
  • seriesStart

非重複事件會保持:

  • isOccurrence: false

如果設置 expand=false,重複事件會按原始單條返回,並帶 rrule。

結果按開始時間穩定排序。

calendar_create

calendar_create 用於新建事件。

必填字段:

  • summary
  • start
  • end

可選字段:

  • description
  • location
  • allDay
  • rrule

插件會校驗真實日曆日期,並要求 end >= start。例如 2025-02-30 這類不存在的日期會被拒絕。

calendar_update

calendar_update 按 uid 更新事件。

可更新字段包括:

  • summary
  • start
  • end
  • description
  • location
  • allDay
  • rrule

未提供的字段保留原值。重複規則不會因爲更新其他字段而丟失。

calendar_delete

calendar_delete 按 uid 刪除事件。

calendar_search 用於按關鍵詞搜索事件。

它會對標題、描述、地點、UID 做客戶端過濾,不區分大小寫。

支持參數:

  • 關鍵詞
  • limit:默認 50,範圍 1-200

結果按開始時間排序。

需要注意:calendar_search 返回原始系列,不展開重複事件。

重複事件限制

calendar_update 和 calendar_delete 按 uid 操作整個重複系列。

這意味着它們適合修改或刪除整個重複日程,但不支持只修改或刪除某一次發生。換句話說,不支持 RECURRENCE-ID 實例級修改或刪除。

如果你需要“只取消週三那一次”,這個插件目前不能直接做到。

時區與時間格式

輸入輸出統一使用 ISO 8601。

  • 定時事件輸出爲 UTC,例如:
2025-01-15T01:00:00Z
  • 全天事件輸出爲日期格式:
2025-01-15

輸入可以帶時區偏移,例如:

2025-01-15T09:00:00+08:00

插件內部會轉成 UTC 存儲。

帶 TZID 命名時區的事件輸出會轉成 UTC。全天邊界、夏令時等複雜時區規則不做精細化處理。

代理與網絡限制

中國大陸訪問 Google 與 iCloud 的 CalDAV 端點不可直連。可以使用 proxyUrl 配置本機代理。

示例:

- id: calendar
  config:
    provider: google
    username: you@gmail.com
    calendarId: you@gmail.com
    password: 你的應用專用密碼
    proxyUrl: http://127.0.0.1:7890

這裏的 proxyUrl 填你本機代理客戶端實際暴露的 HTTP 端口。國內可直連的 CalDAV 服務,例如自建 Nextcloud 或其他私有 CalDAV,通常不需要配置代理。

工具整體超時爲 60 秒。插件不在單次網絡請求上透傳 AbortSignal。

適用場景

dsh-calendar 比較適合這類場景:

  • 你使用 DSH 做智能體或助手,希望模型能直接查詢日曆
  • 你需要模型創建、更新、刪除或搜索日程
  • 你已有 Google、iCloud、Nextcloud 或其他 CalDAV 服務
  • 你可以通過 cordis.patch.yml 維護插件配置
  • 你接受當前版本沒有 Web 設置頁,配置直接寫在 YAML 中

注意事項

使用前建議注意以下幾點:

  1. 插件會以當前 dsh 進程權限運行,安裝前建議檢查源碼與許可證。
  2. 只支持 Basic 認證,不支持 Google / iCloud OAuth。
  3. Google / iCloud 必須使用應用專用密碼,不能用登錄密碼。
  4. calendar_update 與 calendar_delete 針對整個重複系列,不支持單次實例級操作。
  5. calendar_search 不展開重複事件。
  6. iCloud 需要手動填寫完整日曆集合 URL。
  7. 沒有設置頁 UI,所有配置走 cordis.patch.yml。
  8. 如果調用返回 401 / 403,優先檢查是否誤用了登錄密碼。

結尾

dsh-calendar 的價值在於把 CalDAV 日曆能力封裝成五個穩定的模型工具,讓 DSH 智能體可以直接完成查日程、建日程、改日程、刪日程和搜日程這些動作。

GitHub 倉庫:

https://github.com/STARDUSTLC666/dsh-calendar
羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜