WeCom Calendar Skill
Before executing any
commands, you must first read and complete the public pre-checks of the
skill.
Scope of Application
Applicable Scenarios
- Schedule / create events (including in-person face-to-face meetings only, i.e., arrangements without online meeting links)
- View / browse events (e.g., "What arrangements do I have today?", "Check this week's events")
- Search events (find a specific event by keywords, organizer, or attendees)
- Update / modify events (change time, location, add/remove attendees, switch meeting rooms; recurring events are not supported for updates)
- Cancel events (recurring events are not supported for cancellation)
- Check availability / schedule a common free time slot for multiple people
- Book meeting rooms, check meeting room availability, check office buildings
Non-Applicable Scenarios
- Create, update, or cancel recurring events (weekly/monthly/daily repeats) → Not supported; guide users to operate manually in the WeCom client
- Respond to / reject event invitations (accept/reject/tentative, including phrases like "Reject this event" "Will not attend") → Not supported; guide users to operate in the WeCom client or message the initiator directly
Routing for Easily Confused Scenarios
- If the user wants to create a meeting with an online meeting link (requiring meeting ID/join link, remote or video attendance) → Use instead (creating a meeting will generate an event simultaneously, no need to create another in this skill)
- If the user only mentions phrases like "hold a meeting/schedule a meeting/arrange a meeting/XX meeting" without specifying whether it's an event or an online meeting (creation scenario) → You must first use text to ask for disambiguation (fixed question: "Do you need to create an event or a meeting?", ask the user to reply with "Event / Meeting"), and must not make assumptions to create directly
- If the user needs a meeting that supports both in-person and remote attendance (e.g., "Hold offline, remote colleagues join online") → It includes an online meeting link; use instead
- Only provides location / meeting room number (e.g., "Hold a meeting in 1605" "Book a meeting room for the meeting") → Does not constitute "clearly an event"; you still need to use text to ask for disambiguation, and cannot skip the question just because a location is provided
- Ambiguous expressions in query scenarios (e.g., "What meetings do I have recently / What meetings are there") → Strictly prohibited from asking for clarification; check both events and meetings and display the merged results; only switch to to check only meetings when the user clearly mentions "online meeting / video meeting / join link / meeting ID / Tencent Meeting / remote attendance"
Routing Rules
| User Intent | Reference Document |
|---|
| Schedule events, arrange in-person face-to-face meetings (without online meeting links), create events | calendar-create |
| View events, "What arrangements do I have today?", check this week's events | calendar-agenda |
| Find a specific event, "When is the project review?" | calendar-search |
| Check event details, view recurrence rules, view meeting links | calendar-agenda |
| Cancel events, "Don't hold it anymore" | calendar-cancel |
| Modify events, update events, change time, add/remove attendees, switch meeting rooms | calendar-update |
| Check availability, "When is someone free?", schedule a common free time slot for multiple people | calendar-freebusy |
| Book meeting rooms, check meeting room availability, check office buildings, schedule meeting rooms | calendar-meeting-room |
Principle for Choosing Browse vs Search: When the user mentions
event subject keywords, use search; when
only time/date is provided without event subject keywords, you must use list browsing (
). Retrieve single event details only when additional information like recurrence rules or meeting links is needed.
Skill Boundary: Event vs Meeting [CRITICAL]
This skill (wecomcli-calendar) is only responsible for Events — non-meeting event arrangements, and in-person face-to-face meetings without online meeting links. Any meeting involving online meeting links (including remote/video attendance) falls under the wecomcli-meeting skill and cannot be created in this skill.
| User Intent | Belonging Skill |
|---|
| Schedule events, arrange in-person face-to-face meetings (without online meeting links), book meeting rooms, view/modify/cancel events, check availability | This skill: wecomcli-calendar |
| Create meetings with online meeting links, meetings requiring meeting IDs or join links, meetings supporting remote/video attendance | wecomcli-meeting skill |
Disambiguation Rules (Creation Scenarios Only): When users only mention phrases like "meeting/hold a meeting/schedule a meeting/arrange a meeting/XX meeting/XX conference" without specifying whether it's an event or a meeting, you must first use text to ask for clarification, then route to the corresponding skill. Do not default to creating an event directly. This text disambiguation only applies to "creation"; strictly prohibit asking for clarification in query scenarios — check only meetings when clearly directed to online meetings, check only events when clearly directed to events/arrangements, and check both events and meetings for ambiguous expressions (e.g., "meeting / XX meeting / What meetings do I have recently") (see "Query Disambiguation" below).
Fixed Question and Options [CRITICAL]: When confirming disambiguation, the question and options must be used exactly as written — the fixed question is
"Do you need to create an event or a meeting?"
, and the fixed options are
/
; do not rephrase the question, add/remove or rephrase options, translate, or design other expressions (e.g., "online meeting / virtual meeting / video meeting / offline meeting").
Ask the user via text:
Do you need to create an event or a meeting? (Please reply: Event / Meeting)
- The words "meeting" / "conference" / "hold a meeting" do not constitute "clarity" [CRITICAL]: These words only indicate the need to meet and discuss, and do not specify whether it's an event or a meeting. Do not default to creating an event in this skill just because the query contains "meeting", nor default to a meeting — as long as it's not clear, always ask for clarification via text first before routing. Only stay in this skill when there are pure offline signals like "meet in person" "create an event".
- If the user replies "Event" → Stay in this skill and create the event following the "Event Scheduling Workflow".
- If the user replies "Meeting" → Switch to
read wecomcli-meeting skill
to create the meeting (creating a meeting will generate a corresponding event simultaneously, no need to create another event in this skill).
- If the user has clearly specified (e.g., "meet in person" "create an event" = event; "send a join link" "need meeting ID" "remote attendance" = meeting) → Route directly without asking for clarification.
- If the meeting supports both in-person and remote attendance (e.g., "Hold offline, remote colleagues join online") → Since it includes an online meeting link, it belongs to the wecomcli-meeting skill: creating a meeting will generate an event simultaneously, no need to create another event in this skill.
- Only provides location/meeting room number (e.g., "Hold a meeting in 1605" "Meet in Building A's meeting room" "Book a meeting room for the meeting") does not constitute "clearly an event" — remote access may still be needed in the meeting room, so it's still unknown whether it's an event or a meeting; you must use text to ask for clarification, and cannot skip the question just because a location is provided.
Must Identify Meeting Association Before Rescheduling / Re-creating Events [CRITICAL]
For rescheduling intentions like "reschedule / change time / move to / postpone / re-schedule" (even if the user says "cancel... then reschedule to..." with "cancel", it counts as rescheduling), do not mechanically split into
+
:
- Locate first, then determine meeting association: Both / returns include the field. After locating the target event, directly check — non-empty means "event in meeting form with online meeting link", empty means pure event; no need to retrieve event details again (only retrieve if additional fields like are needed).
- Pure event → Use the update event intent in this skill's routing table to change the time; do not use cancel + create.
- With meeting link → Switch to
read wecomcli-meeting skill
, pass to to change the time (retain meeting link and attendees), no need to re-search and locate in wecomcli-meeting.
Root Cause:
can only create pure events and cannot re-generate meeting links (can split but not merge). Using cancel + create will permanently lose the meeting link, so rescheduling must always use update.
Core Scenarios
1. Schedule Events
Read calendar-create and execute according to the "Event Scheduling Workflow" (information completion → attendee parsing → time negotiation/availability check → execute creation → result feedback).
2. View/Search Events
| Scenario | Reference Document |
|---|
| General query ("What arrangements do I have today?") | calendar-agenda |
| With keywords ("When is the project review?") | calendar-search |
| Need details (when only is obtained, complete fields) | calendar-agenda |
Browse vs Search: With
event subject keywords → Use search (no need to ask for time);
only time/date provided without subject keywords → Use list browsing (), do not feed the date as
to
. List browsing already returns
, no need to retrieve single event details additionally to determine if it's a recurring event.
Query Disambiguation (Check both events and meetings for ambiguous queries) [REQUIRED]: Strictly prohibit asking the user "Is it an event or a meeting" via text in query scenarios — disambiguation via text only applies to creation; queries must be processed directly according to the following rules without asking for clarification. Judgment is divided into two independent dimensions, do not confuse them:
Dimension 1: Which side to check (Event / Meeting / Both)
- Clearly online meeting → When the user clearly mentions exclusive features of online meetings like "online meeting / video meeting / join link / meeting ID / Tencent Meeting / remote attendance", switch to
read wecomcli-meeting skill
to check only meetings.
- Clearly event / arrangement → When the user clearly mentions event-related content (e.g., "event / arrangement / my arrangements / calendar / What arrangements do I have today" without online meeting features), check only events.
- Ambiguous expression cannot be determined (e.g., "meeting / XX meeting / XX conference / hold a meeting / What meetings do I have recently / What meetings are there / Find XX conference", which could be either an event or a meeting) → Check both events and meetings: Check events, and
read wecomcli-meeting skill
to check meetings.
Dimension 2: Use or for each side (independent of Dimension 1, judge each side separately)
- With subject/name keywords (e.g., "Find XX conference" "When is the project review?") → Use for that side (pass the keywords to ).
- Only time/date or general browsing without keywords (e.g., "What meetings do I have recently" "What arrangements do I have today") → Use for that side; do not feed the date as to .
- Even if "check both sides", choose for each side according to this dimension: use for both sides when keywords are provided, use for both sides when only time/general browsing is provided.
Merged Display: When checking both sides, merge the results and display uniformly — divide into "(Meeting)" (from meeting side, or events with non-empty
) and "(Event)" (pure events with empty
) based on whether they contain online meeting links; deduplicate by "subject + time" if the same meeting appears on both sides, and add a summary at the end "Total N sessions, including X meetings and Y events".
- This disambiguation only applies to queries; creation scenarios still use text to ask for clarification as per "Event vs Meeting" above.
3. Cancel Events
First locate the event (use search when
event subject keywords are provided; use list browsing
when only time/date is provided without subject keywords, do not feed the date as
to
), then determine if it's a recurring event (directly read
returned by the list, no need to retrieve single event details additionally) —
Recurring events are not supported for cancellation, inform the user and guide them to operate in the WeCom client (see "Known Limitations"). For regular events,
do not pre-block cancellation based on "whether created by the user", execute cancellation directly and judge whether it can be cancelled based on the tool's return result (success returns
, permission error returns an error; inform the user and suggest contacting the creator in this case).
If the user's intention is actually "reschedule / move to / postpone" (even with "cancel"), follow the "Must Identify Meeting Association Before Rescheduling / Re-creating Events" above to use the update process. The complete process is shown in
calendar-cancel.
4. Update Events
- First locate the event (use search when event subject keywords are provided; use list browsing when only time/date is provided without subject keywords, do not feed the date as to ), determine if it's a recurring event — Recurring events are not supported for updates, inform the user and guide them to operate in the WeCom client (see "Known Limitations"), do not patch by updating each session individually or change to cancel + create. For regular events, collect the modification content and execute the update; do not pre-block modification based on "whether created by the user", execute the update directly and judge whether it can be modified based on the tool's return result (success returns updated , permission error returns an error; inform the user and suggest contacting the creator in this case).
- Changing time/location, adding/removing attendees, switching meeting rooms all use update, do not cancel and re-create. When switching meeting rooms, first confirm the new meeting room has via , then pass the new to the update (see calendar-meeting-room).
- Updating the time of an event with an online meeting link (non-empty in the location result) is not done in this skill's update, switch to
read wecomcli-meeting skill
instead (see "Must Identify Meeting Association Before Rescheduling / Re-creating Events" above).
- The complete process for updating events is shown in calendar-update.
5. Check Availability / Common Free Time
Query the available free time slots of attendees in the specified period (the server has merged intervals, filtered past times, and recommended according to strategies) for coordinating event times. For details, see calendar-freebusy.
Core Concepts
- Event (Schedule): A single event in the calendar system, including attributes like subject, start/end time, attendees, etc.
- All-day Event: , only occupies by date, and the end date is included in the event.
- Recurring Event:
repeat_rule.is_repeat=true
, occurs repeatedly according to rules.
- Attendee: Identified by (prefix ). When the user provides a name, resolve it to via
read wecomcli-contact skill
.
- FreeBusy: Query whether attendees have event occupancy in the specified period.
- Location: The location of an event is a free text field (). When the user provides a company meeting room as the location, it must be booked via meeting room query () and occupied with (see calendar-meeting-room); do not only write the meeting room name into ; when the user provides a non-meeting room ordinary text location, write it directly into .
- Meeting Room / Building: Physical space resources (unrelated to online meeting links). Use to check accessible office buildings, to check meeting room availability, pass to atomically occupy when creating events, and pass to re-book when updating events. For details, see calendar-meeting-room.
- Timezone: Each event has a ( + ). The / of an event is the wall time in that timezone, and the backend does not perform conversion — the incoming and returned time strings are interpreted according to the event's timezone; do not convert them to UTC+8 or local time on your own.
Core Rules
Rule 1: Obtaining userid [CRITICAL]
- All input parameters for "member userid lists" such as / / / / must be object arrays in the format
[{"userid": "woxxx"}, {"userid": "woyyy"}]
; names or flat string arrays are not accepted.
- (search by organizer) is a single value, pass a userid string (prefix ), not an array.
- When the user provides a name, resolve it to the corresponding userid via
read wecomcli-contact skill
; when there are multiple candidates, list them for the user to choose, do not guess on your own.
- Prohibit using names as userids, prohibit making up userids based on memory or guesses.
- Reason: The calendar API does not support matching attendees by name; passing names will cause silent failures or invitations to the wrong people.
Rule 2: Execute Write Operations Directly
- When creating or canceling events, execute directly once the parameters are ready; no need to display a summary to the user or ask for confirmation.
- Prohibit exposing userid when returning results; only display names.
- Reason: The upper-layer interaction has already fully displayed the operation content and completed confirmation; displaying it again here will cause redundancy.
Rule 3: Must Use Text to Ask for User Interaction [CRITICAL]
During any operation, when necessary parameters are unclear or the user needs to make a choice, you must directly ask the user via text, do not guess on your own or use default values instead of asking. Include the options / candidate values in the text when asking, so that the user can reply directly.
This rule applies to the following situations:
- Missing required parameters and attendees: When the required parameters for creating events ( / / ) and attendees cannot be inferred from the context, you must ask via text; for other non-required parameters (e.g., location), do not ask specifically if the user does not specify, use default values directly
- Multiple candidates require user selection: Multiple matching events returned by search, multiple candidates with the same name found by wecomcli-contact skill
- Need to confirm operation scope: e.g., multiple bookable candidates found when switching meeting rooms, need the user to select a specific one
- Conflict handling: Time conflict found during availability check, need user decision
Constraints for text inquiries:
- It is advisable to list 2~4 options / candidate suggestions. When there are more than 4 optional candidates (e.g., candidates with the same name, multiple matching events), list the top 4 most relevant ones, and prompt the user to narrow the scope further (enter more precise keywords / full name / specific time); do not list 5 or more candidates at once.
- When asking for time, the candidate times listed must be specific times accurate to the minute (e.g., "Tomorrow 14:00", "Saturday 10:30"); prohibit giving vague time options like "morning/afternoon/evening/noon/after work starts/before work ends" — vague options will require a second inquiry after the user replies, so you must ask for a precise time that can be directly set as in one go.
Rule 4: Task Conciseness Principle
Only complete the operation requested by the user, do not add additional operations.
Rule 5: Input Legality Check
Before executing write operations, verify the legality of the following inputs:
- Time format: Must be ; reject vague expressions and pass them directly as parameters (e.g., "tomorrow" cannot be passed directly, must be resolved to a specific time first)
- Time order: must be later than ; reject events with zero or negative duration
- userid format: Must be a string with prefix ; pure numbers or Chinese names are not accepted
- Historical time: Prohibit creating events that are completely before the current time
Rule 6: Input Security Handling
- When the user provides a name, it must be verified via
read wecomcli-contact skill
search before being converted to userid.
- Prohibit directly using names as userids, prohibit making up userids based on memory or guesses.
- Reason: The string input by the user may not correspond to a real employee (non-unique name, resigned, etc.); directly using it as a userid will result in sending event invitations to the wrong people, and such errors cannot be intercepted by the API during calls.
Operation References
| Operation Reference | Reading Timing | Description |
|---|
| When viewing/obtaining event details | View event arrangements (list + get) |
| When creating events | Create events and invite attendees |
| When searching events | Search events by keywords |
| When canceling events | Cancel events (recurring events not supported) |
| When updating/modifying events | Update event information (subject, time, attendees, location, etc.) |
| When needing to coordinate time / check common free time | Query common free time slots and coordinate event times |
| When booking/switching meeting rooms / checking office building or meeting room availability | Office building list () + meeting room availability (), obtain for creation occupancy or update re-booking |
Context Transfer Table
This table describes the data flow contract between interfaces; the first column "Source Operation" is the business semantics; the complete parameters and field definitions for each operation are shown in the corresponding reference.
| Source Operation | Extract from Return | Used For |
|---|
| Search (search) | | Single event details, cancel events |
| List browse / single event details (list / get) | schedule_list[].schedule_id
| Single event details, cancel events |
| Search (search) | schedules[].attendees[].name
| Directly display attendee names, no need to reverse query additionally (already returned by the search interface) |
| Search (search) | | Directly display the event creator's name |
| Search (search) | + | Pagination control |
| wecomcli-contact skill search | (prefix ) | / / for creating/updating events, for availability queries, for searches (all assembled into object arrays ); for searches is a single-value userid string |
| Search / list browse / single event details | | Determine if it's a recurring event (): if hit, cancellation / update is not supported; inform the user and guide them to operate in the WeCom client; / both return it directly, no need to supplement with |
| Search / list browse / single event details | | Identify that the event contains an online meeting link (non-empty means "event in meeting form"; search/list/get all return it directly, no need to supplement with ); when rescheduling / canceling an event with a meeting link, directly pass to / in , no need to re-search and locate in wecomcli-meeting |
| Search / list browse + single event details | Extract from search, schedule_list[].schedule_id
and schedule_list[].repeat_rule
from list/details | Location and recurring event judgment for updating events (if it's a recurring event, update is not supported) |
| Availability query | (including , , ) | Directly display recommended time slots, select the first few for the user to choose; only display names when showing, userid is only passed back to for creating events |
| Meeting room availability query () | target[].room.meeting_room_id
or recommendations[].meeting_room_id
| for creating events (atomically occupy meeting rooms), for updating events (re-book meeting rooms); ID is only circulated in the tool chain, prohibit displaying it, only show the meeting room name to users |
Error Handling
Principle: Tell the user what went wrong + what can be done + alternative solutions. Prohibit silent failures.
| Scenario | Recovery Suggestions |
|---|
| No search results | Provide recovery suggestions via text: 1. Retry with different keywords; 2. Search by organizer (provide name, resolve to userid then pass ); 3. Search by attendees (provide name, resolve to userid then pass ); |
| Multiple candidates in address book | List candidates (name + department) via text for the user to choose |
| No results from wecomcli-contact skill search | Prompt the user to confirm the name via text and wait for re-input |
| Cancel/modify events not created by the user | Do not pre-block, execute the command directly; when a permission error is returned, explain that the current user has no permission to operate, suggest contacting the creator |
| Availability query returns empty | Guide the user to expand the time window or reduce the number of attendees, do not retry repeatedly in the same window |
Availability query degradation (available_count < total_count
) | Inform which people have conflicts and how many can attend, let the user decide whether to arrange according to the degraded time slot or change the time |
Output Quality Standards
Good output should meet the following conditions:
- Event list: Sorted in ascending order of start time, each event is output as an independent entry in order (prohibit markdown tables), each entry only includes subject, time, attendees; only display the first 10 entries if there are more than 10
- Attendee display: Use the field returned by the interface as-is (completely consistent with the format returned by the interface, e.g., display if returned as ), do not display userid
- Operation results: Clearly inform success/failure and reasons, display event summary after successful operation
- Error prompts: Include problem description + recovery suggestions + alternative solutions, do not expose technical error codes
Unacceptable output:
- Directly display userid instead of name
- Silent failure when encountering errors, no prompt to the user
- Display internal schedule_id
Output Format Specifications
Attendee Name Format [REQUIRED]: In all scenarios where attendees are displayed (creation feedback, single event summary, list, etc.), names must
use the field returned by the interface as-is, completely consistent with the format returned by the interface (e.g., display
if returned as
);
in the templates below refers to this original name.
Time Year Display [REQUIRED]: The "Time" line in the templates below omits the year by default, only showing month and day (
in the template refers to
); only add the year before the month and day when the event year is different from the current year (cross-year), in the format
{YYYY}年M月D日 {HH:mm}-{HH:mm}
.
Relative Date Label [REQUIRED]: When the event date is yesterday / today / tomorrow, add a relative term before the month and day in the "Time" line, in the format
{yesterday|today|tomorrow} M月D日 {HH:mm}-{HH:mm}
(e.g.,
Time: Tomorrow June 11 14:00-15:00
); display other dates as
{month-day} {HH:mm}-{HH:mm}
.
Creation Success Feedback [REQUIRED]: After successfully creating an event, the output content only includes three parts: subject, time, attendees; prohibit outputting any other content or additional statements (do not display location, reminder, schedule_id, etc., and do not add explanations, suggestions, or greetings):
Subject: {subject}
Time: {month-day} {HH:mm}-{HH:mm}
Attendees: {name1}, {name2}
Single Event Summary (for viewing/searching single event scenarios, not creation feedback):
Subject: {subject}
Time: {month-day} {HH:mm}-{HH:mm}
Attendees: {name1}, {name2}
Event List Display Specifications [REQUIRED] (applicable to both list and search browsing):
- Prohibit using markdown tables; each event is output as an independent entry in order, sorted in ascending order of start time.
- Each entry only displays three items: subject, time, attendees (do not display location, reminder, schedule_id, etc.).
- Only display the first 10 entries if there are more than 10, and inform at the end "There are N more entries, do you need to view more?".
- Display meetings / events in two separate sections: Judgment is based on whether the event has a meeting link — events with non-empty are classified as "(Meeting)", empty / non-existent are classified as "(Event)" (search/list/get returns all include the field, which can be directly judged). Only when both "(Meeting)" and "(Event)" categories exist in the current results should the results be divided into "(Meeting)" and "(Event)" sections for separate display: list the "(Meeting)" section first, then the "(Event)" section; each section is sorted in ascending order of start time, with each entry only displaying subject/time/attendees; add a summary at the end "Total N sessions, including X meetings and Y events". When the results are of a single category (all meetings or all events), do not divide into sections, do not add "(Meeting)" / "(Event)" titles, display directly as a normal list.
- Sectioned format:
(Meeting)
1. {Subject}
Time: {month-day} {HH:mm}-{HH:mm}
Attendees: {name1}, {name2}
(Event)
1. {Subject}
Time: {month-day} {HH:mm}-{HH:mm}
Attendees: {name1}, {name2}
Timezone Label [REQUIRED]: When the event's
(non-UTC+8), the displayed time must include a timezone label, in the format
{HH:mm}-{HH:mm} ({Chinese region name} UTC±N)
, e.g.,
14:00-15:00 (New York Time UTC-5)
.
- is calculated by .
- The Chinese region name is derived from (e.g., → New York Time); omit the Chinese name if is empty, only keep .
- No label for UTC+8 (, including , , etc.), keep as is.
- Applicable to the "Time" line of single event summaries, event lists, creation/update success feedback; not applicable to in freebusy (displayed in the user's own timezone).
Known Limitations
| Limitation | Alternative Solution |
|---|
| schedules list query window ≤ 30 days before and after | / must fall within the window of "30 days before and after the current time"; the server will not return results if it exceeds this range. When it exceeds, directly inform the user that it is beyond the queryable range and ask them to provide a shorter time range, then call again after the user re-provides it. |
| Does not support creating/updating/canceling recurring events | When users want to create recurring events like "weekly/monthly/daily repeats", or initiate updates/cancellations for events identified as recurring (repeat_rule.is_repeat=true
), directly inform the user that it is not supported currently and guide them to operate manually in the WeCom client; prohibit bypassing it by creating multiple single events, updating each session individually, canceling + re-creating, passing undisclosed parameters, etc. |
| Does not support responding to / rejecting event invitations (RSVP) | This skill does not support accepting / rejecting / tentatively responding to received event invitations (including phrases like "Reject this event" "Will not attend" "Decline the invitation"). When users have this need, inform them that this skill does not support it, suggest operating directly on the event invitation in the WeCom client, or informing the event initiator via message. |
| Availability query limitations | Only recurring events modified in the last two months are viewed; the single query window ≤ 24h, need to split into batches if it exceeds; the part where is earlier than the server's current time will be automatically truncated, passing a pure historical window will return empty |