{"id":15651713,"url":"https://github.com/jacobmischka/ics-merger","last_synced_at":"2025-04-19T13:50:32.423Z","repository":{"id":12468294,"uuid":"71906261","full_name":"jacobmischka/ics-merger","owner":"jacobmischka","description":"Package, cli tool, server, and web app to merge calendars together.","archived":false,"fork":false,"pushed_at":"2022-12-10T16:55:21.000Z","size":14916,"stargazers_count":37,"open_issues_count":25,"forks_count":8,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-10T06:42:14.851Z","etag":null,"topics":["calendar","fullcalendar","google-calendar","ics-files"],"latest_commit_sha":null,"homepage":"https://calendar.mcw-anesthesiology.tech","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jacobmischka.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-10-25T14:38:36.000Z","updated_at":"2025-02-26T05:12:45.000Z","dependencies_parsed_at":"2023-01-14T07:45:16.197Z","dependency_job_id":null,"html_url":"https://github.com/jacobmischka/ics-merger","commit_stats":null,"previous_names":[],"tags_count":43,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jacobmischka%2Fics-merger","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jacobmischka%2Fics-merger/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jacobmischka%2Fics-merger/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jacobmischka%2Fics-merger/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jacobmischka","download_url":"https://codeload.github.com/jacobmischka/ics-merger/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249282114,"owners_count":21243449,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["calendar","fullcalendar","google-calendar","ics-files"],"created_at":"2024-10-03T12:39:51.418Z","updated_at":"2025-04-19T13:50:32.398Z","avatar_url":"https://github.com/jacobmischka.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Calendar merger\n\nSuite of tools to merge multiple external calendars into a single view or a single file for importing.\n\n## Components\n\n### Package\n\n`dist/ical-merger*.js`\n\nDefault export is a relatively simple function that merges multiple .ics files into one.\n\n```javascript\nmerge(inputs, options);\n```\n\n```javascript\nicals = [\n\tfs.readFileSync('cal.ics', 'utf8'),\n\tfs.readFileSync('another.ics', 'utf8')\n];\nmerge(icals, {\n\tcalname: 'Merged Calendar',\n\ttimezone: 'America/Chicago',\n\tcaldesc: 'Two calendars put together'\n})\n```\n\nCalendar name, description, and timezone default to their respective values in the first calendar encountered (`inputs[0]`);\n\n### CLI tool\n\n`cli.js`\n\nA small wrapper for the underlying package.\n\n```sh\nical-merge \u003cfilenames...\u003e\n```\n\n```sh\nCALNAME=\"Merged Calendar\"\\\nTIMEZONE=\"America/Chicago\"\\\nCALDESC=\"Two calendars put together\"\\\nical-merge cal.ics another.ics\n```\n\nAccepts filenames, options are set by environment variables. Output is sent to stdout.\n\n### Web service\n\n`dist/server.js`\n\nWeb service that serves the calendar webapp and serves merged .ics files.\n\n`/combine.ics` accepts an array of URLs to externally-hosted .ics files, and responds with the merged file. URLs are specified with PHP-style array syntax: `?urls[]=…`.\n\nOther `/[ID].ics` merged files are returned, based on the [`.env.json`][env] configuration file.\n\n### Webapp\n\n`public/**/*`\n\nWebapp that displays public calendars from Google Calendar in a single view. Uses [FullCalendar][fullcalendar] heavily.\n\n![Webapp view](webapp.png)\n\n## Requirements\n\n### `.env.json`\n\nThe web service and the webapp require configuration via `.env.json` in the project's root\n\n```json\n{\n\t\"GOOGLE_CALENDAR_API_KEY\": \"[API KEY]\",\n\t\"GOOGLE_ANALYTICS_TRACKING_ID\": \"[ID]\",\n\t\"calendars\": {\n\t\t\"cal1\": {\n\t\t\t\"calname\": \"Calendar 1\",\n\t\t\t\"caldesc\": \"Calendar 1 desc\",\n\t\t\t\"timezone\": \"America/Chicago\",\n\t\t\t\"color\": \"#462aa3\",\n\t\t\t\"googleCalendarId\": \"[ID]@group.calendar.google.com\",\n\t\t\t\"url\": \"https://calendar.google.com/calendar/ical/[ID]%40group.calendar.google.com/public/basic.ics\"\n\t\t},\n\t\t\"cal2\": {\n\t\t\t\"calname\": \"Calendar 2\",\n\t\t\t\"caldesc\": \"Calendar 2 desc\",\n\t\t\t\"timezone\": \"America/Chicago\",\n\t\t\t\"color\": \"#001f3f\",\n\t\t\t\"subCalendars\": [\n\t\t\t\t{\n\t\t\t\t\t\"calname\": \"Subcalendar 1\",\n\t\t\t\t\t\"caldesc\": \"Subcalendar 1 desc\",\n\t\t\t\t\t\"timezone\": \"America/Chicago\",\n\t\t\t\t\t\"color\": \"#0074D9\",\n\t\t\t\t\t\"googleCalendarId\": \"[ID]@group.calendar.google.com\",\n\t\t\t\t\t\"url\": \"https://calendar.google.com/calendar/ical/[ID]%40group.calendar.google.com/public/basic.ics\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"calname\": \"Subcalendar 2\",\n\t\t\t\t\t\"caldesc\": \"Subcalendar 2 desc\",\n\t\t\t\t\t\"timezone\": \"America/Chicago\",\n\t\t\t\t\t\"color\": \"#7FDBFF\",\n\t\t\t\t\t\"googleCalendarId\": \"[ID]@group.calendar.google.com\",\n\t\t\t\t\t\"url\": \"https://calendar.google.com/calendar/ical/[ID]%40group.calendar.google.com/public/basic.ics\"\n\t\t\t\t}\n\t\t\t]\n\t\t}\n\t},\n\t\"calendarGroups\": {\n\t\t\"basic\": {\n\t\t\t\"calname\": \"Group Name\",\n\t\t\t\"caldesc\": \"Main calendar group\",\n\t\t\t\"timezone\": \"America/Chicago\",\n\t\t\t\"color\": \"#36a2eb\",\n\t\t\t\"calendars\": [\n\t\t\t\t\"cal1\",\n\t\t\t\t\"cal2\"\n\t\t\t]\n\t\t}\n\t},\n\t\"combine\": {\n\t\t\"calname\": \"Combined Calendar\",\n\t\t\"caldesc\": \"Combined calendar desc\",\n\t\t\"timezone\": \"America/Chicago\"\n\t}\n}\n```\nWebapp uses `googleCalendarId`s, web service uses `url`s.\n\n\n[FullCalendar instructions for Google Calendar API key and calendar IDs][fullcalendar-gcal]\n\n## Docker\n\n### Build\nTo build the Docker container run the following command in `./Docker`:\n\n1. `cd Docker`\n2. `cp example.env.json env.json`\n3. _(Edit `env.json` to your needs)_\n4. `docker build . -t ics-merger`\n\n### Run\nTo run the tool in a Docker-container build it first then run:\n\n`docker run -p 80:3000 -d -v $PWD/env.json:/ics-merger/env.json:ro ics-merger`\n\nWhere `env.json` is your configured file.\n\n[env]: #envjson\n[fullcalendar]: https://fullcalendar.io\n[fullcalendar-gcal]: https://fullcalendar.io/docs/google_calendar/\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjacobmischka%2Fics-merger","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjacobmischka%2Fics-merger","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjacobmischka%2Fics-merger/lists"}