{
  "schemaVersion": "1.0",
  "item": {
    "slug": "gcal-oauth-bridge",
    "name": "gcal-oauth-bridge",
    "source": "tencent",
    "type": "skill",
    "category": "效率提升",
    "sourceUrl": "https://clawhub.ai/DanielKillenberger/gcal-oauth-bridge",
    "canonicalUrl": "https://clawhub.ai/DanielKillenberger/gcal-oauth-bridge",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadMode": "redirect",
    "downloadUrl": "/downloads/gcal-oauth-bridge",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=gcal-oauth-bridge",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "installMethod": "Manual import",
    "extraction": "Extract archive",
    "prerequisites": [
      "OpenClaw"
    ],
    "packageFormat": "ZIP package",
    "includedAssets": [
      "SKILL.md",
      "_meta.json"
    ],
    "primaryDoc": "SKILL.md",
    "quickSetup": [
      "Download the package from Yavira.",
      "Extract the archive and review SKILL.md first.",
      "Import or place the package into your OpenClaw setup."
    ],
    "agentAssist": {
      "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
      "steps": [
        "Download the package from Yavira.",
        "Extract it into a folder your agent can access.",
        "Paste one of the prompts below and point your agent at the extracted folder."
      ],
      "prompts": [
        {
          "label": "New install",
          "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
        },
        {
          "label": "Upgrade existing",
          "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
        }
      ]
    },
    "sourceHealth": {
      "source": "tencent",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-04-30T16:55:25.780Z",
      "expiresAt": "2026-05-07T16:55:25.780Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=network",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=network",
        "contentDisposition": "attachment; filename=\"network-1.0.0.zip\"",
        "redirectLocation": null,
        "bodySnippet": null
      },
      "scope": "source",
      "summary": "Source download looks usable.",
      "detail": "Yavira can redirect you to the upstream package for this source.",
      "primaryActionLabel": "Download for OpenClaw",
      "primaryActionHref": "/downloads/gcal-oauth-bridge"
    },
    "validation": {
      "installChecklist": [
        "Use the Yavira download entry.",
        "Review SKILL.md after the package is downloaded.",
        "Confirm the extracted package contains the expected setup assets."
      ],
      "postInstallChecks": [
        "Confirm the extracted package includes the expected docs or setup files.",
        "Validate the skill or prompts are available in your target agent workspace.",
        "Capture any manual follow-up steps the agent could not complete."
      ]
    },
    "downloadPageUrl": "https://openagent3.xyz/downloads/gcal-oauth-bridge",
    "agentPageUrl": "https://openagent3.xyz/skills/gcal-oauth-bridge/agent",
    "manifestUrl": "https://openagent3.xyz/skills/gcal-oauth-bridge/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/gcal-oauth-bridge/agent.md"
  },
  "agentAssist": {
    "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
    "steps": [
      "Download the package from Yavira.",
      "Extract it into a folder your agent can access.",
      "Paste one of the prompts below and point your agent at the extracted folder."
    ],
    "prompts": [
      {
        "label": "New install",
        "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
      },
      {
        "label": "Upgrade existing",
        "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
      }
    ]
  },
  "documentation": {
    "source": "clawhub",
    "primaryDoc": "SKILL.md",
    "sections": [
      {
        "title": "Calendar Bridge Skill",
        "body": "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.\n\nGitHub: https://github.com/DanielKillenberger/gcal-oauth-bridge"
      },
      {
        "title": "What is Calendar Bridge?",
        "body": "A tiny Node.js/Express service running at http://localhost:3000 that:\n\nHandles Google Calendar OAuth once via browser\nStores and auto-refreshes tokens (solves the \"token expired every 7 days\" problem)\nExposes a dead-simple REST API for events, calendars, and auth"
      },
      {
        "title": "API Endpoints",
        "body": "EndpointDescriptionGET /healthService status + auth stateGET /auth/urlGet OAuth consent URLGET /events?days=7Upcoming events from primary calendarGET /events?days=7&calendar=allEvents from ALL calendarsGET /events?days=7&calendar=<id>Events from a specific calendarGET /calendarsList all available calendarsPOST /auth/refreshForce token refresh (normally automatic)\n\nEvents response includes: id, summary, start, end, location, description, htmlLink, status, calendarId, calendarSummary"
      },
      {
        "title": "Checking Events",
        "body": "# Quick event check (7 days, primary calendar)\ncurl http://localhost:3000/events\n\n# All calendars, next 14 days\ncurl http://localhost:3000/events?days=14&calendar=all\n\n# With API key (if CALENDAR_BRIDGE_API_KEY is configured)\ncurl -H \"Authorization: Bearer $API_KEY\" http://localhost:3000/events?calendar=all\n\nTo call from OpenClaw/skill context (no API key needed when running on same host):\n\nGET http://localhost:3000/events?calendar=all&days=7"
      },
      {
        "title": "1. Clone and install",
        "body": "git clone https://github.com/DanielKillenberger/gcal-oauth-bridge.git\ncd gcal-oauth-bridge\nnpm install\ncp .env.example .env\n# Edit .env with GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET"
      },
      {
        "title": "2. Get Google OAuth credentials",
        "body": "Go to https://console.cloud.google.com/apis/credentials\nCreate OAuth 2.0 Client ID (Desktop app)\nEnable Google Calendar API\nAdd redirect URI: http://localhost:3000/auth/callback\nCopy Client ID + Secret to .env"
      },
      {
        "title": "3. Start the service",
        "body": "node app.js\n# or: npm start"
      },
      {
        "title": "4. Authorize (one-time browser flow)",
        "body": "If on a remote VPS, first tunnel port 3000:\n\n# From your local machine:\nssh -L 3000:localhost:3000 your-server\n\nThen:\n\ncurl http://localhost:3000/auth/url\n# Open the returned URL in your browser\n# Complete Google consent → tokens saved automatically\n\nVerify:\n\ncurl http://localhost:3000/health\n# {\"status\":\"ok\",\"authenticated\":true,\"needsRefresh\":false}"
      },
      {
        "title": "5. Keep it running (systemd)",
        "body": "systemctl --user enable calendar-bridge.service\nsystemctl --user start calendar-bridge.service"
      },
      {
        "title": "Re-authentication",
        "body": "If tokens are ever revoked (rare — auto-refresh prevents expiry):\n\nssh -L 3000:localhost:3000 your-server\ncurl http://localhost:3000/auth/url → open URL → complete consent\nDone — new tokens overwrite old ones"
      },
      {
        "title": "Troubleshooting",
        "body": "{\"error\":\"Not authenticated\"} → Run the OAuth setup flow above\n401 Unauthorized → CALENDAR_BRIDGE_API_KEY is set; add Authorization: Bearer <key> header\nCan't reach localhost:3000 → Service not running; check systemctl --user status calendar-bridge\n\"invalid_grant\" / \"token expired\" → Tokens were revoked externally; re-authenticate"
      },
      {
        "title": "Personal Gmail Users",
        "body": "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."
      },
      {
        "title": "Files",
        "body": "GitHub repo: https://github.com/DanielKillenberger/gcal-oauth-bridge\nApp: app.js — main Express server\nConfig: .env (from .env.example)\nTokens: tokens.json (auto-generated, gitignored, never committed)"
      }
    ],
    "body": "Calendar Bridge Skill\n\nUse 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.\n\nGitHub: https://github.com/DanielKillenberger/gcal-oauth-bridge\n\nWhat is Calendar Bridge?\n\nA tiny Node.js/Express service running at http://localhost:3000 that:\n\nHandles Google Calendar OAuth once via browser\nStores and auto-refreshes tokens (solves the \"token expired every 7 days\" problem)\nExposes a dead-simple REST API for events, calendars, and auth\nAPI Endpoints\nEndpoint\tDescription\nGET /health\tService status + auth state\nGET /auth/url\tGet OAuth consent URL\nGET /events?days=7\tUpcoming events from primary calendar\nGET /events?days=7&calendar=all\tEvents from ALL calendars\nGET /events?days=7&calendar=<id>\tEvents from a specific calendar\nGET /calendars\tList all available calendars\nPOST /auth/refresh\tForce token refresh (normally automatic)\n\nEvents response includes: id, summary, start, end, location, description, htmlLink, status, calendarId, calendarSummary\n\nChecking Events\n# Quick event check (7 days, primary calendar)\ncurl http://localhost:3000/events\n\n# All calendars, next 14 days\ncurl http://localhost:3000/events?days=14&calendar=all\n\n# With API key (if CALENDAR_BRIDGE_API_KEY is configured)\ncurl -H \"Authorization: Bearer $API_KEY\" http://localhost:3000/events?calendar=all\n\n\nTo call from OpenClaw/skill context (no API key needed when running on same host):\n\nGET http://localhost:3000/events?calendar=all&days=7\n\nFirst-Time Setup\n1. Clone and install\ngit clone https://github.com/DanielKillenberger/gcal-oauth-bridge.git\ncd gcal-oauth-bridge\nnpm install\ncp .env.example .env\n# Edit .env with GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET\n\n2. Get Google OAuth credentials\nGo to https://console.cloud.google.com/apis/credentials\nCreate OAuth 2.0 Client ID (Desktop app)\nEnable Google Calendar API\nAdd redirect URI: http://localhost:3000/auth/callback\nCopy Client ID + Secret to .env\n3. Start the service\nnode app.js\n# or: npm start\n\n4. Authorize (one-time browser flow)\n\nIf on a remote VPS, first tunnel port 3000:\n\n# From your local machine:\nssh -L 3000:localhost:3000 your-server\n\n\nThen:\n\ncurl http://localhost:3000/auth/url\n# Open the returned URL in your browser\n# Complete Google consent → tokens saved automatically\n\n\nVerify:\n\ncurl http://localhost:3000/health\n# {\"status\":\"ok\",\"authenticated\":true,\"needsRefresh\":false}\n\n5. Keep it running (systemd)\nsystemctl --user enable calendar-bridge.service\nsystemctl --user start calendar-bridge.service\n\nRe-authentication\n\nIf tokens are ever revoked (rare — auto-refresh prevents expiry):\n\nssh -L 3000:localhost:3000 your-server\ncurl http://localhost:3000/auth/url → open URL → complete consent\nDone — new tokens overwrite old ones\nTroubleshooting\n{\"error\":\"Not authenticated\"} → Run the OAuth setup flow above\n401 Unauthorized → CALENDAR_BRIDGE_API_KEY is set; add Authorization: Bearer <key> header\nCan't reach localhost:3000 → Service not running; check systemctl --user status calendar-bridge\n\"invalid_grant\" / \"token expired\" → Tokens were revoked externally; re-authenticate\nPersonal Gmail Users\n\nWorks 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.\n\nFiles\nGitHub repo: https://github.com/DanielKillenberger/gcal-oauth-bridge\nApp: app.js — main Express server\nConfig: .env (from .env.example)\nTokens: tokens.json (auto-generated, gitignored, never committed)"
  },
  "trust": {
    "sourceLabel": "tencent",
    "provenanceUrl": "https://clawhub.ai/DanielKillenberger/gcal-oauth-bridge",
    "publisherUrl": "https://clawhub.ai/DanielKillenberger/gcal-oauth-bridge",
    "owner": "DanielKillenberger",
    "version": "1.0.3",
    "license": null,
    "verificationStatus": "Indexed source record"
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/gcal-oauth-bridge",
    "downloadUrl": "https://openagent3.xyz/downloads/gcal-oauth-bridge",
    "agentUrl": "https://openagent3.xyz/skills/gcal-oauth-bridge/agent",
    "manifestUrl": "https://openagent3.xyz/skills/gcal-oauth-bridge/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/gcal-oauth-bridge/agent.md"
  }
}