├── LICENSE ├── README.md └── services ├── aol.md ├── google.md ├── outlook-web.md └── yahoo.md /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 The Interaction Design Foundation 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # About "Add event to a calendar" repository 2 | 3 | This repository contains community-driven documents that describe how to add events 4 | to different online calendar services that usually don't have an official 5 | documentation/specs. 6 | 7 | The primary goal of this repository is to consolidate the efforts of 8 | developers to debugging/reverse-engineering calendar services to find 9 | possible parameters and features that we can use in our products. 10 | 11 | Usually, 3rd party services don't provide verbose documentation on how to create 12 | calendar events using GET parameters. The main goal is to find available options — reverse-engineering. 13 | 14 |
15 | 16 | ## Docs for Services 17 | 18 | 1. [Google calendar](/services/google.md) 19 | 1. [Yahoo calendar](/services/yahoo.md) 20 | 1. [Outlook Web](/services/outlook-web.md) 21 | 1. [AOL](/services/aol.md) 22 | 23 | 24 | ## Popular packages 25 | 26 | ### JavaScript 27 | 28 | 1. [add2cal/add-to-calendar-button](https://github.com/add2cal/add-to-calendar-button) An up-to-date ValillaJS script to render "add to calendar" buttons from simple JSON. 29 | 1. [carlsednaoui/add-to-calendar-buttons](https://github.com/carlsednaoui/add-to-calendar-buttons) A simple ValillaJS library to add an "add to calendar" buttons for events. 30 | 1. [jojoee/add2calendar](https://github.com/jojoee/add2calendar) A simple ValillaJS library that allows you to add event to calendar easier 31 | 1. [AnandChowdhary/calendar-link](https://github.com/AnandChowdhary/calendar-link) NPM package for generating calendar links for both Node.js and browsers 32 | 1. [AnandChowdhary/add-to-calendar](https://github.com/AnandChowdhary/add-to-calendar) A library that allows you to send invites to calendar events easier 33 | 1. [jshor/datebook](https://github.com/jshor/datebook) An npm module that generates downloadable iCalendar files and URLs for adding events to popular calendar apps. 34 | 35 | 36 | ### PHP 37 | 38 | 1. [spatie/calendar-links](https://github.com/spatie/calendar-links) A package to create "Add event to calendar" links 39 | 40 | 41 | ### Ruby 42 | 43 | 1. [jaredlt/add_to_calendar](https://github.com/jaredlt/add_to_calendar) A ruby gem to generate 'Add To Calendar' URLs for Apple, Google, Office 365, Outlook, Outlook.com and Yahoo calendars 44 | 45 | _List your package/repo here_ 46 | 47 | 48 | ## Materials & Links 49 | 1. [Online calendar link generator](https://stripo.email/calendar-link-generator/) 50 | 1. [How to Create an “Add to Calendar” Link for Your Emails](https://litmus.com/blog/how-to-create-an-add-to-calendar-link-for-your-emails) 51 | -------------------------------------------------------------------------------- /services/aol.md: -------------------------------------------------------------------------------- 1 | # AOL 2 | 3 | ## Official documentation 4 | Not found. 5 | 6 | ## Basic URL 7 | 8 | `https://calendar.aol.com/` 9 | 10 | ## Parameters 11 | 12 | ### v 13 | required: yes 14 | 15 | type: enum. Possible values: 16 | - `60` 17 | 18 | ### title 19 | required: yes 20 | 21 | type: string 22 | 23 | ### st 24 | required: yes 25 | 26 | type: datetime 27 | 28 | ### et 29 | required: yes 30 | 31 | type: datetime 32 | 33 | ### desc 34 | required: no 35 | 36 | type: string 37 | 38 | ### in_loc 39 | required: no 40 | 41 | type: string 42 | 43 | ### dur 44 | required: no 45 | 46 | type: enum. Possible values: 47 | - `allday` 48 | - `false` (default) 49 | -------------------------------------------------------------------------------- /services/google.md: -------------------------------------------------------------------------------- 1 | # Google 2 | 3 | ## Official documentation 4 | 5 | Google has updated their official [Google Calendar API documentation](https://developers.google.com/calendar) for v3 including an updated [events reference](https://developers.google.com/calendar/api/v3/reference/events). The updated documentation also includes a [guide for creating events](https://developers.google.com/calendar/api/guides/create-events). 6 | 7 | Other helpful resources: 8 | * [Google Calendar Help](https://support.google.com/calendar/?hl=en#topic=10509740) 9 | * [Share your calendar with someone](https://support.google.com/calendar/answer/37082) 10 | * [Add a Google calendar to your website](https://support.google.com/calendar/answer/41207) 11 | 12 | ## Basic URL 13 | `https://calendar.google.com/calendar/render` or `https://calendar.google.com/calendar/r/eventedit` 14 | 15 | [Add a test event](https://calendar.google.com/calendar/render?action=TEMPLATE&text=Birthday&dates=20201231T193000Z/20201231T223000Z&details=With%20clowns%20and%20stuff&location=North%20Pole) 16 | 17 | ## Parameters 18 | 19 | ### action 20 | required: yes 21 | 22 | format: string/eval 23 | 24 | possible values: `TEMPLATE` 25 | 26 | example: `action=TEMPLATE` 27 | 28 | description: A default required parameter. (If you're using `https://calendar.google.com/calendar/r/eventedit`, this parameter is not required.) 29 | 30 | ### text 31 | required: yes 32 | 33 | format: text 34 | 35 | example: `text=Birthday` 36 | 37 | description: event title. 38 | 39 | ### dates 40 | required: yes 41 | 42 | format: `YYYYMMDDTHHmmSSZ/YYYYMMDDTHHmmSSZ` 43 | 44 | example: `dates=20201231T193000Z/20201231T223000Z` 45 | 46 | description: gives the start and end dates and times (in Greenwich Mean Time) for the event. 47 | Dates must have both start and end time or it won't work. 48 | The start and end date can be the same (if appropriate). 49 | Special cases: 50 | - to use the user's timezone: `20201231T193000/20201231T223000` (don't specify a timezone); 51 | - to use UTC timezone, convert datetime to UTC, then use `Z` suffix: `20201231T193000Z/20201231T223000Z`; 52 | - for all-day events use `20201231/20210101`. You must use the following date as the end date for a one day all day event, or +1 day to whatever you want the end date to be. 53 | 54 | ### ctz 55 | required: no 56 | 57 | format: [timezone name](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) 58 | 59 | example: `ctz=America/New_York` 60 | 61 | description: custom timezone. 62 | 63 | ### details 64 | required: no 65 | 66 | format: text 67 | 68 | example: `details=With clowns and stuff` 69 | 70 | description: description of your event. 71 | 72 | ### location 73 | required: no 74 | 75 | format: text 76 | 77 | example: `location=North Pole` 78 | 79 | description: set location of the event. 80 | Make sure it's an address google maps can read easily. 81 | 82 | ### crm 83 | 84 | required: no 85 | 86 | possible values: `AVAILABLE`, `BUSY`, `BLOCKING` 87 | 88 | format: string 89 | 90 | example: `crm=AVAILABLE` 91 | 92 | description: if Free, Busy, or Out of Office respectively. 93 | 94 | ### trp 95 | 96 | required: no 97 | 98 | possible values: `true`, `false` 99 | 100 | format: string 101 | 102 | example: `trp=false` 103 | 104 | description: Show event as busy (true) or available (false). 105 | Stands for [RFC 5545 transparency](https://tools.ietf.org/html/rfc5545#section-3.8.2.7). 106 | It's ignored for all day events, please refer to `crm` instead. 107 | 108 | 109 | ### sprop 110 | required: no 111 | 112 | format: key-value 113 | 114 | example: `sprop=website:www.santa.org&sprop=name:Sata-online` 115 | 116 | description: identify the website or event source 117 | 118 | ### add 119 | required: no 120 | 121 | format: text (comma-separated emails) 122 | 123 | example: `add=elf1@example.com,elf2@example.com` 124 | 125 | description: a list of guests (comma-separated). 126 | 127 | ### src 128 | required: no 129 | 130 | format: text (email) 131 | 132 | example: `src=santa@example.com` 133 | 134 | description: add an event to a shared calendar rather than a user's default. 135 | 136 | 137 | ### recur 138 | required: no 139 | 140 | format: text ([RFC-5545 specs](https://icalendar.org/iCalendar-RFC-5545/3-8-5-3-recurrence-rule.html)) 141 | 142 | example: `recur=RRULE:FREQ=DAILY` 143 | 144 | description: set recurring events. 145 | 146 | 147 | ## Tools 148 | 1. [Google calendar link generator](http://kalinka.tardate.com/) 149 | 1. [Google calendar link generator](http://output.jsbin.com/xujuluw) 150 | 151 | -------------------------------------------------------------------------------- /services/outlook-web.md: -------------------------------------------------------------------------------- 1 | # Outlook live 2 | 3 | ## Official documentation 4 | There is no official documentation. 5 | 6 | ## Basic URL 7 | Outlook Live: 8 | `https://outlook.live.com/calendar/deeplink/compose` 9 | 10 | Office 365: 11 | `https://outlook.office.com/calendar/deeplink/compose` 12 | 13 | ### Example 14 | 15 | Outlook Live: 16 | `https://outlook.live.com/calendar/deeplink/compose?path=/calendar/action/compose&rru=addevent&startdt=2023-08-09T19:30:00Z&enddt=2023-08-09T22:30:00Z&subject=Birthday&body=With%20clowns%20and%20stuff&location=North%20Pole` 17 | 18 | Office 365: 19 | `https://outlook.office.com/calendar/deeplink/compose?path=/calendar/action/compose&rru=addevent&startdt=2023-08-09T19:30:00Z&enddt=2023-08-09T22:30:00Z&subject=Birthday&body=With%20clowns%20and%20stuff&location=North%20Pole` 20 | 21 | ## Parameters 22 | 23 | ### path 24 | required: yes 25 | 26 | format: string 27 | 28 | example: `path=/calendar/action/compose` 29 | 30 | description: internal application path. 31 | 32 | ### rru 33 | required: yes 34 | 35 | format: string (`addevent`) 36 | 37 | example: `rru=addevent` 38 | 39 | description: action name. 40 | 41 | ### startdt 42 | required: yes 43 | 44 | format: datetime (`YYYY-MM-DDTHH:mm:SSZ`) or date (`YYYY-MM-DD`, for all-day events) in UTC 45 | 46 | example: `startdt=2020-12-31T19:30:00Z` 47 | 48 | description: The start date for the event. 49 | You can omit trailing `Z`, in this case script assumes that time specified in current user's timezone. 50 | To specify all-day events use the `YYYY-MM-DD` format. 51 | 52 | ### enddt 53 | required: yes 54 | 55 | format: datetime (`YYYY-MM-DDTHH:mm:SSZ`) or date (`YYYY-MM-DD`, for all-day events) in UTC 56 | 57 | example: `enddt=2020-12-31T22:30:00Z` 58 | 59 | description: The end time of the event, format as for `startdt`. 60 | 61 | ### subject 62 | required: yes 63 | 64 | format: string 65 | 66 | example: `subject=Birthday` 67 | 68 | description: event title. 69 | 70 | ### allday 71 | required: no 72 | 73 | format: boolean (`true`/`false`) 74 | 75 | example: `allday=true` 76 | 77 | description: whether event is all-day or not. 78 | 79 | ### body 80 | required: no 81 | 82 | format: text 83 | 84 | example: `body=With clowns and stuff` 85 | 86 | description: description of your event 87 | 88 | ### location 89 | required: no 90 | 91 | format: string 92 | 93 | example: `location=North Pole` 94 | 95 | description: set the location of the event. 96 | 97 | ### online 98 | required: no 99 | 100 | format: boolean (any value means `true`) 101 | 102 | description: toggle the "Skype meeting" button. 103 | 104 | example: `online=1` 105 | 106 | ### to 107 | required: no 108 | 109 | format: string 110 | 111 | description: A comma-separated list of emails of required attendees. 112 | 113 | example: `to=santa@example.com,easter.bunny@example.com` 114 | 115 | ### cc 116 | format: string 117 | 118 | description: A comma-separated list of emails of optional attendees. 119 | 120 | example: `cc=santa@example.com,easter.bunny@example.com` 121 | 122 | 123 | ### reqresponse 124 | format: string 125 | 126 | example: `reqresponse=true` 127 | 128 | ### allowfw 129 | format: boolean ("true"/"false") 130 | 131 | description: Allow forwarding. 132 | 133 | example: `allowfw=true` 134 | 135 | ### hideattn 136 | format: boolean ("true"/"false") 137 | 138 | description: Hide attendee list. 139 | 140 | example: `hideattn=true` 141 | 142 | 143 | ### freebusy 144 | format: string (enum) 145 | 146 | options: 147 | - `free` 148 | - `tentative` 149 | - `busy` 150 | - `oof` 151 | - `workingelsewhere` 152 | - `nodata` 153 | 154 | ### online 155 | format: any 156 | 157 | Description: "Skype meeting" flag. 158 | 159 | ### folderid 160 | description: Unknown, probably Event id. 161 | -------------------------------------------------------------------------------- /services/yahoo.md: -------------------------------------------------------------------------------- 1 | # Yahoo 2 | 3 | ## Official documentation 4 | There is no official documentation. 5 | 6 | ## Basic URL 7 | 8 | `https://calendar.yahoo.com/` 9 | 10 | [Add a test event](https://calendar.yahoo.com/?v=60&TITLE=Birthday&ST=20201231T193000&ET=20201231T223000&DESC=With%20clowns%20and%20stuff&in_loc=North%20Pole&inv_list=John+Doe+%3Cjohn@example.com%3E,Jane+Doe+%3Cjane@example.com%3E) 11 | 12 | ## Parameters 13 | 14 | ### v 15 | required: yes 16 | 17 | format: number 18 | 19 | example: `v=60` 20 | 21 | description: Must be 60. Possibly a version number? 22 | 23 | ### TITLE 24 | required: yes 25 | 26 | format: text 27 | 28 | example: `TITLE=Birthday` 29 | 30 | description: Event title. 31 | Line feeds will appear in the confirmation screen, but will not be saved. 32 | May not contain HTML. 33 | 34 | ### ST 35 | required: yes 36 | 37 | format: datetime (ISO8601) 38 | 39 | example: `ST=20201231T193000Z` 40 | 41 | description: Event start time. Options: 42 | 43 | - `20201231T193000Z`: Event start time in UTC. Will be converted to the user's time zone. 44 | - `20201231T193000`: Event start time in user's local time 45 | - `20201231`: Event start time for an all day event. `DUR` value is ignored if this form is used. 46 | 47 | ### ET 48 | 49 | required: yes 50 | 51 | format: datetime (ISO8601) 52 | 53 | example: `ET=20201231T193000Z` 54 | 55 | description: Event end time. Options the same as for `st` parameter. 56 | 57 | Note that `dur` parameter will be ignored if `et` is specified. 58 | 59 | ⚠️ This parameter appears to be broken with respect to timezones (need to confirm). 60 | 61 | ### dur 62 | 63 | required: no 64 | 65 | status: appears to no longer work 66 | 67 | format: time (`HHmm`) or `allday` 68 | 69 | example: `dur=0200` 70 | 71 | description: Duration of the event. 72 | Format is `HHmm`, zero-padded. 73 | `mm` may range up to 99, and is converted into hours appropriately. 74 | `HH` values over 24 hours appear to be modulated by 24. 75 | Durations that span midnight behave strangely. 76 | Leave this blank if the event has no specific end time, or if this is an all-day event. 77 | Note that `dur` parameter will be ignored if `et` is specified. 78 | Used only when `et` is not specified OR value is `allday`. 79 | 80 | Note that the maximum duration yahoo can except is 99 hours and 59 minutes due to the limitation of the format. 81 | 82 | ### ~type~ 83 | required: no 84 | 85 | status: propably not supported anymore (or format is changed) 86 | 87 | format: number 88 | 89 | example: `type=10` 90 | 91 | description: event's type 92 | - 11 Anniversay 93 | - 10 Appointment (default) 94 | - 12 Bill Payment 95 | - 13 Birthday 96 | - 27 Breakfast 97 | - 14 Call 98 | - 19 Chat 99 | - 37 Class 100 | - 26 Club Event 101 | - 24 Concert 102 | - 29 Dinner 103 | - 15 Graduation 104 | - 30 Happy Hour 105 | - 16 Holiday 106 | - 17 Interview 107 | - 28 Lunch 108 | - 18 Meeting 109 | - 23 Movie 110 | - 21 Net Event 111 | - 20 Other 112 | - 31 Party 113 | - 32 Performance 114 | - 33 Reunion 115 | - 34 Sports Event 116 | - 25 Travel 117 | - 22 TV Show 118 | - 35 Vacation 119 | - 36 Wedding 120 | 121 | ### DESC 122 | required: no 123 | 124 | format: text 125 | 126 | example: `DESC=With clowns and stuff` 127 | 128 | description: description of your event. 129 | This may contain line breaks (encoded in the usual manner, these become %0A). 130 | This may contain HTML, but all tags will be stripped out. 131 | This appears to accept quite a large amount of text, 132 | considering that it is being passed through on a query string. 133 | 134 | ### ~url~ 135 | required: no 136 | 137 | status: propably not supported anymore (there is no input for URL in a form) 138 | 139 | format: URL 140 | 141 | example: `URL=https://example.com` 142 | 143 | description: If present, the URL will be used to create a link out of the event title. 144 | 145 | ### in_loc 146 | required: no 147 | 148 | format: text 149 | 150 | example: `in_loc=North Pole` 151 | 152 | description: event location. 153 | 154 | ### in_st 155 | required: no 156 | 157 | format: text 158 | 159 | example: `in_st=Main str.` 160 | 161 | description: Street address. 162 | 163 | ### in_csz 164 | required: no 165 | 166 | format: text 167 | 168 | example: `in_csz=Atlanta, GA, 30307` 169 | 170 | description: City / State / Zip. 171 | 172 | ### in_ph 173 | required: no 174 | 175 | format: text 176 | 177 | example: `in_ph=404-589-1228` 178 | 179 | description: Phone. 180 | 181 | ### ~RPAT~ 182 | required: no 183 | 184 | format: text 185 | 186 | status: **deprecated** as of August 2021 187 | 188 | example: `RPAT=01Wk` 189 | 190 | description: Used to specify a recurring event. 191 | If this is present, then `REND` is also required. 192 | Examples: 193 | - Day: `01Dy` 194 | - Week: `01Wk` 195 | - Month: `01Mh` 196 | - Year: `01Yr` 197 | - Mon Wedn Fri: `01WkMoWeFr` 198 | - Tues Thurs: `01WkTuTh` 199 | - Mon – Fri: `01WkMoTuWeThFr` 200 | - Sat – Sun: `01WkSuSa` 201 | - Sat – Sun: `01WkSuSa` 202 | - Second Tuesday of every month: `01Mh2Tu` 203 | 204 | 205 | ### REND 206 | required: no (yes if `RPAT` specified) 207 | 208 | format: datetime (`YYYYMMDD`) 209 | 210 | example: `REND=20191231` 211 | 212 | description: Used to specify when a recurring event pattern ends. 213 | Date format: `YYYYMMDD` 214 | 215 | 216 | ### invId 217 | 218 | required: no 219 | 220 | format: text 221 | 222 | example: `` 223 | 224 | description: ? 225 | 226 | ### inv_list 227 | 228 | required: no 229 | 230 | format: string 231 | 232 | example: to=santa@example.com,easter.bunny@example.com 233 | 234 | description: A comma-separated list of emails of attendees. 235 | 236 | ### recurId 237 | 238 | required: no 239 | 240 | format: text 241 | 242 | example: `` 243 | 244 | description: ? 245 | 246 | 247 | ### rem1 248 | required: no 249 | 250 | format: text (length 2 or 3): `{NUMBER}`[`D`|`H`|`M`] 251 | 252 | example: `rem1=1D` (`1D` means 1day) 253 | 254 | description: When reminder 1 should be sent. Set to 0D for no reminder. 255 | 256 | 257 | ### rem2 258 | required: no 259 | 260 | format: text (length 2 or 3): `{NUMBER}`[`D`|`H`|`M`] 261 | 262 | example: `rem2=6H` 263 | 264 | description: When reminder 2 should be sent. Cannot have a reminder 2 without a reminder 1. 265 | 266 | 267 | ### ~remadr~ 268 | required: no 269 | 270 | status: deprecated 271 | 272 | format: text 273 | 274 | example: `remadr=some@example.com` 275 | 276 | description: Probably setup an email address to send notification for a reminder. 277 | 278 | 279 | ### ~msngr~ 280 | required: no 281 | 282 | status: deprecated. Only `true` makes sense, but it's `true` by default. 283 | 284 | format: `true`/`false` 285 | 286 | description: Probably enables messenger notification for a reminder. 287 | 288 | 289 | ### uid 290 | required: no 291 | 292 | format: text 293 | 294 | example: `uid=750e0c92aa33a7382460a280c2dfb8e6` 295 | 296 | description: Unique event ID. Using it, you can change existing events, do not add a new one. 297 | --------------------------------------------------------------------------------