Zoho Calendar技能使用说明
Zoho Calendar
通过托管的OAuth认证访问Zoho Calendar API。管理日历和事件,支持完整的CRUD操作,包括周期性事件和参与者管理。
快速开始
# 列出日历
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/zoho-calendar/api/v1/calendars')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
基础URL
https://gateway.maton.ai/zoho-calendar/api/v1/{endpoint}
网关将请求代理到calendar.zoho.com/api/v1并自动注入您的OAuth令牌。
认证
所有请求都要求在Authorization头部中包含Maton API密钥:
Authorization: Bearer $MATON_API_KEY
环境变量:将您的API密钥设置为MATON_API_KEY:
export MATON_API_KEY="YOUR_API_KEY"
获取您的API密钥
- 请登录或前往maton.ai
- 前往maton.ai/settings
- 复制您的 API 密钥
连接管理
在以下地址管理您的 Zoho Calendar OAuth 连接:https://ctrl.maton.ai。
列出连接
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections?app=zoho-calendar&status=ACTIVE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
创建连接
python <<'EOF'
import urllib.request, os, json
data = json.dumps({'app': 'zoho-calendar'}).encode()
req = urllib.request.Request('https://ctrl.maton.ai/connections', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
获取连接
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
响应:
{
"connection": {
"connection_id": "21fd90f9-5935-43cd-b6c8-bde9d915ca80",
"status": "ACTIVE",
"creation_time": "2025-12-08T07:20:53.488460Z",
"last_updated_time": "2026-01-31T20:03:32.593153Z",
"url": "https://connect.maton.ai/?session_token=...",
"app": "zoho-calendar",
"metadata": {}
}
}
在浏览器中打开返回的url以完成 OAuth 授权。
删除连接
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}', method='DELETE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
指定连接
如果您有多个 Zoho Calendar 连接,请使用Maton-Connection请求头来指定要使用哪一个:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/zoho-calendar/api/v1/calendars')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Maton-Connection', '21fd90f9-5935-43cd-b6c8-bde9d915ca80')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
如果省略此请求头,网关将使用默认(最早创建的)活跃连接。
API 参考
日历
列出日历
GET /zoho-calendar/api/v1/calendars
示例:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/zoho-calendar/api/v1/calendars')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
响应:
{
"calendars": [
{
"uid": "fda9b0b4ad834257b622cb3dc3555727",
"name": "我的日历",
"color": "#8cbf40",
"textcolor": "#FFFFFF",
"timezone": "PST",
"isdefault": true,
"category": "own",
"privilege": "owner"
}
]
}
获取日历详情
GET /zoho-calendar/api/v1/calendars/{calendar_uid}
示例:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/zoho-calendar/api/v1/calendars/fda9b0b4ad834257b622cb3dc3555727')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
创建日历
POST /zoho-calendar/api/v1/calendars?calendarData={json}
必填字段:
- 名称- 日历名称(最多50个字符)
- 颜色- 十六进制颜色代码(例如:#FF5733)
可选字段:
- 文本颜色- 文本颜色十六进制代码
- 描述- 日历描述(最多1000个字符)
- 时区- 日历时区
- 包含在空闲/忙碌显示中- 显示为忙碌/空闲(布尔值)
- 公开- 可见性级别(禁用,freebusy, 或查看)
示例:
python <<'EOF'
import urllib.request, os, json, urllib.parse
calendarData = {
"name": "工作日历",
"color": "#FF5733",
"textcolor": "#FFFFFF",
"description": "我的工作日历"
}
url = f'https://gateway.maton.ai/zoho-calendar/api/v1/calendars?calendarData={urllib.parse.quote(json.dumps(calendarData))}'
req = urllib.request.Request(url, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
响应:
{
"calendars": [
{
"uid": "86fb9745076e4672ae4324f05e1f5393",
"name": "工作日历",
"color": "#FF5733",
"textcolor": "#FFFFFF"
}
]
}
删除日历
DELETE /zoho-calendar/api/v1/calendars/{calendar_uid}
示例:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/zoho-calendar/api/v1/calendars/86fb9745076e4672ae4324f05e1f5393', method='DELETE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
响应:
{
"calendars": [
{
"uid": "86fb9745076e4672ae4324f05e1f5393",
"calstatus": "已删除"
}
]
}
事件
列出事件
GET /zoho-calendar/api/v1/calendars/{calendar_uid}/events?range={json}
查询参数:
| 参数 | 类型 | 描述 |
|---|---|---|
| 范围 | JSON对象 | 必需。格式为{"start":"yyyyMMdd","end":"yyyyMMdd"}的开始和结束日期。最大跨度为31天。 |
| 按实例 | 布尔值 | 如果为true,则单独返回重复事件的实例 |
| 时区 | 字符串 | 日期时间值的时区 |
示例:
python <<'EOF'
import urllib.request, os, json, urllib.parse
from datetime import datetime, timedelta
today = datetime.now()
end_date = today + timedelta(days=7)
range_param = json.dumps({
"start": today.strftime("%Y%m%d"),
"end": end_date.strftime("%Y%m%d")
})
url = f'https://gateway.maton.ai/zoho-calendar/api/v1/calendars/fda9b0b4ad834257b622cb3dc3555727/events?range={urllib.parse.quote(range_param)}'
req = urllib.request.Request(url)
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
响应:
{
"events": [
{
"uid": "c63e8b9fcb3e48c2a00b16729932d636@zoho.com",
"title": "团队会议",
"dateandtime": {
"timezone": "America/Los_Angeles",
"start": "20260206T100000-0800",
"end": "20260206T110000-0800"
},
"isallday": false,
"etag": "1770368451507",
"organizer": "user@example.com"
}
]
}
获取事件详情
GET /zoho-calendar/api/v1/calendars/{calendar_uid}/events/{event_uid}
示例:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/zoho-calendar/api/v1/calendars/fda9b0b4ad834257b622cb3dc3555727/events/c63e8b9fcb3e48c2a00b16729932d636@zoho.com')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
创建事件
POST /zoho-calendar/api/v1/calendars/{calendar_uid}/events?eventdata={json}
必需字段(在 eventdata 中):
-
日期与时间- 一个对象,包含开始时间、结束时间,以及可选的时区
- 格式:yyyyMMdd'T'HHmmss'Z'(格林尼治标准时间)用于定时事件
- 格式:yyyyMMdd用于全天事件
可选字段:
- 标题- 事件名称
- 描述- 活动详情(最多10,000个字符)
- 地点- 活动地点(最多255个字符)
- 全天事件- 用于全天事件的布尔值
- 私密性- 用于向非代表隐藏详情的布尔值
- 颜色- 十六进制颜色代码
- 参与者- 参与者对象数组
- 提醒- 提醒对象数组
- 重复规则- 重复规则字符串(例如,FREQ=DAILY;COUNT=5)
示例:
python <<'EOF'
import urllib.request, os, json, urllib.parse
from datetime import datetime, timedelta
start_time = datetime.utcnow() + timedelta(hours=1)
end_time = start_time + timedelta(hours=1)
eventdata = {
"title": "团队会议",
"dateandtime": {
"timezone": "America/Los_Angeles",
"start": start_time.strftime("%Y%m%dT%H%M%SZ"),
"end": end_time.strftime("%Y%m%dT%H%M%SZ")
},
"description": "每周团队同步会议",
"location": "会议室A"
}
url = f'https://gateway.maton.ai/zoho-calendar/api/v1/calendars/fda9b0b4ad834257b622cb3dc3555727/events?eventdata={urllib.parse.quote(json.dumps(eventdata))}'
req = urllib.request.Request(url, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
响应:
{
"events": [
{
"uid": "c63e8b9fcb3e48c2a00b16729932d636@zoho.com",
"title": "团队会议",
"dateandtime": {
"timezone": "America/Los_Angeles",
"start": "20260206T100000-0800",
"end": "20260206T110000-0800"
},
"etag": "1770368451507",
"estatus": "added"
}
]
}
更新事件
PUT /zoho-calendar/api/v1/calendars/{calendar_uid}/events/{event_uid}?eventdata={json}
必填字段:
- dateandtime- 开始和结束时间
- etag- 当前的 etag 值(来自“获取事件详情”)
可选字段:与创建事件相同
示例:
python <<'EOF'
import urllib.request, os, json, urllib.parse
from datetime import datetime, timedelta
start_time = datetime.utcnow() + timedelta(hours=2)
end_time = start_time + timedelta(hours=1)
eventdata = {
"title": "更新的团队会议",
"dateandtime": {
"timezone": "America/Los_Angeles",
"start": start_time.strftime("%Y%m%dT%H%M%SZ"),
"end": end_time.strftime("%Y%m%dT%H%M%SZ")
},
"etag": 1770368451507
}
url = f'https://gateway.maton.ai/zoho-calendar/api/v1/calendars/fda9b0b4ad834257b622cb3dc3555727/events/c63e8b9fcb3e48c2a00b16729932d636@zoho.com?eventdata={urllib.parse.quote(json.dumps(eventdata))}'
req = urllib.request.Request(url, method='PUT')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
删除事件
DELETE /zoho-calendar/api/v1/calendars/{calendar_uid}/events/{event_uid}
必需请求头:
- etag- 事件的当前etag值
示例:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/zoho-calendar/api/v1/calendars/fda9b0b4ad834257b622cb3dc3555727/events/c63e8b9fcb3e48c2a00b16729932d636@zoho.com', method='DELETE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('etag', '1770368451507')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
响应:
{
"events": [
{
"uid": "c63e8b9fcb3e48c2a00b16729932d636@zoho.com",
"estatus": "deleted",
"caluid": "fda9b0b4ad834257b622cb3dc3555727"
}
]
}
参与者
创建或更新事件时,包含参与者:
{
"attendees": [
{
"email": "user@example.com",
"permission": 1,
"attendance": 1
}
]
}
权限等级:0(访客),1(查看),2(邀请),3(编辑)参与状态:0(非参与者),1(必需),2(可选)
提醒
{
"reminders": [
{
"action": "popup",
"minutes": 30
},
{
"action": "email",
"minutes": 60
}
]
}
操作类型: 电子邮件,弹窗,通知
周期性事件
使用rrule字段,并遵循 iCalendar RRULE 格式:
{
"rrule": "FREQ=DAILY;COUNT=5;INTERVAL=1"
}
示例:
- 连续5天,每天一次:FREQ=DAILY;COUNT=5;INTERVAL=1
- 每周一和周二:FREQ=WEEKLY;INTERVAL=1;BYDAY=MO,TU;UNTIL=20250817T064600Z
- 每月最后一个周二:FREQ=MONTHLY;INTERVAL=1;BYDAY=TU;BYSETPOS=-1;COUNT=2
代码示例
JavaScript
const response = await fetch(
'https://gateway.maton.ai/zoho-calendar/api/v1/calendars',
{
headers: {
'Authorization': `Bearer ${process.env.MATON_API_KEY}`
}
}
);
const data = await response.json();
Python
import os
import requests
response = requests.get(
'https://gateway.maton.ai/zoho-calendar/api/v1/calendars',
headers={'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'}
)
data = response.json()
备注
- 事件和日历数据以 JSON 格式通过eventdata或calendarData查询参数传递
- 事件日期/时间格式:yyyyMMdd'T'HHmmss'Z'(格林威治标准时间)或yyyyMMdd适用于全天事件
- 列出事件的时间范围参数不得超过31天
- 执行更新和删除操作时,etag是必需的——在修改前务必获取最新的etag
- 对于删除操作,etag必须作为请求头传递,而非查询参数
- 重要提示:使用curl命令时,若URL包含方括号,请使用curl -g以禁用通配符解析
- 重要提示:将curl输出通过管道传递给jq或其他命令时,某些Shell环境中$MATON_API_KEY等环境变量可能无法正确展开
错误处理
| 状态码 | 含义 |
|---|---|
| 400 | 缺少Zoho Calendar连接、缺少必需参数或请求无效 |
| 401 | Maton API密钥无效或缺失,或OAuth范围不匹配 |
| 404 | 未找到资源 |
| 429 | 请求频率受限 |
| 4xx/5xx | 来自Zoho Calendar API的透传错误 |
常见错误
| 错误 | 描述 |
|---|---|
| ETAG_MISSING | 删除操作需要 etag 请求头 |
| EXTRA_PARAM_FOUND | 请求中包含无效参数 |
| INVALID_DATA | 请求数据格式错误 |
故障排除:API 密钥问题
- 请检查MATON_API_KEY环境变量是否已设置:
echo $MATON_API_KEY
- 通过列出连接来验证 API 密钥是否有效:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
故障排除:无效的应用名称
- 请确保您的 URL 路径以zoho-calendar开头。例如:
- 正确示例:https://gateway.maton.ai/zoho-calendar/api/v1/calendars
- 错误示例:https://gateway.maton.ai/api/v1/calendars


微信扫一扫,打赏作者吧~