Skip to content

Commit 9d6b566

Browse files
authored
Add README.md
1 parent 10c515b commit 9d6b566

File tree

4 files changed

+165
-3
lines changed

4 files changed

+165
-3
lines changed

README.md

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
# 📅 ScheduleQuest
2+
3+
![The ScheduleQuest landing page](https://github.com/leoherzog/ScheduleQuest/blob/main/img/landing.png?raw=true)
4+
5+
## What is this?
6+
7+
ScheduleQuest is a free, open-source web app to distribute to your recipients for scheduling with your Google Calendar, built on Google Apps Script. The Calendlys/cal.coms/YouCanBook.Mes of the world charge for the features you need, and [Google Calendar's built-in Appointment Scheduling](https://www.wired.com/story/calendly-google-calendar-appointment-schedule/) is a bit limited in customizability.
8+
9+
![Scheduling a meeting in ScheduleQuest](https://github.com/leoherzog/ScheduleQuest/blob/main/img/scheduling.png?raw=true)
10+
11+
### Features
12+
13+
- 🌐 Create a unique link that others can use to book an appointment on your Google Calendar
14+
- 📑 Offer mulitple types of meetings, each with their own configurable timeframe and event settings
15+
- 📒 Place events on any calendar you have edit access to
16+
- 📆 Confirm availability against multiple calendars
17+
- 🤖 Intelligent suggestion of available free times on both your and (if accessible) the scheduling party's calendar
18+
- ⚡ Send a webhook push to integrate with [IFTTT](https://ifttt.com/maker_webhooks), [Zapier](https://zapier.com/page/webhooks/), and more when an event is scheduled
19+
- 🌈 Configurable accent color
20+
- 🌙 Automatic light and dark mode
21+
- 💳 No premium tier. 100% free.
22+
23+
## Setup
24+
25+
Making your own ScheduleQuest page is easy!
26+
27+
1. Create a new [Google Apps Script](https://script.google.com/) project as the user that you want to be invited to newly created events. Give this script a name in the top left (e.g. ScheduleQuest).
28+
2. Click `Services ➕` in the left sidebar, scroll down to and select `Google Calendar API`, and click `Add`.
29+
3. Copy and paste the three files from [the `src` folder](https://github.com/leoherzog/ScheduleQuest/blob/main/src/) in this repository into three files in your Apps Script project named `Code.gs`, `index.html`, `config.html`.
30+
4. Customize the `config.html` file to contain the types of meetings you want to offer. Details are available in [the configuration section below](#configuration).
31+
5. Click `Deploy ⏷` in the top right, then `New Deployment`. Change the `Who Has Access` dropdown to whomever you want to be able to schedule events, and click `Deploy`.
32+
33+
Apps Script will then show you a deployment "Web App" URL that you can copy to the clipboard. This is the link to distribute to your recipients!
34+
35+
### Configuration
36+
37+
```html
38+
<script>
39+
const meetingTypes = {
40+
41+
"demo": { // a short unique id used internally for the type of meeting
42+
43+
// what calendar to put the event on. "primary", or the id of a calendar you have edit access to.
44+
"scheduleOn": "primary",
45+
46+
// array of calendar ids to check against for availability
47+
"busyAgainst": ["primary", "myotheraccount@gmail.com", "example.com_saj4co1nm5kyh8qs440fssktx4@group.calendar.google.com"],
48+
49+
// the name of the type of meeting that the person will see
50+
"name": "Product Demo",
51+
52+
// a font awesome icon for this meeting type
53+
"icon": "fa-solid fa-calendar-day",
54+
55+
// array of possible meeting lengths in minutes
56+
"length": [60],
57+
58+
// minimum number of minutes from now that the meeting can be scheduled
59+
"minMinutesFromNow": 240,
60+
61+
// maximum number of days from now that the meeting can be scheduled
62+
"maxDaysFromNow": 90,
63+
64+
// minimum time each day that the meeting can be scheduled
65+
"timeMin": "09:00",
66+
67+
// maximum time each day that the meeting can be scheduled
68+
"timeMax": "17:00",
69+
70+
// number of seconds between each time option
71+
"timeStep": 1800,
72+
73+
// array of days of the week to exclude from scheduling. 0 is Sunday, 6 is Saturday.
74+
"daysToExclude": [0, 6],
75+
76+
// label for the title field
77+
"titleLabel": "Your Name",
78+
79+
// the title of the event, with {INPUT} replaced with what the user enters in the title field
80+
"title": "Sales Demo with {INPUT}",
81+
82+
// whether the title field is editable
83+
"titleReadOnly": false,
84+
85+
// label for the location field
86+
"locationLabel": "Location",
87+
88+
// the location of the event, with {INPUT} replaced with what the user enters in the location field
89+
"location": "Google Meet",
90+
91+
// whether the location field is editable
92+
"locationReadOnly": true,
93+
94+
// whether Google Meet virtual meetings are enabled
95+
"allowVirtual": true,
96+
97+
// whether Google Meet virtual meetings are initially enabled
98+
"preferVirtual": true,
99+
100+
// label for the description field
101+
"descriptionLabel": "Description",
102+
103+
// the description of the event
104+
"description": "Chatting with you to get to know your needs and to show you our product.",
105+
106+
// whether the description field is editable
107+
"descriptionReadOnly": false,
108+
109+
// whether to show a field for additional attendees
110+
"otherguests": true,
111+
112+
// whether to send an email invitation to the person scheduling the meeting
113+
"sendEmailInvitation": true,
114+
115+
// optional webhook url to send a push notification when the meeting is scheduled
116+
"webhookUrl": null
117+
118+
},
119+
...
120+
}
121+
</script>
122+
```
123+
124+
#### Advanced
125+
126+
ScheduleQuest is built with the excellent [PicoCSS](https://picocss.org/) framework. It encourages simple and symantic HTML. If you'd like to customize the look and feel of your page, edit the `index.html` file in your Apps Script project with your own classes or style overrides.
127+
128+
Example:
129+
130+
```html
131+
<style>
132+
:root[data-theme="light"], :root[data-theme="dark"] {
133+
--primary: #DB4437; /* google red */
134+
--primary-hover: #BD2E22; /* 10% darker */
135+
--primary-focus: #BD2E22;
136+
}
137+
</style>
138+
```
139+
140+
## About Me
141+
142+
<a href="https://herzog.tech/" target="_blank">
143+
<img src="https://herzog.tech/signature/link.svg.png" width="32px" />
144+
</a>
145+
<a href="https://twitter.com/xd1936" target="_blank">
146+
<img src="https://herzog.tech/signature/twitter.svg.png" width="32px" />
147+
</a>
148+
<a href="https://github.com/leoherzog" target="_blank">
149+
<img src="https://herzog.tech/signature/github.svg.png" width="32px" />
150+
</a>
151+
<a href="https://keybase.io/leoherzog" target="_blank">
152+
<img src="https://herzog.tech/signature/keybase.svg.png" width="32px" />
153+
</a>
154+
<a href="https://linkedin.com/in/leoherzog" target="_blank">
155+
<img src="https://herzog.tech/signature/linkedin.svg.png" width="32px" />
156+
</a>
157+
<a href="https://hope.edu/directory/people/herzog-leo/" target="_blank">
158+
<img src="https://herzog.tech/signature/anchor.svg.png" width="32px" />
159+
</a>
160+
<br />
161+
<a href="https://www.buymeacoffee.com/leoherzog" target="_blank">
162+
<img src="https://cdn.buymeacoffee.com/buttons/lato-black.png" alt="Buy Me A Coffee" width="217px" />
163+
</a>
File renamed without changes.

config.html renamed to src/config.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"scheduleOn": "primary",
55
"busyAgainst": ["primary", "myotheraccount@gmail.com", "example.com_saj4co1nm5kyh8qs440fssktx4@group.calendar.google.com"],
66
"name": "Product Demo",
7-
"icon": "fas fa-calendar-day",
7+
"icon": "fa-solid fa-calendar-day",
88
"length": [60],
99
"minMinutesFromNow": 240,
1010
"maxDaysFromNow": 90,

index.html renamed to src/index.html

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -411,11 +411,10 @@ <h1 id="typetitle" class="card-title"></h1>
411411
if ($('#additionalguests').value) guests += ',' + $('#additionalguests').value;
412412
let title = type['title'].replace('{INPUT}', $('#title').value);
413413
let location = type['location'].replace('{INPUT}', $('#location').value);
414-
let description = type['description'].replace('{INPUT}', $('#description').value);
415414
let virtual = type['allowVirtual'] ? $('#virtual').value : false;
416415
$('#submit').disabled = true;
417416
$('#submit').setAttribute('aria-busy', 'true');
418-
google.script.run.withSuccessHandler(confirmSchedule).withFailureHandler(errorScheduling).scheduleEvent(type['scheduleOn'], guests, title, location, description, $('#date').value, $('#starttime').value, $('#length').value, virtual, type['sendEmailInvitation'], type['webhookUrl']);
417+
google.script.run.withSuccessHandler(confirmSchedule).withFailureHandler(errorScheduling).scheduleEvent(type['scheduleOn'], guests, title, location, $('#description').value, $('#date').value, $('#starttime').value, $('#length').value, virtual, type['sendEmailInvitation'], type['webhookUrl']);
419418
}
420419

421420
function confirmSchedule(details) {

0 commit comments

Comments
 (0)