DingTalk Calendar Skill
Prerequisites — Must Read Before Executing Any Operation
CRITICAL — Before executing any operation, MUST first use the Read tool to fully read . This lightweight file contains the global execution contract, safety baseline, and on-demand loading navigation for shared references; do not preload all its references.
For common paths, execute directly according to this file; do not pre-read the large and comprehensive calendar.md. Only read the corresponding sections on demand when recurring schedules, responding to invitations, sharing/ACL, attachments, calendars, or low-frequency parameters cannot be located from this file; read 03-meeting.md only for the scope and failure closure of meeting room booking.
<!-- VISIBLE_SHORTCUTS_START -->
Shortcuts (preferred when no dedicated script/recipe exists)
The following shortcuts are present in both the public catalog and the Runtime Schema. They are routed by this skill/recipe; when matched, a Shortcut takes precedence over atomic commands. For parameters, only query
dws schema --cli-path "calendar +<shortcut>" --compact --jq '{cli_path,parameters,constraints,confirmation}' -f json
; when only the already-published
is needed, query
--jq '{cli_path,outcomes:.result.outcomes,pagination}'
; for field-level details, further query
; do not infer missing information from Help or samples. Only read a known leaf Help once when Schema is unavailable; use the same leaf Help to fix an
once. For
, Help is forbidden: if a wrong suggestion is given, use the explicit entry already loaded in the Skill/reference; if neither exists, report drift. Full Catalog/root/parent/product Help is forbidden; omit
only for mapping, interface, or provenance audits. When existing routing and references cannot locate low-frequency capabilities, use
dws shortcut list --service calendar --format json
to discover.
| Shortcut | Risk | Applicable scenario |
|---|
| read | Query the schedule list (defaults to today when no time is provided) |
dws calendar +attendee-list
| read | View event attendees |
| write | Create an event, and optionally invite attendees by name (automatically resolves userId; on failure, automatically rolls back and deletes the event) |
| read | Query the user's calendar list |
dws calendar +book-search
| read | Fuzzy search calendars by name |
dws calendar +cancel-event
| high-risk-write | Cancel (delete) an existing event (first confirm it actually exists before deleting) |
| read | Detect time conflicts in my schedule for a certain day (overlap/double-booking; default today) |
| read | Query a person's busy/free status in a specified time range by name (automatically resolves userId) |
| read | Find my free time slots within working hours on a certain day (default today 09:00-18:00) |
| read | Query user / meeting room busy-free status (at least one of and ) |
| write | Add attendees to an existing event by name (automatically resolves userId then batch adds) |
| read | Check my own busy/free status in a time range (default today; no name input required) |
| read | View the next nearest event (default scans the next 7 days) |
| write | Reschedule an existing event (only changes start/end time; other fields unchanged) |
| read | Search available meeting rooms by time range (defaults to 1 hour from now when no time is provided) |
dws calendar +room-groups
| read | Meeting room group list |
dws calendar +room-search
| read | Fuzzy search meeting rooms by name (does not check availability) |
dws calendar +suggest-time
| read | Resolve multiple participants by name and recommend time slots when everyone is free (automatically resolves userId) |
| read | List my today's schedule (automatically calculates today's start/end; no need to manually enter a time range) |
| read | List my tomorrow's schedule (automatically calculates tomorrow's start/end; no need to manually enter a time range) |
| read | List my this week's schedule (automatically calculates the week's start/end with Monday as the first day; no need to manually enter a time range) |
<!-- VISIBLE_SHORTCUTS_END -->
Intent Table
| User says | Command |
|---|
| "today / tomorrow / this week's schedule" | python scripts/calendar_today_agenda.py [today|tomorrow|week]
|
| "Schedule a meeting (including attendees + meeting room)" | first search rooms to get , then one event create --attendees <ids> --rooms <roomId>
; for complex fallback use calendar_schedule_meeting.py
|
| "Common free time for multiple people" | python scripts/calendar_free_slot_finder.py --users <ids> --date <yyyy-MM-dd>
|
| "Check busy/free" | dws calendar busy search --users <userIds> --start "<ISO>" --end "<ISO>"
|
| "Add attendee" / "Book room" / "Cancel" | dws calendar attendee add
/ / |
Common Fast Paths (omit Help / Reference)
When the following parameters are already determined, execute directly;
do not call
, Schema, or read
again:
| Intent | Direct command |
|---|
| Recommend common time by name | dws calendar +suggest-time --with "姓名1,姓名2" --start "<ISO>" --end "<ISO>" --duration <分钟> --format json
|
| Create a meeting by name (no meeting room) | dws calendar +book --title "<主题>" --start "<ISO>" --end "<ISO>" --with "姓名1,姓名2" --format json
; Runtime requires confirmation before precisely replaying and adding |
| Check conflicts on day N | dws calendar +conflicts --in-days <N> --format json
(today ) |
| Check free windows on day N | dws calendar +free-slots --from <开始小时> --to <结束小时> --in-days <N> --format json
|
| Search available meeting rooms | dws calendar room search --start "<ISO>" --end "<ISO>" [--group-id <ID>] --available --format json
|
| Event details/attendees | dws calendar event get --id <EVENT_ID> --format json
/ dws calendar attendee list --event <EVENT_ID> --format json
|
Under the same state, the same command with the same parameters is called only once; re-querying is allowed only when a write operation occurred, a new cursor was obtained, or the first result was clearly incomplete. When looking for an event by title, start from the most likely and narrowest time window; stop immediately once a unique match is obtained, and do not continue scanning other months.
Standard SOP (Mandatory Process)
When the following intents are matched,
must execute in the corresponding SOP order;
forbidden to skip steps, replace commands, or fabricate userId/eventId. Every command must include
; time parameters
must be ISO-8601 (e.g.,
2026-07-03T14:00:00+08:00
).
SOP-1 Query Events (list-events)
Trigger: today / tomorrow / this week's schedule / what meetings do I have / events in a certain time range.
- Preferred script (mandatory):
python scripts/calendar_today_agenda.py today|tomorrow|week
(aggregates today's agenda).
- Fallback CLI (mandatory): when the script is unavailable,
dws calendar event list --start "<起始ISO>" --end "<结束ISO>" --format json
; if / are not provided, the default is today (00:00:00~23:59:59). When is returned, continue paging until the cursor is empty; do not treat a single successful page as a complete query.
- Parse (mandatory): extract the real , , and ; extract only what is needed; forbidden to paste the entire JSON verbatim. When the user asks for a summary or count, complete the aggregation locally and only output per-group counts and necessary details, to avoid filling the reply line by line and causing the latter half to be truncated.
Forbidden: using
to replace a busy/free query (for busy/free, use SOP-3), fabricating time windows, or using non-ISO time formats.
SOP-2 Create Event (create-event)
Trigger: create an event / schedule a meeting / add an event.
- Resolve attendees (mandatory): for each name, run
dws aisearch person --query "<姓名>" --dimension name --format json
and take ; join multiple people with commas.
- Execute (mandatory):
dws calendar event create --title "<主题>" --start "<ISO>" --end "<ISO>" --attendees <userId1,userId2> --format json
(add // as needed).
- Verify (on demand once): get the event ID from in the creation response (downstream parameter semantics call it ). If the creation response already contains the title, description, and time range the user asked for, reuse it directly; do not run an extra list just to 'take another look'. Only run /narrow-window once when the response is missing fields, the user explicitly asks to verify, or the later state has changed.
Forbidden: skipping attendee userId resolution and passing names directly; fabricating a meeting room
.
SOP-3 Check Busy/Free (check-busy)
Trigger: whether someone / a meeting room is available / find free time / avoid conflicts.
- Resolve object (mandatory): name →
dws aisearch person --query "<姓名>" --dimension name --format json
to get ; for meeting room use .
- Converge time range (mandatory): / must be explicitly provided or converged by the user; if the time range is unclear, must ask first; forbidden to default to an all-day window.
- Execute (mandatory):
dws calendar busy search --users <userId1,userId2> --start "<ISO>" --end "<ISO>" --format json
(for rooms, use , can be passed together). Forbidden to use to scan schedules instead of a busy/free query.
- Free slots (mandatory): use
python scripts/calendar_free_slot_finder.py
to find common free time.
If there is indeed no common free time that satisfies the requested duration within the specified window, clearly provide the longest common free window and ask whether to shorten the duration, expand the time range, or change the date; without user confirmation, do not change the time on your own, and do not claim the meeting has been arranged.
Forbidden: using
to impersonate
, or defaulting to an all-day query before the time range is confirmed.
Execution Hard Constraints
- Verify the request first, then clean up resources: first extract and temporarily store the details, conflict pairs, attendees, meeting rooms, and verification conclusions the user asked to see from the structured responses; even if temporary resources are deleted afterward, the final reply must present these results item by item. A successful tool call does not mean the results have been delivered to the user.
- Target verification must name conclusions: when conflict/busy-free/search returns many records or the output is truncated, you must converge and verify by the current case's title, , person, or resource ID; you cannot just say 'ran the check'. For example, a conflict task must clearly state the overlapping start/end time of targets A/B and whether back-to-back adjacency is excluded.
- New event + new meeting room: prefer completing in two steps: when the user asks from the start to create an event and book a room, and there is no intermediate operation depending on a created , first run to get the real , then use one
event create ... --rooms <ROOM_ID>
to complete creation and booking; attendees can also be included via . Only use when the event already exists, the user asks to see the event before booking, or the one-step creation failed; do not perform the two writes 'create → room add' without reason.
- Multi-turn event tasks must retain the ; subsequent adding/removing attendees, booking a room, changing rooms, modifying the description, and deleting are all executed against the same ; do not recreate duplicate events.
- When the user explicitly says 'help me book an available meeting room', after returns available rooms, directly select the first that is bookable and does not require custom approval and execute ; do not throw the choice back to the user and stall the task.
- Booking a room for an existing event:
dws calendar room search --start ... --end ... --format json
→ dws calendar room add --event <EVENT_ID> --rooms <ROOM_ID> --format json
→ verify with or .
- Changing a meeting room: first
room delete --event <EVENT_ID> --rooms <OLD_ROOM_ID>
, then room add --event <EVENT_ID> --rooms <NEW_ROOM_ID>
, and finally re-check; do not only update .
- Attendee changes use , event description changes use , and event deletion uses . If the user's current message explicitly requests deletion/cancellation, execute directly; otherwise confirm first.
- Deleted terminal state: verify once on demand: when the user explicitly asks to 'confirm deletion/no residue', after succeeds, perform a narrow-window active list check using the original , title, calendar, and original start/end time; for ordinary 'cancel after done', structured deletion success is the terminal state, with no extra get/list. may still return historical objects or tombstones; unless truly exists in the response, do not claim 'status changed to cancelled'.
- When a script fails or parameters are incomplete, immediately fall back to explicit
dws calendar event/attendee/room
commands; do not stop at 'I want to view the usage'.
- All dws commands must include ; query times must explicitly use / .
Cross-Product Collaboration
- Video meeting initiation / join links / inviting to meeting / in-meeting controls → currently not supported by the CLI; please complete these in the DingTalk client
- Post-meeting summaries / to-dos → switch to
- Resolving attendees by person name → first use
Notes
For ordinary 'given time slot + any available meeting room' cases, go directly through the two-step fast path in this file; only when the user restricts building/floor/specific meeting room, the search is empty, or the range needs to be broadened, read the scope early-stop and failure gate in
03-meeting.md. All paths forbid assuming
.
Local Intents and Short Flows
- Local intent disambiguation; Short flows.