├── credentials.json
├── .gitignore
├── src
├── public
│ ├── views
│ │ ├── events.html
│ │ └── index.html
│ └── css
│ │ └── app.css
└── app.js
├── package.json
├── SECURITY.md
└── README.md
/credentials.json:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | config
--------------------------------------------------------------------------------
/src/public/views/events.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Google Events
8 |
9 |
10 |
14 |
15 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "google-calender",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "engines": {
7 | "node": "13.10.1"
8 | },
9 | "dependencies": {
10 | "@sendgrid/mail": "^7.4.0",
11 | "axios": "^0.21.1",
12 | "ejs": "^3.1.7",
13 | "express": "^4.17.1",
14 | "googleapis": "^39.2.0",
15 | "json-bigint": "^1.0.0",
16 | "node-forge": "^0.10.0",
17 | "node-json2html": "^1.4.0",
18 | "nodemon": "^2.0.3"
19 | },
20 | "devDependencies": {},
21 | "scripts": {
22 | "start": "node src/app.js",
23 | "dev": "env-cmd -f ./config/dev.env node src/app.js"
24 | },
25 | "author": "",
26 | "license": "ISC"
27 | }
28 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 | # Security Policy
2 |
3 | ## Supported Versions
4 |
5 | Use this section to tell people about which versions of your project are
6 | currently being supported with security updates.
7 |
8 | | Version | Supported |
9 | | ------- | ------------------ |
10 | | 5.1.x | :white_check_mark: |
11 | | 5.0.x | :x: |
12 | | 4.0.x | :white_check_mark: |
13 | | < 4.0 | :x: |
14 |
15 | ## Reporting a Vulnerability
16 |
17 | Use this section to tell people how to report a vulnerability.
18 |
19 | Tell them where to go, how often they can expect to get an update on a
20 | reported vulnerability, what to expect if the vulnerability is accepted or
21 | declined, etc.
22 |
--------------------------------------------------------------------------------
/src/public/css/app.css:
--------------------------------------------------------------------------------
1 | .button {
2 | background-color: #4CAF50;
3 | border: none;
4 | color: white;
5 | padding: 15px 32px;
6 | text-align: center;
7 | text-decoration: none;
8 | display: inline-block;
9 | font-size: 16px;
10 | margin: 4px 2px;
11 | cursor: pointer;
12 | }
13 |
14 | .form {
15 | margin: 0 200px;
16 | border-radius: 5px;
17 | background-color: #f2f2f2;
18 | padding: 15px 30px;
19 | } span {
20 | color: red;
21 | margin-left: 20px;
22 | }
23 |
24 | input[type=email],
25 | input[type=text],
26 | select {
27 | width: 100%;
28 | padding: 12px 20px;
29 | margin: 8px 0;
30 | display: inline-block;
31 | border: 1px solid #ccc;
32 | border-radius: 4px;
33 | box-sizing: border-box;
34 | }
35 | input[type=submit] {
36 | width: 100%;
37 | background-color: #4CAF50;
38 | color: white;
39 | padding: 14px 20px;
40 | margin: 15px 0;
41 | border: none;
42 | border-radius: 4px;
43 | cursor: pointer;
44 | }
45 | input[type=submit]:hover {
46 | background-color: #45a049;
47 | }
48 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # GoogleCalender
2 |
3 |
4 | *****************************************************
5 | ****************** IMPORTANT ************************
6 |
7 |
8 | Make YOUR OWN credentials.json file BEFORE running the code
9 |
10 | Watch video: The Google Calendar API (PART 1)
11 |
12 | Time: 13:20 - Google Calendar API and credentials.json
13 |
14 |
15 | ****************** IMPORTANT ************************
16 | *****************************************************
17 |
18 |
19 | How this Project works? https://www.youtube.com/watch?v=K2JD61PZ-8U&list=PLcL8q_TiioW3FxvmlatZlTZQCnRs_UMoG
20 |
21 |
22 | This project is made by GOOGLE SEARCH API, SENDGRID and GOOGLE DEVELOPER CONSOLE.
23 |
24 | Run the Google Calender App on the Browser by installing the repo code and running following commands on the BASH terminal:
25 |
26 | 1 --> cd GoogleCalender-master
27 |
28 | 2 --> npm i express env-cmd
29 |
30 | 3 --> make a config folder in the root directory and inside it make a 'dev.env' file like as config(folder) -> dev.env(file) .The config file must contain 4 env variables as:
31 |
32 | SENDGRID_API_KEY=your sendgrid api key
33 |
34 | CLIENT_ID=your google api client id
35 |
36 | CLIENT_SECRET=your google client secret
37 |
38 | REFRESH_TOKEN=your developer refresh token
39 |
40 |
41 | 4 --> npm run dev
42 |
43 | 5 --> Open the Google Calender app in your browser.
44 |
--------------------------------------------------------------------------------
/src/public/views/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Google Calander
6 |
7 |
8 |
9 |
28 |
29 |
--------------------------------------------------------------------------------
/src/app.js:
--------------------------------------------------------------------------------
1 | /*
2 | Make YOUR OWN credentials.json file BEFORE running the CODE
3 |
4 | Watch video: The Google Calendar API (PART 1)
5 |
6 | Time: 13:20 - Google Calendar API and credentials.json
7 |
8 | */
9 |
10 | // NEW COMMIT
11 |
12 | const express = require('express')
13 | const app = express()
14 | const path = require('path')
15 | const bodyParser = require('body-parser');
16 |
17 | var var_arr=['Extracting finished. Refresh the browser to see your Google events'];
18 |
19 | app.use(express.static(path.join(__dirname, 'public')))
20 | app.set('views', __dirname + '/public/views');
21 | app.engine('html', require('ejs').renderFile);
22 | app.set('view engine', 'html');
23 | app.use(bodyParser.urlencoded({extended: true}));
24 | app.use(bodyParser.json());
25 |
26 | app.get('/', (req, res) =>{
27 | res.render('index.html');
28 | })
29 |
30 | app.post('/', (req, res) => {
31 | const tkn=req.body.token;
32 | const fs = require('fs');
33 | const {google} = require('googleapis');
34 |
35 | const SCOPES = ['https://www.googleapis.com/auth/calendar.readonly'];
36 | // The file token.json stores the user's access and refresh tokens, and is
37 | // created automatically when the authorization flow completes for the first
38 | // time.
39 | const TOKEN_PATH = 'token.json';
40 |
41 | // Load client secrets from a local file.
42 | fs.readFile('credentials.json', (err, content) => {
43 | if (err) return console.log('Error loading client secret file:', err);
44 | // Authorize a client with credentials, then call the Google Calendar API.
45 | authorize(JSON.parse(content), listEvents);
46 | });
47 |
48 | /**
49 | * Create an OAuth2 client with the given credentials, and then execute the
50 | * given callback function.
51 | * @param {Object} credentials The authorization client credentials.
52 | * @param {function} callback The callback to call with the authorized client.
53 | */
54 | function authorize(credentials, callback) {
55 | const {client_secret, client_id, redirect_uris} = credentials.installed;
56 | const oAuth2Client = new google.auth.OAuth2(
57 | client_id, client_secret, redirect_uris[0]);
58 |
59 | // Check if we have previously stored a token.
60 | fs.readFile(TOKEN_PATH, (err, token) => {
61 | if (err) return getAccessToken(oAuth2Client, callback);
62 | oAuth2Client.setCredentials(JSON.parse(token));
63 | callback(oAuth2Client);
64 | });
65 | }
66 |
67 | /**
68 | * Get and store new token after prompting for user authorization, and then
69 | * execute the given callback with the authorized OAuth2 client.
70 | * @param {google.auth.OAuth2} oAuth2Client The OAuth2 client to get token for.
71 | * @param {getEventsCallback} callback The callback for the authorized client.
72 | */
73 | function getAccessToken(oAuth2Client, callback) {
74 | oAuth2Client.getToken(tkn, (err, token) => {
75 | if (err) return console.error('Error retrieving access token', err);
76 | oAuth2Client.setCredentials(token);
77 | // Store the token to disk for later program executions
78 | fs.writeFile(TOKEN_PATH, JSON.stringify(token), (err) => {
79 | if (err) return console.error(err);
80 | console.log('Token stored to', TOKEN_PATH);
81 | });
82 | callback(oAuth2Client);
83 | });
84 | }
85 |
86 | /**
87 | * Lists the next events on the user's primary calendar.
88 | * @param {google.auth.OAuth2} auth An authorized OAuth2 client.
89 | */
90 | function listEvents(auth) {
91 | async function fun(){
92 | const calendar = await google.calendar({version: 'v3', auth});
93 | calendar.events.list({
94 | calendarId: 'primary',
95 | timeMin: (new Date()).toISOString(),
96 | maxResults: 30,
97 | singleEvents: true,
98 | orderBy: 'startTime',
99 | }, (err, res) => {
100 | if (err) return console.log('The API returned an error: ' + err);
101 | const events = res.data.items;
102 | if (events.length) {
103 | console.log('Your upcoming events:', events);
104 | events.map((event, i) => {
105 | var_arr.push(event);
106 | });
107 | } else {
108 | console.log('No upcoming events found.');
109 | }
110 | });
111 | }
112 | fun()
113 | }
114 | res.send(var_arr)
115 | res.render('index.html')
116 | });
117 |
118 |
119 | app.post('/events', (req, res) =>{
120 | // Require google from googleapis package.
121 | const { google } = require('googleapis')
122 | // Require oAuth2 from our google instance.
123 | const { OAuth2 } = google.auth
124 |
125 | // Create a new instance of oAuth and set our Client ID & Client Secret.
126 | const oAuth2Client = new OAuth2(process.env.CLIENT_ID, process.env.CLIENT_SECRET)
127 |
128 | // Call the setCredentials method on our oAuth2Client instance and set our refresh token.
129 | oAuth2Client.setCredentials({
130 | refresh_token: process.env.REFRESH_TOKEN,
131 | })
132 |
133 | // Create a new calender instance.
134 | const calendar = google.calendar({ version: 'v3', auth: oAuth2Client })
135 |
136 | // Create a new event start date instance for temp uses in our calendar.
137 | const eventStartTime = new Date()
138 | eventStartTime.setDate(eventStartTime.getDay() + 2)
139 |
140 | // Create a new event end date instance for temp uses in our calendar.
141 | const eventEndTime = new Date()
142 | eventEndTime.setDate(eventEndTime.getDay() + 2)
143 | eventEndTime.setMinutes(eventEndTime.getMinutes() + 60)
144 |
145 | // Create a dummy event for temp uses in our calendar
146 | const event = {
147 | summary: `${req.body.summary}`,
148 | description: `${req.body.description}`,
149 | colorId: 6,
150 | start: {
151 | dateTime: eventStartTime,
152 | },
153 | end: {
154 | dateTime: eventEndTime,
155 | },
156 | }
157 |
158 | // Check if we a busy and have an event on our calendar for the same time.
159 | calendar.freebusy.query(
160 | {
161 | resource: {
162 | timeMin: eventStartTime,
163 | timeMax: eventEndTime,
164 | items: [{ id: 'primary' }],
165 | },
166 | },
167 | (err, res) => {
168 | // Check for errors in our query and log them if they exist.
169 | if (err) return console.error('Free Busy Query Error: ', err)
170 |
171 | // Create an array of all events on our calendar during that time.
172 | const eventArr = res.data.calendars.primary.busy
173 |
174 | // Check if event array is empty which means we are not busy
175 | if (eventArr.length === 0) {
176 | // If we are not busy create a new calendar event.
177 | return calendar.events.insert(
178 | { calendarId: 'primary', resource: event },
179 | err => {
180 | // Check for errors and log them if they exist.
181 | if (err) return console.error('Error Creating Calender Event:', err)
182 | // Else log that the event was created.
183 | return console.log('Event created successfully.')
184 | })
185 | }
186 | // If event array is not empty log that we are busy.
187 | return console.log(`Sorry I'm busy for that time...`)
188 | }
189 | )
190 | console.log(req.body)
191 | const sgMail = require('@sendgrid/mail')
192 | sgMail.setApiKey(process.env.SENDGRID_API_KEY)
193 | const msg = {
194 | to: req.body.to, // Change to your recipient
195 | from: 'your email goes here', // Change to your verified sender
196 | subject: req.body.summary,
197 | text: req.body.description,
198 | html: req.body.description,
199 | }
200 | sgMail
201 | .send(msg)
202 | .then(() => {
203 | console.log('Email sent')
204 | })
205 | .catch((error) => {
206 | console.error(error)
207 | })
208 |
209 | res.render('events.html')
210 | })
211 |
212 | app.listen(3000, () =>{
213 | console.log('Server running on port 3000')
214 | })
--------------------------------------------------------------------------------