diff --git a/.env.example b/.env.example index b82a747..27a918b 100644 --- a/.env.example +++ b/.env.example @@ -3,9 +3,4 @@ # Required: HackMD Configuration # HACKMD_API_TOKEN=your_hackmd_api_token -# HACKMD_TEAM_NAME=your_hackmd_team_name_optional # Defaults to your own personal space - -# Google Calendar API Authentication -# You can get this from the Google Cloud Console -# Create an API Key and restrict it to the Google Calendar API -# GOOGLE_API_KEY=your_google_calendar_api_key_here +# HACKMD_TEAM_NAME=your_hackmd_team_name_optional # Defaults to your own personal space \ No newline at end of file diff --git a/.github/workflows/create-meeting-artifacts-manual.yml b/.github/workflows/create-meeting-artifacts-manual.yml index 433684f..9219993 100644 --- a/.github/workflows/create-meeting-artifacts-manual.yml +++ b/.github/workflows/create-meeting-artifacts-manual.yml @@ -57,8 +57,7 @@ jobs: env: GITHUB_TOKEN: ${{ steps.app-token.outputs.token }} HACKMD_API_TOKEN: ${{ secrets.HACKMD_API_TOKEN }} - GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }} - ADDITIONAL_ARGS: ${{ inputs.dry_run == 'true' && '--dry-run' || '' }} + ADDITIONAL_ARGS: ${{ github.event.inputs.dry_run == 'true' && '--dry-run' || '' }} run: node create-node-meeting-artifacts.mjs ${{ inputs.meeting_group }} --verbose $ADDITIONAL_ARGS - name: Upload artifacts diff --git a/README.md b/README.md index 28f5920..745cf4d 100644 --- a/README.md +++ b/README.md @@ -6,8 +6,6 @@ A modern Node.js application that creates GitHub issues and HackMD documents for - Node.js 22+ (LTS) - GitHub Personal Access Token -- Google Cloud Project with Calendar API enabled (for meeting scheduling) -- Google API Key for Calendar access - HackMD API Token (for meeting minutes) ## 🔑 Authentication Setup @@ -26,19 +24,6 @@ A modern Node.js application that creates GitHub issues and HackMD documents for 3. Create a new API token for the meeting artifacts tool 4. Optionally, create or join a team workspace for better organization -### Google Authentication (Calendar Only) - -#### API Key Authentication (Recommended) - -1. Go to [Google Cloud Console](https://console.cloud.google.com/) -2. Create a new project or select an existing one -3. Enable the Google Calendar API -4. Go to **Credentials** → **Create Credentials** → **API Key** -5. Restrict the API key to the Google Calendar API for security -6. Add the API key to your environment variables as `GOOGLE_API_KEY` - -**Note:** API Keys provide simplified authentication and are sufficient for read-only calendar access. They don't require complex OAuth flows or service account setup. - ## 📁 Project Structure ``` @@ -47,7 +32,7 @@ create-node-meeting-artifacts/ │ ├── config.mjs # Configuration management │ ├── constants.mjs # Application constants │ ├── github.mjs # GitHub API integration -│ ├── google.mjs # Google APIs integration +│ ├── calendar.mjs # Calendar integration │ ├── meeting.mjs # Meeting operations │ └── utils.mjs # Utility functions ├── templates/ # Meeting templates @@ -202,7 +187,6 @@ The application creates: - `GITHUB_TOKEN`: GitHub Personal Access Token - `HACKMD_API_TOKEN`: HackMD API token for creating and managing documents -- `GOOGLE_API_KEY`: Google Calendar API Key for read-only calendar access ### Meeting Base Configuration @@ -210,7 +194,6 @@ Each `meeting_base_` file contains: ```bash CALENDAR_FILTER="Meeting Name in Calendar" -CALENDAR_ID="nodejs.org_nr77ama8p7d7f9ajrpnu506c98@group.calendar.google.com" USER="nodejs" REPO="repository-name" GROUP_NAME="Full Group Name" diff --git a/TEMPLATES_DOCUMENTATION.md b/TEMPLATES_DOCUMENTATION.md index 279950f..aa2b1e7 100644 --- a/TEMPLATES_DOCUMENTATION.md +++ b/TEMPLATES_DOCUMENTATION.md @@ -18,7 +18,7 @@ There are several variables in the documents that need to be configured: The following properties are available in meeting base templates and can be used in meeting issue generation: - **`CALENDAR_FILTER`:** The name of calendar events that mark the group's meeting date/time -- **`CALENDAR_ID`:** The Google Calendar ID for the Node.js calendar (typically `nodejs.org_nr77ama8p7d7f9ajrpnu506c98@group.calendar.google.com`) +- **`ICAL_URL`:** The ICAL URL for a given meetings' calendar - **`USER`:** The GitHub username/organization (typically `nodejs`) - **`REPO`:** The repository name where meeting issues are created - **`GROUP_NAME`:** The full name of the Committee, Working Group, Initiative, or Team @@ -55,7 +55,7 @@ A base of metadata and some content for the issue to be created on time, with ag ``` CALENDAR_FILTER="" -CALENDAR_ID="nodejs.org_nr77ama8p7d7f9ajrpnu506c98@group.calendar.google.com" +ICAL_URL="" USER="nodejs" REPO="" GROUP_NAME="" @@ -72,7 +72,7 @@ JOINING_INSTRUCTIONS=" ``` CALENDAR_FILTER="Node.js Community Committee" -CALENDAR_ID="nodejs.org_nr77ama8p7d7f9ajrpnu506c98@group.calendar.google.com" +ICAL_URL="<...>" USER="nodejs" REPO="community-committee" GROUP_NAME="Community Committee" diff --git a/create-node-meeting-artifacts.mjs b/create-node-meeting-artifacts.mjs index 94e30a1..26633f2 100644 --- a/create-node-meeting-artifacts.mjs +++ b/create-node-meeting-artifacts.mjs @@ -11,9 +11,9 @@ import { Command } from 'commander'; +import * as calendar from './src/calendar.mjs'; import environmentConfig from './src/config.mjs'; import * as github from './src/github.mjs'; -import * as google from './src/google.mjs'; import * as hackmd from './src/hackmd.mjs'; import * as meetings from './src/meeting.mjs'; @@ -32,9 +32,6 @@ const config = { meetingGroup: program.args[0], }; -// Step 2: Initialize Google Calendar client with API Key -const calendarClient = google.createCalendarClient(config.google); - // Step 3: Initialize GitHub client const githubClient = github.createGitHubClient(config); @@ -67,10 +64,11 @@ if (config.dryRun) { } // Step 6: Find next meeting event in calendar -const event = await google.findNextMeetingEvent(calendarClient, meetingConfig); +const events = await calendar.getEventsFromCalendar( + meetingConfig.properties.ICAL_URL +); -// Step 7: Extract meeting date from event -const meetingDate = new Date(event.start.dateTime); +const meetingDate = await calendar.findNextMeetingDate(events, meetingConfig); // Step 8: Get Meeting Title const meetingTitle = meetings.generateMeetingTitle( diff --git a/global.d.ts b/global.d.ts index dfc2a0c..4ec2382 100644 --- a/global.d.ts +++ b/global.d.ts @@ -3,15 +3,11 @@ * This file makes types from third-party libraries available globally without imports in JSDoc comments */ -import type { calendar_v3 } from '@googleapis/calendar'; import type { RestEndpointMethodTypes } from '@octokit/rest'; import type { API } from '@hackmd/api'; import type { SingleNote } from '@hackmd/api/dist/type.d.ts'; declare global { - // Google API type aliases - type CalendarEvent = calendar_v3.Schema$Event; - type CalendarClient = calendar_v3.Calendar; type HackMDClient = API; type HackMDNote = SingleNote; diff --git a/package-lock.json b/package-lock.json index 6dc17df..0225550 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,18 +9,19 @@ "version": "0.0.1", "license": "MIT", "dependencies": { - "@googleapis/calendar": "^11.0.1", "@hackmd/api": "^2.5.0", "@octokit/rest": "^22.0.0", "commander": "^14.0.1", "dedent": "^1.6.0", - "dotenv": "^17.2.2" + "dotenv": "^17.2.2", + "ical": "^0.8.0" }, "bin": { "create-node-meeting-artifacts": "create-node-meeting-artifacts.mjs" }, "devDependencies": { "@eslint/js": "^9.33.0", + "@types/ical": "^0.8.3", "@types/properties-parser": "^0.3.3", "eslint": "^9.33.0", "eslint-plugin-import-x": "^4.16.1", @@ -261,18 +262,6 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@googleapis/calendar": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/@googleapis/calendar/-/calendar-11.0.1.tgz", - "integrity": "sha512-XR6/V8SjuOyGMMx5shcKB2Ouyqkw2OG5a1srCb6ifPkIJG5qu/aocQ4VVizPc89izgdCGaKqcSpRFNJUsUuizg==", - "license": "Apache-2.0", - "dependencies": { - "googleapis-common": "^8.0.2-rc.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, "node_modules/@hackmd/api": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/@hackmd/api/-/api-2.5.0.tgz", @@ -565,6 +554,16 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/ical": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/@types/ical/-/ical-0.8.3.tgz", + "integrity": "sha512-qPejGORaXOstmqyKzp0Qw9nXDPiWiahiJJcx4zMB0zJVg0rLfJ6bDip/naqagEqYTjKl/LI91399hR8zFwRJ5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "rrule": "2.6.4" + } + }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", @@ -898,15 +897,6 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/agent-base": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", - "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", - "license": "MIT", - "engines": { - "node": ">= 14" - } - }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -981,41 +971,12 @@ "dev": true, "license": "MIT" }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, "node_modules/before-after-hook": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-4.0.0.tgz", "integrity": "sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ==", "license": "Apache-2.0" }, - "node_modules/bignumber.js": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.3.1.tgz", - "integrity": "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==", - "license": "MIT", - "engines": { - "node": "*" - } - }, "node_modules/brace-expansion": { "version": "1.1.12", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", @@ -1027,12 +988,6 @@ "concat-map": "0.0.1" } }, - "node_modules/buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", - "license": "BSD-3-Clause" - }, "node_modules/call-bind-apply-helpers": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", @@ -1046,22 +1001,6 @@ "node": ">= 0.4" } }, - "node_modules/call-bound": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", - "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "get-intrinsic": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -1162,19 +1101,11 @@ "node": ">= 8" } }, - "node_modules/data-uri-to-buffer": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", - "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", - "license": "MIT", - "engines": { - "node": ">= 12" - } - }, "node_modules/debug": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "dev": true, "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -1244,15 +1175,6 @@ "node": ">= 0.4" } }, - "node_modules/ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "license": "Apache-2.0", - "dependencies": { - "safe-buffer": "^5.0.1" - } - }, "node_modules/es-define-property": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", @@ -1569,12 +1491,6 @@ "node": ">=0.10.0" } }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "license": "MIT" - }, "node_modules/fast-content-type-parse": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-3.0.0.tgz", @@ -1612,29 +1528,6 @@ "dev": true, "license": "MIT" }, - "node_modules/fetch-blob": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", - "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/jimmywarting" - }, - { - "type": "paypal", - "url": "https://paypal.me/jimmywarting" - } - ], - "license": "MIT", - "dependencies": { - "node-domexception": "^1.0.0", - "web-streams-polyfill": "^3.0.3" - }, - "engines": { - "node": "^12.20 || >= 14.13" - } - }, "node_modules/file-entry-cache": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", @@ -1722,18 +1615,6 @@ "node": ">= 6" } }, - "node_modules/formdata-polyfill": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", - "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", - "license": "MIT", - "dependencies": { - "fetch-blob": "^3.1.2" - }, - "engines": { - "node": ">=12.20.0" - } - }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -1743,34 +1624,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/gaxios": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-7.1.1.tgz", - "integrity": "sha512-Odju3uBUJyVCkW64nLD4wKLhbh93bh6vIg/ZIXkWiLPBrdgtc65+tls/qml+un3pr6JqYVFDZbbmLDQT68rTOQ==", - "license": "Apache-2.0", - "dependencies": { - "extend": "^3.0.2", - "https-proxy-agent": "^7.0.1", - "node-fetch": "^3.3.2" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/gcp-metadata": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-7.0.1.tgz", - "integrity": "sha512-UcO3kefx6dCcZkgcTGgVOTFb7b1LlQ02hY1omMjjrrBzkajRMCFgYOjs7J71WqnuG1k2b+9ppGL7FsOfhZMQKQ==", - "license": "Apache-2.0", - "dependencies": { - "gaxios": "^7.0.0", - "google-logging-utils": "^1.0.0", - "json-bigint": "^1.0.0" - }, - "engines": { - "node": ">=18" - } - }, "node_modules/get-intrinsic": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", @@ -1847,49 +1700,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/google-auth-library": { - "version": "10.2.1", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-10.2.1.tgz", - "integrity": "sha512-HMxFl2NfeHYnaL1HoRIN1XgorKS+6CDaM+z9LSSN+i/nKDDL4KFFEWogMXu7jV4HZQy2MsxpY+wA5XIf3w410A==", - "license": "Apache-2.0", - "dependencies": { - "base64-js": "^1.3.0", - "ecdsa-sig-formatter": "^1.0.11", - "gaxios": "^7.0.0", - "gcp-metadata": "^7.0.0", - "google-logging-utils": "^1.0.0", - "gtoken": "^8.0.0", - "jws": "^4.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/google-logging-utils": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-1.1.1.tgz", - "integrity": "sha512-rcX58I7nqpu4mbKztFeOAObbomBbHU2oIb/d3tJfF3dizGSApqtSwYJigGCooHdnMyQBIw8BrWyK96w3YXgr6A==", - "license": "Apache-2.0", - "engines": { - "node": ">=14" - } - }, - "node_modules/googleapis-common": { - "version": "8.0.2-rc.0", - "resolved": "https://registry.npmjs.org/googleapis-common/-/googleapis-common-8.0.2-rc.0.tgz", - "integrity": "sha512-JTcxRvmFa9Ec1uyfMEimEMeeKq1sHNZX3vn2qmoUMtnvixXXvcqTcbDZvEZXkEWpGlPlOf4joyep6/qs0BrLyg==", - "license": "Apache-2.0", - "dependencies": { - "extend": "^3.0.2", - "gaxios": "^7.0.0-rc.4", - "google-auth-library": "^10.0.0-rc.1", - "qs": "^6.7.0", - "url-template": "^2.0.8" - }, - "engines": { - "node": ">=18.0.0" - } - }, "node_modules/gopd": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", @@ -1902,19 +1712,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/gtoken": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-8.0.0.tgz", - "integrity": "sha512-+CqsMbHPiSTdtSO14O51eMNlrp9N79gmeqmXeouJOhfucAedHw9noVe/n5uJk3tbKE6a+6ZCQg3RPhVhHByAIw==", - "license": "MIT", - "dependencies": { - "gaxios": "^7.0.0", - "jws": "^4.0.0" - }, - "engines": { - "node": ">=18" - } - }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -1964,17 +1761,22 @@ "node": ">= 0.4" } }, - "node_modules/https-proxy-agent": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", - "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", - "license": "MIT", + "node_modules/ical": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/ical/-/ical-0.8.0.tgz", + "integrity": "sha512-/viUSb/RGLLnlgm0lWRlPBtVeQguQRErSPYl3ugnUaKUnzQswKqOG3M8/P1v1AB5NJwlHTuvTq1cs4mpeG2rCg==", + "license": "Apache-2.0", "dependencies": { - "agent-base": "^7.1.2", - "debug": "4" - }, - "engines": { - "node": ">= 14" + "rrule": "2.4.1" + } + }, + "node_modules/ical/node_modules/rrule": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/rrule/-/rrule-2.4.1.tgz", + "integrity": "sha512-+NcvhETefswZq13T8nkuEnnQ6YgUeZaqMqVbp+ZiFDPCbp3AVgQIwUvNVDdMNrP05bKZG9ddDULFp0qZZYDrxg==", + "license": "SEE LICENSE IN LICENSE", + "optionalDependencies": { + "luxon": "^1.3.3" } }, "node_modules/ignore": { @@ -2067,15 +1869,6 @@ "node": ">=12.0.0" } }, - "node_modules/json-bigint": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", - "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", - "license": "MIT", - "dependencies": { - "bignumber.js": "^9.0.0" - } - }, "node_modules/json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", @@ -2097,27 +1890,6 @@ "dev": true, "license": "MIT" }, - "node_modules/jwa": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz", - "integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==", - "license": "MIT", - "dependencies": { - "buffer-equal-constant-time": "^1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/jws": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", - "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", - "license": "MIT", - "dependencies": { - "jwa": "^2.0.0", - "safe-buffer": "^5.0.1" - } - }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -2165,6 +1937,16 @@ "dev": true, "license": "MIT" }, + "node_modules/luxon": { + "version": "1.28.1", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-1.28.1.tgz", + "integrity": "sha512-gYHAa180mKrNIUJCbwpmD0aTu9kV0dREDrwNnuyFAsO1Wt0EVYSZelPnJlbj9HplzXX/YWXHFTL45kvZ53M0pw==", + "license": "MIT", + "optional": true, + "engines": { + "node": "*" + } + }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -2212,6 +1994,7 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, "license": "MIT" }, "node_modules/napi-postinstall": { @@ -2237,56 +2020,6 @@ "dev": true, "license": "MIT" }, - "node_modules/node-domexception": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", - "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", - "deprecated": "Use your platform's native DOMException instead", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/jimmywarting" - }, - { - "type": "github", - "url": "https://paypal.me/jimmywarting" - } - ], - "license": "MIT", - "engines": { - "node": ">=10.5.0" - } - }, - "node_modules/node-fetch": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", - "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", - "license": "MIT", - "dependencies": { - "data-uri-to-buffer": "^4.0.0", - "fetch-blob": "^3.1.4", - "formdata-polyfill": "^4.0.10" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/node-fetch" - } - }, - "node_modules/object-inspect": { - "version": "1.13.4", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", - "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/optionator": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", @@ -2429,21 +2162,6 @@ "node": ">=6" } }, - "node_modules/qs": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", - "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.1.0" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -2464,25 +2182,18 @@ "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" } }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" + "node_modules/rrule": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/rrule/-/rrule-2.6.4.tgz", + "integrity": "sha512-sLdnh4lmjUqq8liFiOUXD5kWp/FcnbDLPwq5YAc/RrN6120XOPb86Ae5zxF7ttBVq8O3LxjjORMEit1baluahA==", + "dev": true, + "license": "SEE LICENSE IN LICENSE", + "dependencies": { + "tslib": "^1.10.0" + }, + "optionalDependencies": { + "luxon": "^1.21.3" + } }, "node_modules/semver": { "version": "7.7.2", @@ -2520,78 +2231,6 @@ "node": ">=8" } }, - "node_modules/side-channel": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", - "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3", - "side-channel-list": "^1.0.0", - "side-channel-map": "^1.0.1", - "side-channel-weakmap": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-list": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", - "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-map": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", - "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-weakmap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", - "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3", - "side-channel-map": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/spdx-exceptions": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", @@ -2730,21 +2369,6 @@ "punycode": "^2.1.0" } }, - "node_modules/url-template": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", - "integrity": "sha512-XdVKMF4SJ0nP/O7XIPB0JwAEuT9lDIYnNsK8yGVe43y0AWoKeJNdv3ZNWh7ksJ6KqQFjOO6ox/VEitLnaVNufw==", - "license": "BSD" - }, - "node_modules/web-streams-polyfill": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", - "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", diff --git a/package.json b/package.json index 4eeee96..03d6156 100644 --- a/package.json +++ b/package.json @@ -11,15 +11,16 @@ "node": ">=22.0.0" }, "dependencies": { - "@googleapis/calendar": "^11.0.1", "@hackmd/api": "^2.5.0", "@octokit/rest": "^22.0.0", "commander": "^14.0.1", "dedent": "^1.6.0", - "dotenv": "^17.2.2" + "dotenv": "^17.2.2", + "ical": "^0.8.0" }, "devDependencies": { "@eslint/js": "^9.33.0", + "@types/ical": "^0.8.3", "@types/properties-parser": "^0.3.3", "eslint": "^9.33.0", "eslint-plugin-import-x": "^4.16.1", diff --git a/src/calendar.mjs b/src/calendar.mjs new file mode 100644 index 0000000..ed3a5ee --- /dev/null +++ b/src/calendar.mjs @@ -0,0 +1,61 @@ +import ical from 'ical'; + +/** + * Creates an ICAL instance from the input URL + * @param {string} url + */ +export const getEventsFromCalendar = async url => { + const response = await fetch(url); + const text = await response.text(); + + return Object.values(ical.parseICS(text)); +}; + +/** + * @param {Date} now + */ +const getWeekBounds = (now = new Date()) => { + const startDate = now.getUTCDate() - now.getUTCDay(); + + const start = new Date(now.setUTCDate(startDate)); + start.setUTCHours(0, 0, 0, 0); + + const end = new Date(now.setUTCDate(startDate + 7)); + end.setUTCHours(0, 0, 0, 0); + + return [start, end]; +}; + +/** + * Finds the next meeting event in any iCal feed for the current week + * @param {ical.CalendarComponent[]} allEvents - The events + * @param {import('./types').MeetingConfig} meetingConfig - Meeting configuration object + * @returns {Promise} The date of the next meeting + */ +export const findNextMeetingDate = async (allEvents, { properties }) => { + const [weekStart, weekEnd] = getWeekBounds(); + + const filteredEvents = allEvents.filter( + event => + // The event must be recurring + event.rrule && + // The event must match our filter + (event.summary || event.description)?.includes(properties.CALENDAR_FILTER) + ); + + for (const event of filteredEvents) { + // Get all recurrences in our timeframe + event.rrule.options.tzid = event.tzid; + const duringOurTimeframe = event.rrule.between(weekStart, weekEnd); + + if (duringOurTimeframe.length > 0) { + return duringOurTimeframe[0]; + } + } + + throw new Error( + `No meeting found for ${properties.GROUP_NAME || 'this group'} ` + + `in the current week (${weekStart.toISOString().split('T')[0]} to ${weekEnd.toISOString().split('T')[0]}). ` + + `This is expected for bi-weekly meetings or meetings that don't occur every week.` + ); +}; diff --git a/src/config.mjs b/src/config.mjs index df3e2f5..bc21d78 100644 --- a/src/config.mjs +++ b/src/config.mjs @@ -10,12 +10,6 @@ export default { // GitHub personal access token from environment githubToken: process.env.GITHUB_TOKEN, - // Google authentication configuration - now uses API Keys for simplicity - google: { - // Google API Key for Calendar access (preferred method) - apiKey: process.env.GOOGLE_API_KEY, - }, - // HackMD configuration for meeting notes hackmd: { // HackMD API token for authentication diff --git a/src/google.mjs b/src/google.mjs deleted file mode 100644 index 27b5400..0000000 --- a/src/google.mjs +++ /dev/null @@ -1,58 +0,0 @@ -import { calendar } from '@googleapis/calendar'; - -/** - * Creates an authenticated Google Calendar client using API Key - * @param {import('./types.d.ts').GoogleConfig} gConfig - Google configuration object - * @returns {CalendarClient} Authenticated Google Calendar client - */ -export const createCalendarClient = ({ apiKey: auth }) => - calendar({ version: 'v3', auth }); - -/** - * Finds the next meeting event in Google Calendar for the current week - * @param {import('@googleapis/calendar').calendar_v3.Calendar} calendarClient - Google Calendar client - * @param {import('./types.d.ts').MeetingConfig} meetingConfig - Meeting configuration object - * @returns {Promise} Calendar event object - */ -export const findNextMeetingEvent = async (calendarClient, meetingConfig) => { - const now = new Date(); - - // Calculate the start of the current week (Saturday 00:00:00 UTC) - // This handles the scenario where we want a full week from Saturday to Friday - const daysSinceStartOfWeek = (now.getUTCDay() + 1) % 7; // Saturday = 0, Sunday = 1, ..., Friday = 6 - const weekStart = new Date(now); - - weekStart.setUTCDate(now.getUTCDate() - daysSinceStartOfWeek); - weekStart.setUTCHours(0, 0, 0, 0); - - // Calculate the end of the week (Friday 23:59:59 UTC) - const weekEnd = new Date(weekStart); - - weekEnd.setUTCDate(weekStart.getUTCDate() + 6); - weekEnd.setUTCHours(23, 59, 59, 999); - - // Search for events in the specified calendar using the filter text - const response = await calendarClient.events.list({ - calendarId: meetingConfig.properties.CALENDAR_ID?.replace(/"/g, ''), - timeMin: weekStart.toISOString(), - timeMax: weekEnd.toISOString(), - singleEvents: true, - // Replace spaces with dots for Google Calendar search compatibility - q: meetingConfig.properties.CALENDAR_FILTER?.replace(/"/g, '').replace( - / /g, - '.' - ), - }); - - // Ensure we found at least one event - if (!response.data.items || response.data.items.length === 0) { - throw new Error( - `No meeting found for ${meetingConfig?.properties?.GROUP_NAME || 'this group'} ` + - `in the current week (${weekStart.toISOString().split('T')[0]} to ${weekEnd.toISOString().split('T')[0]}). ` + - `This is expected for bi-weekly meetings or meetings that don't occur every week.` - ); - } - - // Return the first (next) event found - return response.data.items[0]; -}; diff --git a/src/types.d.ts b/src/types.d.ts index 95d15cf..f31c002 100644 --- a/src/types.d.ts +++ b/src/types.d.ts @@ -4,8 +4,6 @@ export interface EnvironmentConfig { /** GitHub personal access token */ githubToken: string; - /** Google API configuration (Calendar only) */ - google: GoogleConfig; /** HackMD API configuration */ hackmd: HackMDConfig; /** Directory paths configuration */ @@ -23,14 +21,6 @@ export interface CLIConfig { export type AppConfig = EnvironmentConfig & CLIConfig; -/** - * Google authentication configuration (Calendar only) - */ -export interface GoogleConfig { - /** Google API Key for Calendar access */ - apiKey?: string; -} - /** * HackMD API configuration */ @@ -65,8 +55,8 @@ export interface MeetingConfig { * Meeting properties parsed from template file */ export interface MeetingProperties { - /** Calendar ID to search for events */ - CALENDAR_ID?: string; + /** ICAL to search for events */ + ICAL_URL?: string; /** Text filter for calendar events */ CALENDAR_FILTER?: string; /** GitHub repository owner/user */ diff --git a/templates/meeting_base_Release b/templates/meeting_base_Release index a528f10..47a0ef1 100644 --- a/templates/meeting_base_Release +++ b/templates/meeting_base_Release @@ -1,5 +1,5 @@ CALENDAR_FILTER="Node.js Release Working Group Meeting" -CALENDAR_ID="c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8@group.calendar.google.com" +ICAL_URL="https://calendar.google.com/calendar/ical/c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8%40group.calendar.google.com/public/basic.ics" USER="nodejs" REPO="Release" GROUP_NAME="Release WorkGroup" diff --git a/templates/meeting_base_benchmarking b/templates/meeting_base_benchmarking index cd777eb..bf88861 100644 --- a/templates/meeting_base_benchmarking +++ b/templates/meeting_base_benchmarking @@ -1,5 +1,5 @@ CALENDAR_FILTER="Benchmarking WG Meeting" -CALENDAR_ID="c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8@group.calendar.google.com" +ICAL_URL="https://calendar.google.com/calendar/ical/c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8%40group.calendar.google.com/public/basic.ics" USER="nodejs" REPO="benchmarking" GROUP_NAME="Benchmarking WorkGroup" diff --git a/templates/meeting_base_build b/templates/meeting_base_build index 02b2067..42b3082 100644 --- a/templates/meeting_base_build +++ b/templates/meeting_base_build @@ -1,5 +1,5 @@ CALENDAR_FILTER="Build WG Meeting" -CALENDAR_ID="c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8@group.calendar.google.com" +ICAL_URL="https://calendar.google.com/calendar/ical/c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8%40group.calendar.google.com/public/basic.ics" USER="nodejs" REPO="build" AGENDA_TAG=build-agenda diff --git a/templates/meeting_base_cross_project_council b/templates/meeting_base_cross_project_council index cd5c3de..d80fa05 100644 --- a/templates/meeting_base_cross_project_council +++ b/templates/meeting_base_cross_project_council @@ -1,6 +1,5 @@ CALENDAR_FILTER="Cross Project Council Meeting" -CALENDAR_ID="c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8@group.calendar.google.com" -CALENDAR_ID="linuxfoundation.org_fuop4ufv766f9avc517ujs4i0g@group.calendar.google.com" +ICAL_URL="https://webcal.prod.itx.linuxfoundation.org/lfx/a0941000002wBygAAE" USER="openjs-foundation" HOST="OpenJS Foundation" REPO="cross-project-council" diff --git a/templates/meeting_base_diag b/templates/meeting_base_diag index ca9025b..eb92853 100644 --- a/templates/meeting_base_diag +++ b/templates/meeting_base_diag @@ -1,5 +1,5 @@ CALENDAR_FILTER="Diagnostics WG Meeting" -CALENDAR_ID="c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8@group.calendar.google.com" +ICAL_URL="https://calendar.google.com/calendar/ical/c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8%40group.calendar.google.com/public/basic.ics" USER="nodejs" REPO="diagnostics" GROUP_NAME="Diagnostics WorkGroup" diff --git a/templates/meeting_base_diag_deepdive b/templates/meeting_base_diag_deepdive index b985171..8c4b7ec 100644 --- a/templates/meeting_base_diag_deepdive +++ b/templates/meeting_base_diag_deepdive @@ -1,5 +1,5 @@ CALENDAR_FILTER="Diagnostics Deep Dive Meeting" -CALENDAR_ID="c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8@group.calendar.google.com" +ICAL_URL="https://calendar.google.com/calendar/ical/c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8%40group.calendar.google.com/public/basic.ics" USER="nodejs" REPO="diagnostics" GROUP_NAME="Diagnostics Deep Dive" diff --git a/templates/meeting_base_ecosystem_report b/templates/meeting_base_ecosystem_report index 1125ebf..a4db802 100644 --- a/templates/meeting_base_ecosystem_report +++ b/templates/meeting_base_ecosystem_report @@ -1,5 +1,5 @@ CALENDAR_FILTER="Ecosystem Report Collab Space" -CALENDAR_ID="linuxfoundation.org_fuop4ufv766f9avc517ujs4i0g@group.calendar.google.com" +ICAL_URL="https://webcal.prod.itx.linuxfoundation.org/lfx/a0941000002wBygAAE" USER="openjs-foundation" HOST="OpenJS Foundation" REPO="ecosystem-report-collab-space" diff --git a/templates/meeting_base_loaders b/templates/meeting_base_loaders index 9ab34aa..1d3780f 100644 --- a/templates/meeting_base_loaders +++ b/templates/meeting_base_loaders @@ -1,5 +1,5 @@ CALENDAR_FILTER="Loaders Team Meeting" -CALENDAR_ID="c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8@group.calendar.google.com" +ICAL_URL="https://calendar.google.com/calendar/ical/c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8%40group.calendar.google.com/public/basic.ics" USER="nodejs" REPO="loaders" GROUP_NAME="Loaders Team" diff --git a/templates/meeting_base_modules b/templates/meeting_base_modules index f77b4e4..c5063ff 100644 --- a/templates/meeting_base_modules +++ b/templates/meeting_base_modules @@ -1,5 +1,5 @@ CALENDAR_FILTER="Modules Team Meeting" -CALENDAR_ID="c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8@group.calendar.google.com" +ICAL_URL="https://calendar.google.com/calendar/ical/c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8%40group.calendar.google.com/public/basic.ics" USER="nodejs" REPO="modules" GROUP_NAME="Modules Team" diff --git a/templates/meeting_base_next-10 b/templates/meeting_base_next-10 index 74dbc77..e3f0c8f 100644 --- a/templates/meeting_base_next-10 +++ b/templates/meeting_base_next-10 @@ -1,5 +1,5 @@ CALENDAR_FILTER="Node.js Next 10 years" -CALENDAR_ID="c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8@group.calendar.google.com" +ICAL_URL="https://calendar.google.com/calendar/ical/c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8%40group.calendar.google.com/public/basic.ics" USER="nodejs" REPO="next-10" GROUP_NAME="Next 10 Years team" diff --git a/templates/meeting_base_outreach b/templates/meeting_base_outreach index 26204dc..9610261 100644 --- a/templates/meeting_base_outreach +++ b/templates/meeting_base_outreach @@ -1,5 +1,5 @@ CALENDAR_FILTER="Node.js Outreach Meeting" -CALENDAR_ID="c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8@group.calendar.google.com" +ICAL_URL="https://calendar.google.com/calendar/ical/c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8%40group.calendar.google.com/public/basic.ics" USER="nodejs" REPO="outreach" GROUP_NAME="Outreach" diff --git a/templates/meeting_base_package-maintenance b/templates/meeting_base_package-maintenance index de127ff..7c53749 100644 --- a/templates/meeting_base_package-maintenance +++ b/templates/meeting_base_package-maintenance @@ -1,5 +1,5 @@ CALENDAR_FILTER="Package Maintenance" -CALENDAR_ID="c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8@group.calendar.google.com" +ICAL_URL="https://calendar.google.com/calendar/ical/c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8%40group.calendar.google.com/public/basic.ics" USER="nodejs" REPO="package-maintenance" GROUP_NAME="Package Maintenance Team" diff --git a/templates/meeting_base_package_metadata_interop b/templates/meeting_base_package_metadata_interop index 5905b1a..d2afaab 100644 --- a/templates/meeting_base_package_metadata_interop +++ b/templates/meeting_base_package_metadata_interop @@ -1,5 +1,5 @@ CALENDAR_FILTER="Package Metadata Interoperability" -CALENDAR_ID="linuxfoundation.org_fuop4ufv766f9avc517ujs4i0g@group.calendar.google.com" +ICAL_URL="https://webcal.prod.itx.linuxfoundation.org/lfx/a0941000002wBygAAE" USER="openjs-foundation" HOST="OpenJS Foundation" REPO="package-metadata-interoperability-collab-space" diff --git a/templates/meeting_base_security-wg b/templates/meeting_base_security-wg index c70cd8d..c383abc 100644 --- a/templates/meeting_base_security-wg +++ b/templates/meeting_base_security-wg @@ -1,5 +1,5 @@ CALENDAR_FILTER="Security-WG meeting" -CALENDAR_ID="c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8@group.calendar.google.com" +ICAL_URL="https://calendar.google.com/calendar/ical/c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8%40group.calendar.google.com/public/basic.ics" USER="nodejs" REPO="security-wg" GROUP_NAME="Security team" diff --git a/templates/meeting_base_security_collab b/templates/meeting_base_security_collab index e54b14d..3599036 100644 --- a/templates/meeting_base_security_collab +++ b/templates/meeting_base_security_collab @@ -1,5 +1,5 @@ CALENDAR_FILTER="Security Collab Space meeting" -CALENDAR_ID="linuxfoundation.org_fuop4ufv766f9avc517ujs4i0g@group.calendar.google.com" +ICAL_URL="https://webcal.prod.itx.linuxfoundation.org/lfx/a0941000002wBygAAE" USER="openjs-foundation" HOST="OpenJS Foundation" REPO="security-collab-space" diff --git a/templates/meeting_base_standards b/templates/meeting_base_standards index 107dbdc..9e75b3f 100644 --- a/templates/meeting_base_standards +++ b/templates/meeting_base_standards @@ -1,5 +1,5 @@ CALENDAR_FILTER="Standards Working Group Meeting" -CALENDAR_ID="linuxfoundation.org_fuop4ufv766f9avc517ujs4i0g@group.calendar.google.com" +ICAL_URL="https://webcal.prod.itx.linuxfoundation.org/lfx/a0941000002wBygAAE" USER="openjs-foundation" HOST="OpenJS Foundation" REPO="standards" diff --git a/templates/meeting_base_sustainability_collab b/templates/meeting_base_sustainability_collab index 1c5767c..80cb5ba 100644 --- a/templates/meeting_base_sustainability_collab +++ b/templates/meeting_base_sustainability_collab @@ -1,5 +1,5 @@ CALENDAR_FILTER="Sustainability Collaboration Space" -CALENDAR_ID="linuxfoundation.org_fuop4ufv766f9avc517ujs4i0g@group.calendar.google.com" +ICAL_URL="https://webcal.prod.itx.linuxfoundation.org/lfx/a0941000002wBygAAE" USER="openjs-foundation" HOST="OpenJS Foundation" REPO="sustainability-collab-space" diff --git a/templates/meeting_base_tooling b/templates/meeting_base_tooling index 0028923..844cde1 100644 --- a/templates/meeting_base_tooling +++ b/templates/meeting_base_tooling @@ -1,5 +1,5 @@ CALENDAR_FILTER="Node.js Tooling" -CALENDAR_ID="c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8@group.calendar.google.com" +ICAL_URL="https://calendar.google.com/calendar/ical/c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8%40group.calendar.google.com/public/basic.ics" USER="nodejs" REPO="tooling" GROUP_NAME="Tooling Group" diff --git a/templates/meeting_base_tsc b/templates/meeting_base_tsc index 7b41a64..a5225ba 100644 --- a/templates/meeting_base_tsc +++ b/templates/meeting_base_tsc @@ -1,5 +1,5 @@ CALENDAR_FILTER="Node.js TSC Meeting" -CALENDAR_ID="c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8@group.calendar.google.com" +ICAL_URL="https://calendar.google.com/calendar/ical/c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8%40group.calendar.google.com/public/basic.ics" USER="nodejs" REPO="TSC" HOST="Node.js" diff --git a/templates/meeting_base_typescript b/templates/meeting_base_typescript index b2919d6..76477f5 100644 --- a/templates/meeting_base_typescript +++ b/templates/meeting_base_typescript @@ -1,5 +1,5 @@ CALENDAR_FILTER="TypeScript team meeting" -CALENDAR_ID="c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8@group.calendar.google.com" +ICAL_URL="https://calendar.google.com/calendar/ical/c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8%40group.calendar.google.com/public/basic.ics" USER="nodejs" REPO="typescript" GROUP_NAME="TypeScript team" diff --git a/templates/meeting_base_userfeedback b/templates/meeting_base_userfeedback index ee46718..b3999ee 100644 --- a/templates/meeting_base_userfeedback +++ b/templates/meeting_base_userfeedback @@ -1,5 +1,5 @@ CALENDAR_FILTER="Node.js User Feedback Meeting" -CALENDAR_ID="c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8@group.calendar.google.com" +ICAL_URL="https://calendar.google.com/calendar/ical/c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8%40group.calendar.google.com/public/basic.ics" USER="nodejs" REPO="user-feedback" GROUP_NAME="User Feedback" diff --git a/templates/meeting_base_uvwasi b/templates/meeting_base_uvwasi index ec3880a..58d8410 100644 --- a/templates/meeting_base_uvwasi +++ b/templates/meeting_base_uvwasi @@ -1,5 +1,5 @@ CALENDAR_FILTER="Node.js uvwasi team meeting" -CALENDAR_ID="c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8@group.calendar.google.com" +ICAL_URL="https://calendar.google.com/calendar/ical/c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8%40group.calendar.google.com/public/basic.ics" USER="nodejs" REPO="uvwasi" GROUP_NAME="uvwasi team" diff --git a/templates/meeting_base_web b/templates/meeting_base_web index fffa791..4490188 100644 --- a/templates/meeting_base_web +++ b/templates/meeting_base_web @@ -1,5 +1,5 @@ -CALENDAR_FILTER="Web Team Meeting" -CALENDAR_ID="c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8@group.calendar.google.com" +CALENDAR_FILTER="Web Team Monthly" +ICAL_URL="https://webcal.prod.itx.linuxfoundation.org/lfx/a092M00001IV4HSQA1" USER="nodejs" REPO="web-team" AGENDA_TAG=web-agenda diff --git a/templates/meeting_base_web-server-frameworks b/templates/meeting_base_web-server-frameworks index d69a14a..94d2e46 100644 --- a/templates/meeting_base_web-server-frameworks +++ b/templates/meeting_base_web-server-frameworks @@ -1,5 +1,5 @@ CALENDAR_FILTER="Web Server Frameworks" -CALENDAR_ID="c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8@group.calendar.google.com" +ICAL_URL="https://calendar.google.com/calendar/ical/c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8%40group.calendar.google.com/public/basic.ics" USER="nodejs" REPO="web-server-frameworks" GROUP_NAME="Web Server Frameworks"