-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
5ee2d31
commit 0be8aeb
Showing
10 changed files
with
264 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
.idea/* | ||
config.json | ||
config/config.json |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
39 changes: 39 additions & 0 deletions
39
files/opt/dash-button/scripts/providers/meetingReminder/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
## Configure Meeting Reminder | ||
|
||
The Meeting Reminder takes an event from a given Google Calender and sends a reminder to all attendants on Slack. | ||
(E-Mail addresses are for finding attendants on Slack) | ||
|
||
You will have to set up a project and enable it on Google in order to use the Calender api. | ||
You can follow Step 1 of Googles Node.js Quickstart [here](https://developers.google.com/calendar/quickstart/nodejs). | ||
After creating and downloading the client configuration, copy the content of the json file to the "secretFile" field in your config.json. | ||
|
||
The time parameter allows to control when the event has to have it's endtime. (If you insert 10 it will take the first event with an endtime after the next 10 minutes) | ||
|
||
Here is an example configuration: | ||
|
||
```json | ||
{ | ||
"buttons": [ | ||
{ | ||
"mac": "xx:xx:xx:xx:xx:xx", | ||
"provider": "meetingReminder", | ||
"providerConfig": { | ||
"calendarId": "primary", | ||
"time": "now" | ||
} | ||
}, | ||
{ | ||
"mac": "xx:xx:xx:xx:xx:xx", | ||
"provider": "meetingReminder", | ||
"providerConfig": { | ||
"calendarId": "primary", | ||
"time": "10" | ||
} | ||
} | ||
], | ||
"providerConfig": { | ||
|
||
} | ||
} | ||
|
||
``` |
167 changes: 167 additions & 0 deletions
167
files/opt/dash-button/scripts/providers/meetingReminder/meetingReminder.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,167 @@ | ||
// require modules needed to send Slack messages | ||
const fs = require('fs'); | ||
const readline = require('readline'); | ||
const {google} = require('googleapis'); | ||
const { WebClient } = require('@slack/client'); | ||
|
||
const SCOPES = ['https://www.googleapis.com/auth/calendar.readonly']; | ||
|
||
// export module for main script | ||
module.exports = { | ||
dashHandler : function (sender, providerConfig) { | ||
meetingReminderHandler(sender, providerConfig); | ||
} | ||
}; | ||
|
||
function meetingReminderHandler(sender, providerConfig) { | ||
try { | ||
const content = providerConfig.secretFile; | ||
authorize(content, readEvent, sender, providerConfig); | ||
} catch (err) { | ||
return console.log('Error loading client secret file:', err); | ||
} | ||
} | ||
|
||
// Create an OAuth2 client with the given credentials, and then execute the given callback function. | ||
function authorize(credentials, callback, sender, providerConfig) { | ||
const {client_secret, client_id, redirect_uris} = credentials.installed; | ||
let token = {}; | ||
const oAuth2Client = new google.auth.OAuth2( | ||
client_id, client_secret, redirect_uris[0]); | ||
|
||
if (providerConfig.googleToken != undefined) { | ||
token = providerConfig.googleToken; | ||
} else { | ||
getAccessToken(oAuth2Client, callback, sender, providerConfig); | ||
} | ||
|
||
// Check if we have previously stored a token. | ||
if (providerConfig.googleToken != undefined) { | ||
token = providerConfig.googleToken; | ||
} else { | ||
return getAccessToken(oAuth2Client, callback, sender, providerConfig, function (res) { | ||
console.log(res); | ||
}); | ||
} | ||
oAuth2Client.setCredentials(token); | ||
callback(oAuth2Client, sender, providerConfig); | ||
} | ||
|
||
// Get and store new token after prompting for user authorization, and then | ||
// execute the given callback with the authorized OAuth2 client. | ||
function getAccessToken(oAuth2Client, callback, sender, providerConfig) { | ||
const authUrl = oAuth2Client.generateAuthUrl({ | ||
access_type: 'offline', | ||
scope: SCOPES, | ||
}); | ||
console.log('Authorize this app by visiting this url:', authUrl); | ||
const rl = readline.createInterface({ | ||
input: process.stdin, | ||
output: process.stdout, | ||
}); | ||
rl.question('Enter the code from that page here: ', (code) => { | ||
rl.close(); | ||
oAuth2Client.getToken(code, (err, token) => { | ||
if (err) return callback(err); | ||
oAuth2Client.setCredentials(token); | ||
// Store the token to disk for later program executions | ||
try { | ||
providerConfig['googleToken'] = token; | ||
const updateProviderConfig = require('../../script'); | ||
updateProviderConfig.updateProviderConfig(providerConfig,'meetingReminder'); | ||
} catch (err) { | ||
console.error(err); | ||
} | ||
callback(oAuth2Client, sender, providerConfig); | ||
}); | ||
}); | ||
} | ||
|
||
// Reads google calender event and calls send message function | ||
function readEvent(auth, sender, providerConfig) { | ||
const calendar = google.calendar({version: 'v3', auth}); | ||
var startTime = new Date(); | ||
var time = sender.providerConfig.time; | ||
|
||
if (time == 'now') { | ||
startTime = (new Date()).toISOString(); | ||
} else { | ||
time = startTime.getTime() + time * 60000; | ||
startTime = (new Date(time)).toISOString(); | ||
} | ||
|
||
calendar.events.list({ | ||
calendarId: sender.providerConfig.calendarId, | ||
timeMin: startTime, | ||
maxResults: 1, | ||
singleEvents: true, | ||
orderBy: 'startTime', | ||
}, (err, res) => { | ||
if (err) return console.log('The API returned an error: ' + err); | ||
const events = res.data.items; | ||
let emails = {}; | ||
|
||
events[0].attendees.forEach(value => { | ||
emails[value.email] = value.email; | ||
}); | ||
sendSlackReminder(emails, events[0], sender, providerConfig); | ||
}); | ||
} | ||
|
||
// Searches for userIds to send Slack message and calls send function | ||
function sendSlackReminder(emails, appointment, sender, providerConfig) { | ||
const web = new WebClient(providerConfig.slackToken); | ||
|
||
let arguments = { | ||
'token': providerConfig.slackToken | ||
}; | ||
|
||
web.users.list(arguments).then((res) => { | ||
res.members.forEach(value => { | ||
if (emails[value.profile.email] != undefined) { | ||
sendSlackMessage(value.id, appointment, providerConfig.slackToken); | ||
} | ||
}); | ||
}).catch(error => { | ||
console.error('Slack: an error occurred: ', error); | ||
}); | ||
} | ||
|
||
// Sends reminder for appointment via Slack | ||
function sendSlackMessage(id, appointment, token) { | ||
const web = new WebClient(token); | ||
|
||
var messageText = 'Reminder: ' + appointment.summary; | ||
var start; | ||
var now = new Date(); | ||
|
||
if (appointment.start.dateTime != undefined) { | ||
start = new Date(appointment.start.dateTime); | ||
} else { | ||
start = new Date(appointment.start.date); | ||
} | ||
|
||
if (now < start) { | ||
msec = start - now; | ||
var min = Math.floor(msec / 1000 / 60); | ||
var hour = Math.floor(msec / 1000 / 60 /60); | ||
messageText = messageText + ' starts in ' + min % 60 + ' minutes' + (hour != 0 ? ' and ' + hour + ' hours!' : '!'); | ||
} else { | ||
msec = now - start; | ||
var min = Math.floor(msec / 1000 / 60); | ||
messageText = messageText + ' started ' + min + ' minutes ago!'; | ||
} | ||
|
||
let arguments = { | ||
'token': token, | ||
'channel': id, | ||
'as_user': 'false', | ||
'text': messageText | ||
}; | ||
|
||
web.chat.postMessage(arguments).then((res) => { | ||
console.log('Slack: Sent message: ', res.message.text); | ||
}).catch(error => { | ||
console.error('Slack: an error occurred: ', error); | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
#!/bin/bash -e | ||
|
||
# Privileged is needed for being able to inspect packages in the host system | ||
docker run -d --name dash-button --net=host --restart unless-stopped --privileged -v $(pwd)/config.json:/config.json fusonic/amazon-dash-buttons:latest | ||
docker run -d --name dash-button --net=host --restart unless-stopped --privileged -v $(pwd)/config:/opt/dash-button/config fusonic/amazon-dash-buttons:latest |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
#!/bin/bash -e | ||
|
||
# Privileged is needed for being able to inspect packages in the host system | ||
docker run -it --rm --net=host --privileged -v $(pwd)/config.json:/config.json -v ${PWD}/files/opt/dash-button/scripts:/opt/dash-button/scripts dev/dash-buttons | ||
docker run -it --rm --net=host --privileged -v $(pwd)/config:/opt/dash-button/config -v ${PWD}/files/opt/dash-button/scripts:/opt/dash-button/scripts dev/dash-buttons |