SuperAPI AI Directory

feishu-cli-calendar

Office & productivity

View repository

Updated 10-16 04:53

About this skill

Feishu Smart Calendar Skill

Intelligently schedule meetings via feishu-cli: automatically find common free time, filter meeting rooms by capacity/floor, accept/decline invitations. AI Agents mainly use this skill for scheduling meetings.

Basic Calendar CRUD(list/get/primary/create-event/list-events/update-event/delete-event/agenda/event-search/event-reply/attendee/freebusy) please refer to feishu-cli-toolkit Section 2 "Calendar and Events". This skill focuses on the three new smart subcommands added in v1.18+.

Core Concepts

Positioning of the Trio

Subcommand What It Solves When to Use
suggestion Recommend common free time slots for a group of participants First step in scheduling a meeting: set the time
room-find Find available meeting rooms for a given time slot Second step in scheduling a meeting: set the location
rsvp Accept/decline/tentatively accept received invitations Invitee handles invitations

Typical combination: first suggestion get recommended time slots → room-find filter meeting rooms for that time slot → calendar create-event create the event and invite participants and meeting rooms.

Underlying Implementation & Retries

  • Direct calls to OpenAPI /open-apis/calendar/v4/freebusy/suggestion and .../freebusy/room_find, SDK v3.5.3 does not expose these two methods.
  • room-find built-in DoWithRetry(MaxRetries=3 / MaxTotalAttempts=8 / RetryOnRateLimit=true)——429 rate limiting does not count toward failure attempts, full-jitter backoff, cap 30s.
  • room-find Multi-slot batching uses concurrent calls (default 10 workers), 429 is retried by each goroutine individually, no user-level backoff needed.
  • suggestion currentlydoes not have DoWithRetry attached(single call), if running frequently in manual scripts please sleep 1-2s yourself.

Identity Selection

Command Token Behavior
suggestion / room-find User Token preferred + App Token fallback: when already auth login use User Token (check private busy/free), if not logged in fall back to App Token (check public busy/free, company-bookable meeting rooms).--user-access-token can be explicitly specified.
rsvp User Token required(reply to invitations as yourself), if not logged in an error is reported directly.

Permissions:calendar:calendar.free_busy:read(suggestion / room-find)、calendar:calendar.event:reply(rsvp)。

calendar rsvp supports --action, also supports the official lark-cli compatible alias --rsvp-status, the two are equivalent and different values cannot be specified at the same time.

Subcommand Quick Reference

1. calendar suggestion (find common free time)

feishu-cli calendar suggestion \
  --attendee-ids ou_aaa,ou_bbb,oc_groupid \
  --duration 30m \
  [--start 2024-01-22T09:00:00+08:00] \
  [--end   2024-01-22T18:00:00+08:00] \
  [--timezone Asia/Shanghai] \
  [--event-rrule "FREQ=WEEKLY;COUNT=4"] \
  [--exclude 2024-01-22T12:00:00+08:00~2024-01-22T13:00:00+08:00] \
  [-o json]
Parameter Description Default Value
--attendee-ids(required) List of participant IDs, comma-separated,ou_xxx(user) + oc_xxx(group chat) mixed —
--duration(required) Meeting duration,30m / 1h30m / 90(plain number is in minutes), range 1-1440 —
--start Search start (RFC3339) Current time
--end Search end (RFC3339) start 23:59:59 of the same day
--timezone Time zone, e.g. Asia/Shanghai —
--event-rrule Recurrence rule rrule string (find common free time for recurring meetings) —
--exclude Exclude time slots, multiple slots separated by commas, single slot start~end RFC3339 —
-o Output format:json for AI parsing / empty for human viewing empty

Returns: recommended time slot list + ai_action_guidance(human-readable suggestions provided by the server).

Output example (text)

推荐时段(共 3 个):

[1] 2024-01-22T09:00:00+08:00 ~ 2024-01-22T09:30:00+08:00
    理由: 全员有空
[2] 2024-01-22T10:00:00+08:00 ~ 2024-01-22T10:30:00+08:00
    理由: 全员有空
[3] 2024-01-22T14:00:00+08:00 ~ 2024-01-22T14:30:00+08:00
    理由: 全员有空

建议: 推荐选择上午 09:00,所有人精力较好。

2. calendar room-find (find meeting rooms)

feishu-cli calendar room-find \
  --slot 2024-01-22T09:00:00+08:00~2024-01-22T10:00:00+08:00 \
  [--slot 2024-01-22T14:00:00+08:00~2024-01-22T15:00:00+08:00] \
  [--attendee-ids ou_aaa,ou_bbb] \
  [--city "北京" --building "飞书大厦" --floor F2] \
  [--room-name "01,02,03"] \
  [--min-capacity 6 --max-capacity 20] \
  [--timezone Asia/Shanghai] \
  [-o json]
Parameter Description Default value
--slot(required) Time slot to query start~end(RFC3339); can be passed repeatedly or multiple slots separated by commas —
--attendee-ids Participant ID (ou_xxx/oc_xxx), used to recommend meeting rooms close to participants —
--city City constraint —
--building Building constraint —
--floor Floor constraint (e.g., F2) —
--room-name Meeting room name constraint, multiple separated by commas —
--min-capacity / --max-capacity Capacity range (≥0, min ≤ max) 0 (unlimited)
--timezone Time zone —
--event-rrule Recurrence rule rrule —

Returns: list of available meeting rooms aggregated by time slot, including room_id/room_name/capacity/reserve_until_time. For multiple slots, queries are concurrent (10 workers); if any time slot fails, the first error is returned immediately.

Output example (text)

2024-01-22T09:00:00+08:00 ~ 2024-01-22T10:00:00+08:00
  [1] 飞书大厦-F2-01 (id=omm_xxx, capacity=8)
      可预订至: 2024-01-22T10:00:00+08:00
  [2] 飞书大厦-F2-02 (id=omm_yyy, capacity=12)

2024-01-22T14:00:00+08:00 ~ 2024-01-22T15:00:00+08:00
  (无可用会议室)

3. calendar rsvp (reply to invitation)

feishu-cli calendar rsvp \
  --event-id <EVENT_ID> \
  --action accept | decline | tentative \
  [--calendar-id <CAL_ID>] \
  [--user-access-token <TOKEN>]
Parameter Description Default value
--event-id(required) Event ID —
--action(required) accept / decline / tentative —
--calendar-id Calendar ID Primary calendar (automatically calls calendar primary)
--user-access-token User Token, replies as yourself Required (requireUserToken), errors out directly if not logged in

and calendar event-reply difference:

Dimension rsvp(new) event-reply(old)
Parameter style All flags (--event-id/--action) Positional parameter <calendar_id> <event_id> + --status
calendar-id Can be omitted (defaults to primary calendar) Required
Applicable AI Agent scheduling Humans typing commands directly

Typical workflow

Workflow A: AI Agent schedules a meeting (end-to-end)

# 1. 找共同空闲(30 分钟,明早 9-12 点)
feishu-cli calendar suggestion \
  --attendee-ids ou_alice,ou_bob,ou_carol \
  --duration 30m \
  --start 2024-01-22T09:00:00+08:00 \
  --end   2024-01-22T12:00:00+08:00 \
  -o json | jq '.suggestions[0]'
# 假设拿到 09:30-10:00

# 2. 在该时段找会议室(6-12 人,F2 楼)
feishu-cli calendar room-find \
  --slot 2024-01-22T09:30:00+08:00~2024-01-22T10:00:00+08:00 \
  --floor F2 --min-capacity 6 --max-capacity 12 \
  -o json | jq '.time_slots[0].meeting_rooms[0]'
# 假设拿到 room_id=omm_xxx

# 3. 创建日程并邀请参与人 + 会议室(走 toolkit)
feishu-cli calendar create-event \
  --calendar-id <主日历> \
  --summary "三方对齐" \
  --start 2024-01-22T09:30:00+08:00 \
  --end   2024-01-22T10:00:00+08:00
# 后续 attendee add 把人和 room 加进去

Workflow B: Batch reply to invitations

# 列出待答复的邀请(走 toolkit calendar agenda + jq 过滤 status=needs_action)
feishu-cli calendar agenda --start-date 2024-01-22 --end-date 2024-01-23 -o json \
  | jq -r '.events[] | select(.status=="needs_action") | "\(.event_id)"' \
  | while read eid; do
      feishu-cli calendar rsvp --event-id "$eid" --action accept --user-access-token <TOKEN>
    done

Key flag quick reference

Scenario Key flag Notes
Time slot format start~end(RFC3339) --slot and --exclude both use ~ as separator,not --
Multiple time slots --slot a~b --slot c~d or --slot a~b,c~d Both StringSlice syntaxes are supported
Two ways to write duration --duration 30m or --duration 30 Pure number = minutes; range 1-1440
AI parsing -o json Both suggestion / room-find support it; rsvp only has text output
Don't know calendar-id rsvp omits --calendar-id Automatically uses primary calendar

Pitfalls (must read)

1. ID prefix must be ou_ / oc_

--attendee-ids internally goes through SplitAttendeeIDs(raw) splits by prefix:

  • ou_xxx → attendee_user_ids
  • oc_xxx → attendee_chat_ids
  • Other prefixes (omm_/room_/app_ meeting room or resource token) → stderr logs warn thenskip, does not block batch
  • Duplicate IDs are automatically deduplicated

So: copied from Feishu user_id(plain string without prefix)/union_id(on_xxx)/email will all be skipped if fed directly; you must first use feishu-cli user get or contact:user.base:readonly API to convert to ou_xxx。

2. Frequent 429s are the norm; rely on DoWithRetry

freebusy/room_find has a high 429 hit rate in batch concurrency scenarios (measured: 10 workers running 6 slots often triggers 2-3 times). The CLI has built-in RetryOnRateLimit=true——do not stack retry at the user layer, it will hit the MaxTotalAttempts=8 limit and fail early. If running large batches requires more aggressive concurrency, adjust the roomFindWorkers constant and recompile a version.

suggestion has no retry attached yet; before calling in a loop, do your own sleep 1。

3. duration unit pitfall

  • --duration 30 = 30 minutes(not seconds, not hours)
  • --duration 30m = 30 minutes
  • --duration 1h30m = 90 minutes
  • --duration 1.5h = error(time.ParseDuration does not accept decimal hours, write 1h30m)
  • range 1-1440; anything over 24 hours errors out directly

4. start/end default values are easy to trip on

  • --start defaults = current time (not 00:00 of the day)
  • --end defaults = start 23:59:59 of the same day (note it is the same day; crossing days requires explicitly passing --end)
  • To find "all day tomorrow" → you must pass both

5. rsvp makes an extra API call when there is no calendar-id

Omitting --calendar-id will first call calendar primary to get the primary calendar and then call reply, adding one extra RTT. In batch reply scripts it is recommended to first feishu-cli calendar primary -o json cache the ID and then pass it to each rsvp。

6. rsvp action has only three enums

accept / decline / tentative, any other string directly 400. Common typos:accpet / declined / maybe。

7. exclude / slot time direction

start~end in end must bestrictly later than start, equality also errors. Crossing days requires the correct timezone; do not directly pass T00:00:00Z followed by +08:00 mixed together, inconsistent timezones will parse and compare chaotically.

When to switch to other skills

Requirement switch to
create/modify/delete schedules, list schedule agenda, event-search feishu-cli-toolkit Section 2 "Calendar and Schedules"
Plain freebusy query for a single person/single time slot (no smart recommendation) feishu-cli-toolkit Section 2 "Free/Busy Query"
add/remove attendee, query attendee list feishu-cli-toolkit Section 2 "Attendee Management"
event-reply old API (positional-argument version) feishu-cli-toolkit Section 2
send meeting reminder messages to attendees feishu-cli-msg + feishu-cli-card
get ou_xxx open_id (email/user_id → open_id conversion) feishu-cli-toolkit Contacts section / lark-cli contact +search-user

Permission Quick Reference

Command scope Token Recommendation
suggestion calendar:calendar.free_busy:read User Token preferred + App Token fallback
room-find calendar:calendar.free_busy:read User Token preferred + App Token fallback
rsvp calendar:calendar.event:reply User Token required(reply as yourself)

Precheck:

feishu-cli auth check --scope "calendar:calendar.free_busy:read calendar:calendar.event:reply"