Microsoft Graph Calendar — Find Free Slots
Use this skill when the user wants to:
- - Find a time when multiple employees are all free
- Check if a specific person is available at a given time
- List upcoming meetings / busy blocks for one or more people
- Suggest meeting slots across the company
Setup (ทำครั้งแรกครั้งเดียว)
ถ้าผู้ใช้ยังไม่เคย setup หรือระบบแจ้งว่าขาด credentials ให้ทำดังนี้:
- 1. ถามผู้ใช้ 3 ค่านี้ทีละค่า:
- AZURE
TENANTID (Azure Portal → Azure Active Directory → Overview)
- AZURE
CLIENTID (App registrations → your app → Application (client) ID)
- AZURE
CLIENTSECRET (App registrations → your app → Certificates & secrets)
- 2. เมื่อได้ครบแล้ว รันคำสั่ง:
CODEBLOCK0
ค่าจะถูกบันทึกไว้ที่ ~/.openclaw/ms-graph-calendar.json (permission 600) และจะถูกโหลดอัตโนมัติทุกครั้งที่ใช้ skill
- 3. ทดสอบด้วย:
node skills/ms-graph-calendar/scripts/get-token.js
ถ้าได้ "✅ Token acquired" แปลว่าพร้อมใช้งานแล้ว
App Registration ต้องมี Application Permissions:
- -
Calendars.Read — read all users' calendars - INLINECODE2 — list employees
- Admin ต้อง Grant consent ก่อน
Configuration
Authentication is cached after first login. No environment variables required for device code flow.
For headless/automated operation, set these environment variables:
- - AZURECLIENTID - Azure AD app client ID
- AZURECLIENTSECRET - Azure AD app secret
- AZURETENANTID - Tenant ID (use "consumers" for personal accounts)
Tools
This skill runs Node.js scripts via bash. Files:
- -
scripts/ — Node.js scripts - INLINECODE4 — ตาราง mapping ชื่อเล่น → email (แก้ไขได้เลย)
Instructions
Step 1 — Get Access Token
Before any Graph API call, get an app-only token:
node skills/ms-graph-calendar/scripts/get-token.js
Store the token in a temp variable for subsequent calls.
Step 2 — Parse the User's Request
Extract from the user's message:
- - Who: names or emails of attendees (e.g. "Alice and Bob", "the marketing team")
- When: date range to search (e.g. "this week", "next Monday", "March 5–7")
- Duration: how long the meeting should be (default 60 minutes)
- Timezone: default to
Asia/Bangkok if not specified
If any info is missing, ask the user before proceeding.
Step 3 — Resolve Employee Emails
3a. ลองแปลงชื่อเล่นก่อน (เร็วกว่า ไม่ต้องเรียก API):
node skills/ms-graph-calendar/scripts/resolve-nicknames.js --names "แบงค์,มิ้ว,โบ้"
อ่านจาก
nicknames.md ในโฟลเดอร์ skill — แก้ไขได้ตรงนั้นเลย
3b. ถ้าหาไม่เจอใน nicknames.md ให้ fallback ไปค้น Graph API:
node skills/ms-graph-calendar/scripts/list-users.js --search "ชื่อ"
Confirm กับ user ถ้ามีคนชื่อเดียวกันหลายคน
Step 4 — Find Free Slots (choose one method)
Method A — findMeetingTimes (best for small groups, ≤10 people):
CODEBLOCK5
Method B — getSchedule (best for large groups or viewing free/busy blocks):
CODEBLOCK6
Step 5 — Present Results
Format the available slots clearly:
CODEBLOCK7
If no slots are found, widen the search window and try again, or report that no common availability exists in that period.
Example Conversations
User: "Find a 1-hour slot this week where Alice, Bob, and Carol are all free"
Agent:
- 1. Resolves emails for Alice, Bob, Carol
- Runs
find-meeting-times.js with date range = this Mon–Fri - Returns top 3 available slots
User: "Is John free tomorrow afternoon?"
Agent:
- 1. Resolves John's email
- Runs
get-schedule.js for tomorrow 12:00–18:00 - Reports free/busy blocks
User: "Show me everyone in the marketing team's availability next week"
Agent:
- 1. Lists users in the Marketing group via INLINECODE9
- Runs
get-schedule.js for all their emails - Presents a visual free/busy summary
Error Handling
| Error | Cause | Fix |
|---|
| INLINECODE11 | Token expired or wrong credentials | Re-run get-token.js, check env vars |
| INLINECODE13 |
Missing Admin Consent | Ask IT admin to grant consent in Azure Portal |
|
404 Not Found | User email doesn't exist | Verify email via
list-users.js |
| No slots found | Everyone is busy | Widen time range or reduce attendees |
Security Notes
- - Credentials are read from env vars only — never log or echo them
- This skill has read-only access to calendars (
Calendars.Read) - It cannot create, edit, or delete any events
- To restrict which mailboxes the app can read, ask your IT admin to set an App Access Policy in Exchange Online:
CODEBLOCK8
Microsoft Graph Calendar — 查找空闲时段
当用户想要执行以下操作时,请使用此技能:
- - 查找多位员工同时空闲的时间
- 检查特定人员在指定时间是否有空
- 列出一人或多人即将召开的会议/忙碌时段
- 建议公司范围内的会议时段
设置(首次一次性操作)
如果用户尚未设置,或系统提示缺少凭据,请按以下步骤操作:
- 1. 逐一询问用户以下3个值:
- AZURE
TENANTID(Azure门户 → Azure Active Directory → 概述)
- AZURE
CLIENTID(应用注册 → 你的应用 → 应用程序(客户端)ID)
- AZURE
CLIENTSECRET(应用注册 → 你的应用 → 证书和机密)
- 2. 获取完整信息后,运行以下命令:
bash
node skills/ms-graph-calendar/scripts/setup.js \
--tenant-id
TENANTID> \
--client-id CLIENTID> \
--client-secret CLIENTSECRET>
这些值将保存在 ~/.openclaw/ms-graph-calendar.json(权限600),每次使用此技能时会自动加载。
- 3. 使用以下命令进行测试:
bash
node skills/ms-graph-calendar/scripts/get-token.js
如果显示✅ Token acquired,则表示已准备就绪。
应用注册必须具有以下应用程序权限:
- - Calendars.Read — 读取所有用户的日历
- User.Read.All — 列出员工
- 管理员必须事先授予同意
配置
首次登录后,身份验证将被缓存。设备代码流程无需环境变量。
对于无头/自动化操作,请设置以下环境变量:
- - AZURECLIENTID - Azure AD 应用客户端 ID
- AZURECLIENTSECRET - Azure AD 应用机密
- AZURETENANTID - 租户 ID(个人账户使用consumers)
工具
此技能通过 bash 运行 Node.js 脚本。文件:
- - scripts/ — Node.js 脚本
- nicknames.md — 昵称 → 邮箱映射表(可直接编辑)
操作说明
步骤 1 — 获取访问令牌
在进行任何 Graph API 调用之前,先获取仅限应用的令牌:
bash
node skills/ms-graph-calendar/scripts/get-token.js
将令牌存储在临时变量中,供后续调用使用。
步骤 2 — 解析用户请求
从用户消息中提取以下信息:
- - 谁:参与者的姓名或邮箱(例如Alice 和 Bob、市场团队)
- 何时:搜索的日期范围(例如本周、下周一、3月5日至7日)
- 时长:会议应持续多长时间(默认60分钟)
- 时区:如未指定,默认为 Asia/Bangkok
如果缺少任何信息,请先询问用户再继续操作。
步骤 3 — 解析员工邮箱
3a. 先尝试转换昵称(更快,无需调用 API):
bash
node skills/ms-graph-calendar/scripts/resolve-nicknames.js --names Bank,Miu,Bo
从技能文件夹中的 nicknames.md 读取 — 可直接在此处编辑。
3b. 如果在 nicknames.md 中找不到,则回退到搜索 Graph API:
bash
node skills/ms-graph-calendar/scripts/list-users.js --search 姓名
如果有多人同名,请与用户确认。
步骤 4 — 查找空闲时段(选择一种方法)
方法 A — findMeetingTimes(最适合小团体,≤10人):
bash
node skills/ms-graph-calendar/scripts/find-meeting-times.js \
--attendees alice@company.com,bob@company.com \
--start 2025-03-01T08:00:00 \
--end 2025-03-01T18:00:00 \
--duration 60 \
--timezone Asia/Bangkok \
--max 5
方法 B — getSchedule(最适合大团体或查看空闲/忙碌时段):
bash
node skills/ms-graph-calendar/scripts/get-schedule.js \
--emails alice@company.com,bob@company.com,carol@company.com \
--start 2025-03-01T00:00:00 \
--end 2025-03-07T00:00:00 \
--timezone Asia/Bangkok \
--interval 30
步骤 5 — 呈现结果
清晰地格式化可用时段:
📅 所有人都空闲的可用时段:
- 1. 周一 3月3日 · 10:00–11:00
- 周二 3月4日 · 14:00–15:00
- 周三 3月5日 · 09:00–10:00
哪个时段最合适?
如果未找到任何时段,请扩大搜索范围并重试,或报告该时间段内没有共同空闲时间。
示例对话
用户:查找本周 Alice、Bob 和 Carol 都有空的1小时时段
助手:
- 1. 解析 Alice、Bob、Carol 的邮箱
- 使用日期范围 = 本周一至周五运行 find-meeting-times.js
- 返回前3个可用时段
用户:John 明天下午有空吗?
助手:
- 1. 解析 John 的邮箱
- 为明天12:00–18:00运行 get-schedule.js
- 报告空闲/忙碌时段
用户:显示市场团队所有人下周的空闲情况
助手:
- 1. 通过 list-users.js --group Marketing 列出市场组的用户
- 为所有邮箱运行 get-schedule.js
- 呈现可视化的空闲/忙碌摘要
错误处理
| 错误 | 原因 | 解决方法 |
|---|
| 401 未授权 | 令牌过期或凭据错误 | 重新运行 get-token.js,检查环境变量 |
| 403 禁止访问 |
缺少管理员同意 | 请 IT 管理员在 Azure 门户中授予同意 |
| 404 未找到 | 用户邮箱不存在 | 通过 list-users.js 验证邮箱 |
| 未找到时段 | 所有人都在忙 | 扩大时间范围或减少参与者 |
安全说明
- - 凭据仅从环境变量读取 — 切勿记录或回显
- 此技能对日历具有只读访问权限(Calendars.Read)
- 无法创建、编辑或删除任何事件
- 要限制应用可以读取的邮箱,请让 IT 管理员在 Exchange Online 中设置应用访问策略:
powershell
New-ApplicationAccessPolicy -AppId -PolicyScopeGroupId -AccessRight RestrictAccess