Some CalDAV server doesn't provide ICAL format, so it cannot be used on MM's calendar modules.
This module enables to convert your CalDAV calendar data into popular ICAL(.ics) file. Converted ICAL output is hosted on MM itself.
For previous users: ~2.0 is newly rebuilt from scratch. You may need a new installation and configuration.
cd ~/MagicMirror/modules
git clone https://github.com/MMRIZE/MMM-CalDAV
cd MMM-CalDav
npm installBefore update, backup your
.envfile into somewhere safe.
cd ~/MagicMirror/modules/MMM-CalDAV
git pull
npm updateYou have to read
.envand Preparation Section also.
{
module: "MMM-CalDAV", // This module works in background, so `position` is not needed.
config: {
timeRangeStart: -30, // Get events from 30 days before
servers: [
{ // example of icloud or basic auth
envPrefix: "ICLOUD_", // prefix for identifying each server
serverUrl: "https://caldav.icloud.com", // Ask to your CALDAV provider
targets: [
{ displayName: "Family" },
{ displayName: "Home", icsName: "home_calendar" },
"Work",
],
},
{ // example of Google Calendar.
envPrefix: "GOOGLE_",
serverUrl: "https://apidata.googleusercontent.com/caldav/v2/",
authMethod: 'Oauth',
targets: [],
updateInterval: 1000 * 60 * 30,
},
{ // example of synology contacts
envPrefix: "SYNOLOGY_",
serverUrl: "http://mynas.ddns.me:5000/carddav/USERNAME/a1234567-ef5b-4d4a-b742-9d3e5886d229"
targets: [ "Team Contacts", "Partners"]
},
],
}
},- event
Then it will provide the ICAL URL like;
http://localhost:8080/CALDAV/ICLOUD_Family.ics
http://localhost:8080/CALDAV/ICLOUD_home_calendar.ics
http://localhost:8080/CALDAV/ICLOUD_Work.ics
http://localhost:8080/CALDAV/SYNOLOGY_Team_Contacts.ics
...
The Generated URL will have a sanitized-safe filename/url. For example the calendar name 회사 will be converted to _ED_9A_8C_EC_82_AC. So It's better to use icsName to avoid it and to get an easier name if you are a non-English user.
Each calendar would prepend envPrefix in the front of the filename to distinguish each other easily. (like ICLOUD_xxx.ics)
You can use the URL as a feed of the calendar module(e.g. default calendar module)
{
module: "calendar",
position: "top_left",
config: {
servers: [
{
symbol: "calendar-check",
url: "http://localhost:8080/CALDAV/ICLOUD_Family.ics",
auth: { // REQUIRED
user: 'username1', // DEFINED in .env file.
pass: 'password1',
method: 'basic'
}
},
...The real extracted & parsed result will be stored under modules/MMM-CalDAV/service as a hidden .ics file. If you need to reset the previously stored data, just delete them there.
| Field | Default | Description |
|---|---|---|
servers |
[] | REQUIRED Array of CalDAV server |
updateInterval |
900000 | (ms) Interval to rescan and update the result. Default value is 15 minutes. |
timeRangeStart |
-365 | (days) Get the events before these days from today. |
timeRangeEnd |
365 | (days) Get the events until these days since today. |
updateInterval,timeRangeStart,timeRangeEndcould be overridden in each server.timeRangeStartandtimeRangeEndwill be ignored inaccountType: 'carddav'.
| Field | Default | Description |
|---|---|---|
accountType |
'caldav' | REQUIRED To retrieve normal calendar events. |
envPrefix |
'DEFAULT_' | REQUIRED To match .env variables, each server should have unique one. |
serverUrl |
'' | REQUIRED CalDAV service url of the server. |
authMethod |
'Basic' | For Google Calendar, use 'Oauth' |
timeRangeStart |
config value | You can override speicfic days for this server. |
timeRangeEnd |
config value | You can override speicfic days for this server. |
updateInterval |
config value | You can override the specific interval for this server. |
| Field | Default | Description |
|---|---|---|
accountType |
'carddav' | IMPORTANT/REQUIRED To get birthday events from addressbook. |
envPrefix |
'DEFAULT_' | REQUIRED To match .env variables, each server should have unique one. |
serverUrl |
'' | REQUIRED CardDAV service url of the server. It may different with CalDAV endpoint. |
authMethod |
'Basic' | For Google Calendar, use 'Oauth' |
updateInterval |
config value | You can override the specific interval for this server. |
targets |
[] | (Array of string/object) addressBook filter by its name. [] would be all addressBooks. |
There would be more properties, but 99.99% of users would not need them. But if you have interest, see the belows;
| Field | Default | Description |
|---|---|---|
expand |
true | Forcing the server to expand recurring components into individual calendar objects. If you have some trouble with REPEATED EVENTS, try this to false} |
useMultiGet |
true | This is used to retrieve specific calendar object resources from within a collection. Usually you don't have to change this. |
targets: [ ... ] array could have string(the name of calendar/addressBook) or object(A pair of original calendar/addressBook name and the result ics name)
envPrefix: 'SOME_', // for example.
targets: [ "Family", "Work" ], // Get events from "Family" and "Work" calendar/addressBook then will serve them as "SOME_Family.ics" and "SOME_Work.ics"
// or
targets: [
{ displayName: "Family", icsName: "private" }, // Get events from "Family" calendar/addressBook then will serve them as "SOME_private.ics"
{ displayName: "Work", icsName: "company" }, // Get events from "Work" calendar/addressBook then will serve them as "Some_company.ics"
],
targets: [], // Get events from all calendars/addressBooks then will serve them as "SOME_ORIGINALNAME.ics"Some CardDAV provider doesn't support
displayName. in that case, the birthday calendar of that will be served as "SOME_untitled.ics"
The birthday list from Google is already possible by natural. So, you don't care about
CardDAVof Google. Seek a calendar which hasBirthdaysasdisplayNamein your result.
For the security issue, this module is using .env file to store some secret data.
Open .env file in module directory. (If not exists, copy one from env.example)
Remove # from a line commented-out you need.
CALDAV_SERVICE_USERNAME=username1
CALDAV_SERVICE_PASSWORD=password1REQUIRED
- CALDAV_SERVICE_USERNAME : Used for generated .ics auth in the calendar parser.
- CALDAV_SERVICE_PASSWORD : Used for generated .ics auth in the calendar parser
// default calendar module.
{
module: "calendar",
position: "top_left",
config: {
calendars: [
{
symbol: "calendar-check",
url: "http://localhost:8080/CALDAV/ICLOUD_Family.ics",
auth: { // REQUIRED
user: 'username1', // <= used here
pass: 'password1', // <= used here
method: 'basic'
}
},
...You need app-specific password to use this module. Read this
# .env
ICLOUD_username=[email protected]
ICLOUD_password=abcd-efgh-ijkl-mnop// MMM-CalDAV config in config.js
config: {
servers: [
{
envPrefix: 'ICLOUD_', // prefix for identifying each server
serverUrl: 'https://caldav.icloud.com', // for normal calendar
...config: {
servers: [
{
accountType: 'carddav',
envPrefix: "ICLOUD_", // prefix for identifying server. You can share this with iCloud CalDav
serverUrl: 'https://contacts.icloud.com', // for birthday list
...You need third-party app password. Here
Then rest setup would be similar to Apple.
- serverUrl: https://caldav.calendar.yahoo.com
Yahoo doesn't support
CardDAVanymore.
https://www.fastmail.help/hc/en-us/articles/1500000278342
- serverUrl: https://caldav.fastmail.com/
- serverUrl for CardDAV : https://carddav.fastmail.com/ Then the rest setup would be similar to Apple.
- serverUrl: Ask to the system admin or user manual. Then rest setup would be similar to Apple.
Google request OAuth2 authentification to use the calendar data.
-
Go to Google Dev console.
-
Create a new project or select existing project.
-
MENU >
APIs & Services>Library; SearchCalDAV APIthen enaable API for your project. -
MENU >
APIs & Services>credentials; Create a credentials(OAuth Client IdforDesktop app) -
Only you need is
Client IDandClient Secret, just remember them. All other properties or options are not so important. (You may have to register the user who will use this module for his/her calendars inTestingstatus) -
Fill the below values;
# .env
AUTH_authHost=http://localhost
AUTH_authPort=3000
GOOGLE_tokenUrl=https://accounts.google.com/o/oauth2/token
GOOGLE_username=[email protected]
GOOGLE_clientId=99999999-abcd1234h92het5hsfbec5c3dnifeo9c.apps.googleusercontent.com
GOOGLE_clientSecret=AAAAA-abcd1234uLweeQL2mwHMuWMxXwIA
GOOGLE_refreshToken=For AUTH_authHost and AUTH_authPort, you don't have to modify these values generally. These values will be used in google_auth.js
You have to fill XXXX_username, XXXX_clientId, XXXX_clientSecret with your previous preparation for Google OAuth. and you don't need to fill refreshToken at this moment. In this example, GOOGLE_ is used as server prefix.
- Then, execute
google_auth.js
cd ~/MagicMirror/modules/MMM-CalDAV
node google_auth.js GOOGLE_You are using GOOGLE_ as server environment prefix, so add it as a parameter.
It will open a browser, then start authentification.
After authentification, you can get refreshToken, Fill that into your .env file.
% node google_auth.js GOOGLE_
Server listening on http://localhost:3000, When the browser is not opened, open it manually
Your refresh token is: "1//09AbCdEfGh30tCgYIARAAGAkSNwF-L9IrUHWoAvpHPzQ_LYybJZbo8pjG_oCdfWc33lu5alklJgeUWLAfCCRhbCfa7IgAbCdEfGh"
Please add it to your .env file as "GOOGLE_refreshToken".
- Fill remaining refreshToken value.
# .env
AUTH_authHost=http://localhost
AUTH_authPort=3000
GOOGLE_tokenUrl=https://accounts.google.com/o/oauth2/token
GOOGLE_username=[email protected]
GOOGLE_clientId=99999999-abcd1234h92het5hsfbec5c3dnifeo9c.apps.googleusercontent.com
GOOGLE_clientSecret=AAAAA-abcd1234uLweeQL2mwHMuWMxXwIA
GOOGLE_refreshToken=1//09AbCdEfGh30tCgYIARAAGAkSNwF-L9IrUHWoAvpHPzQ_LYybJZbo8pjG_oCdfWc33lu5alklJgeUWLAfCCRhbCfa7IgAbCdEfGh- Then you can configure your module config like this;
// MMM-CalDAV config in config.js
config: {
servers: [
{
envPrefix: "GOOGLE_", // prefix for identifying each server
serverUrl: "https://apidata.googleusercontent.com/caldav/v2/",
authMethod: 'Oauth', // <= IMPORTANT
...Thankfully, Google provide Birthday of contacts as calendar by default. You can find
Birthdayscalendar in the result. Or specify it withdisplayName:'Birthdays'
You can add more servers. Just keep the prefixes.
# .env
SERVER1_username=[email protected]
SERVER1_password=abcd-efgh-ijkl-mnop
SERVER2_username=johndoe1234
SERVER2_password=abcd1234// MMM-CalDAV config
servers: [
{
envPrefix: "SERVER1_",
serverUrl: "https://caldav.somewhere.com",
},
{
envPrefix: "SERVER2_",
serverUrl: "https://otherwhere.com/caldav",
},
],- Connecting to CalDAV server and getting calendar data might take some time. So on the first bootup after installation of this module, the calendar module could not load any data. Please wait a while for the next updating cycle. After the first ICAL file, the events will be reflected on the next calendar's update time regardless of rebooting.
- I have not tested all the possible CalDAV servers. So if you can find any issue on the various CalDAVs, feel free to make a PR for it.
- For the purpose of this module, the generated
.icsis designed to be hidden and not accessible without auth intentionally. You should useCALDAV_SERVER_USERNAMEandCALDAV_SERVER_PASSWORDwithBasicauth to access that URL. - If the name of generated
.icsis duplicated, it will be overwritten. Separate them withicsNameby manual. - At this moment, all address books will be retrieved. Filtering is not supported. (I need help to get real examples to know the multi-addressbooks structure.)
https://github.com/MMRIZE/MMM-CalDAV/wiki
- ADD: Revealing URL on
google_authscript to open the browser by hand. - ADD: Description of hidden properties of config. (#9)
- ADD:
eslintthings - UPDATE: some dependencies
- Seongnoh Yi ([email protected])