Calendar Bridge Skill
Use this skill to interact with the Calendar Bridge service — a local REST API that wraps Google Calendar OAuth with persistent token storage and auto-refresh.
GitHub: https://github.com/DanielKillenberger/gcal-oauth-bridge
What is Calendar Bridge?
A tiny Node.js/Express service running at http://localhost:3000 that:
- - Handles Google Calendar OAuth once via browser
- Stores and auto-refreshes tokens (solves the "token expired every 7 days" problem)
- Exposes a dead-simple REST API for events, calendars, and auth
API Endpoints
| Endpoint | Description |
|---|
| INLINECODE1 | Service status + auth state |
| INLINECODE2 |
Get OAuth consent URL |
|
GET /events?days=7 | Upcoming events from primary calendar |
|
GET /events?days=7&calendar=all | Events from ALL calendars |
|
GET /events?days=7&calendar=<id> | Events from a specific calendar |
|
GET /calendars | List all available calendars |
|
POST /auth/refresh | Force token refresh (normally automatic) |
Events response includes: id, summary, start, end, location, description, htmlLink, status, calendarId, INLINECODE17
Checking Events
CODEBLOCK0
To call from OpenClaw/skill context (no API key needed when running on same host):
CODEBLOCK1
First-Time Setup
1. Clone and install
CODEBLOCK2
2. Get Google OAuth credentials
- - Go to https://console.cloud.google.com/apis/credentials
- Create OAuth 2.0 Client ID (Desktop app)
- Enable Google Calendar API
- Add redirect URI: INLINECODE18
- Copy Client ID + Secret to INLINECODE19
3. Start the service
CODEBLOCK3
4. Authorize (one-time browser flow)
If on a remote VPS, first tunnel port 3000:
CODEBLOCK4
Then:
CODEBLOCK5
Verify:
CODEBLOCK6
5. Keep it running (systemd)
CODEBLOCK7
Re-authentication
If tokens are ever revoked (rare — auto-refresh prevents expiry):
- 1. INLINECODE20
- INLINECODE21 → open URL → complete consent
- Done — new tokens overwrite old ones
Troubleshooting
- -
{"error":"Not authenticated"} → Run the OAuth setup flow above 401 Unauthorized → CALENDAR_BRIDGE_API_KEY is set; add Authorization: Bearer <key> header- Can't reach localhost:3000 → Service not running; check INLINECODE26
- "invalid_grant" / "token expired" → Tokens were revoked externally; re-authenticate
Personal Gmail Users
Works with personal Gmail. Google shows an "unverified app" warning — click Advanced → Go to [app] to proceed. Tokens are stored locally on your server, not shared with anyone.
Files
- - GitHub repo: https://github.com/DanielKillenberger/gcal-oauth-bridge
- App:
app.js — main Express server - Config:
.env (from .env.example) - Tokens:
tokens.json (auto-generated, gitignored, never committed)
日历桥接技能
使用此技能与日历桥接服务交互——这是一个本地REST API,封装了Google Calendar OAuth,具备持久化令牌存储和自动刷新功能。
GitHub: https://github.com/DanielKillenberger/gcal-oauth-bridge
什么是日历桥接?
一个运行在 http://localhost:3000 的轻量级Node.js/Express服务,具备以下功能:
- - 通过浏览器一次性处理Google Calendar OAuth
- 存储并自动刷新令牌(解决了每7天令牌过期的问题)
- 为事件、日历和认证提供极其简单的REST API
API端点
| 端点 | 描述 |
|---|
| GET /health | 服务状态 + 认证状态 |
| GET /auth/url |
获取OAuth授权同意URL |
| GET /events?days=7 | 主日历的即将发生的事件 |
| GET /events?days=7&calendar=all | 所有日历的事件 |
| GET /events?days=7&calendar=
| 特定日历的事件 |
| GET /calendars | 列出所有可用日历 |
| POST /auth/refresh | 强制刷新令牌(通常自动进行) |
事件响应包含:id、summary、start、end、location、description、htmlLink、status、calendarId、calendarSummary
查看事件
bash
快速查看事件(7天,主日历)
curl http://localhost:3000/events
所有日历,未来14天
curl http://localhost:3000/events?days=14&calendar=all
使用API密钥(如果配置了CALENDARBRIDGEAPI_KEY)
curl -H Authorization: Bearer $API_KEY http://localhost:3000/events?calendar=all
从OpenClaw/技能上下文中调用(在同一主机上运行时无需API密钥):
GET http://localhost:3000/events?calendar=all&days=7
首次设置
1. 克隆并安装
bash
git clone https://github.com/DanielKillenberger/gcal-oauth-bridge.git
cd gcal-oauth-bridge
npm install
cp .env.example .env
编辑.env文件,填入GOOGLECLIENTID和GOOGLECLIENTSECRET
2. 获取Google OAuth凭据
- - 访问 https://console.cloud.google.com/apis/credentials
- 创建OAuth 2.0客户端ID(桌面应用)
- 启用Google Calendar API
- 添加重定向URI:http://localhost:3000/auth/callback
- 将客户端ID和密钥复制到.env文件中
3. 启动服务
bash
node app.js
或:npm start
4. 授权(一次性浏览器流程)
如果在远程VPS上,首先隧道转发端口3000:
bash
从本地机器执行:
ssh -L 3000:localhost:3000 your-server
然后:
bash
curl http://localhost:3000/auth/url
在浏览器中打开返回的URL
完成Google同意流程 → 令牌自动保存
验证:
bash
curl http://localhost:3000/health
{status:ok,authenticated:true,needsRefresh:false}
5. 保持运行(systemd)
bash
systemctl --user enable calendar-bridge.service
systemctl --user start calendar-bridge.service
重新认证
如果令牌被撤销(很少发生——自动刷新可防止过期):
- 1. ssh -L 3000:localhost:3000 your-server
- curl http://localhost:3000/auth/url → 打开URL → 完成同意流程
- 完成——新令牌会覆盖旧令牌
故障排除
- - {error:Not authenticated} → 执行上述OAuth设置流程
- 401 Unauthorized → 已设置CALENDARBRIDGEAPIKEY;添加Authorization: Bearer 请求头
- 无法访问localhost:3000 → 服务未运行;检查systemctl --user status calendar-bridge
- invalidgrant / token expired → 令牌被外部撤销;重新认证
个人Gmail用户
适用于个人Gmail。Google会显示未验证应用警告——点击高级 → 前往[应用]继续。令牌存储在本地服务器上,不会与任何人共享。
文件
- - GitHub仓库: https://github.com/DanielKillenberger/gcal-oauth-bridge
- 应用:app.js — 主Express服务器
- 配置:.env(从.env.example复制)
- 令牌:tokens.json(自动生成,已加入gitignore,永不提交)