From 3765d7f43fea17a803af7da2ba1a99abe0159aa5 Mon Sep 17 00:00:00 2001 From: danhuiZ Date: Mon, 17 Jul 2017 16:34:39 -0700 Subject: [PATCH 01/10] bot and model --- bot.js | 4 ++-- models.js | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/bot.js b/bot.js index 6072700..734cc4a 100644 --- a/bot.js +++ b/bot.js @@ -51,10 +51,10 @@ rtm.start(); rtm.on(RTM_EVENTS.MESSAGE, function handleRtmMessage(message) { console.log('Message:', message); - if(message.message.sub_type==='bot_message') { + if(message && message.subtype === 'bot_message') { return; } - rtm.sendMessage("hello i am seeing and replytin to your meesage", message.channel); + rtm.sendMessage("hello i am seeing and replying to your meesage", message.channel); web.chat.postMessage(message.channel, 'Hello there', obj, function(err, res) { if (err) { console.log('Error:', err); diff --git a/models.js b/models.js index 292ab37..774d9ca 100644 --- a/models.js +++ b/models.js @@ -1,9 +1,9 @@ var mongoose = require('mongoose'); var userSchema = mongoose.Schema({ - username: String, - password: String, - phone: String + slackId: String, + slackName: String, + googleProfileAccess: Boolean, }); @@ -11,5 +11,5 @@ var userSchema = mongoose.Schema({ User = mongoose.model('User', userSchema); module.exports = { - User:User + User: User }; From 366aa0b5d732306f689550b437bd16e76eeeea12 Mon Sep 17 00:00:00 2001 From: danhuiZ Date: Tue, 18 Jul 2017 09:14:22 -0700 Subject: [PATCH 02/10] day1 --- app.js | 148 +++++++++++++++-------------------------------- bot.js | 159 +++++++++++++++++++++++++++++++++------------------ models.js | 12 +++- package.json | 7 ++- 4 files changed, 163 insertions(+), 163 deletions(-) diff --git a/app.js b/app.js index e3e6ec2..a5fc55d 100644 --- a/app.js +++ b/app.js @@ -1,16 +1,9 @@ var express = require('express'); -var session = require('express-session'); -var MongoStore = require('connect-mongo')(session); -var path = require('path'); -var logger = require('morgan'); -var cookieParser = require('cookie-parser'); -var bodyParser = require('body-parser'); -var passport = require('passport'); -var LocalStrategy = require('passport-local'); -var mongoose = require('mongoose'); -var connect = process.env.MONGODB_URI; +var google = require('googleapis'); +var OAuth2 = require('client-oauth2') -var REQUIRED_ENV = "SECRET MONGODB_URI".split(" "); +// REQUIRED SOURCE CHECKS +var REQUIRED_ENV = "SLACK_SECRET MONGODB_URI".split(" "); REQUIRED_ENV.forEach(function(el) { if (!process.env[el]){ @@ -19,107 +12,58 @@ REQUIRED_ENV.forEach(function(el) { } }); - -mongoose.connect(connect); - -var models = require('./models'); - -var routes = require('./routes/routes'); -var auth = require('./routes/auth'); +// RUNNING SERVER var app = express(); +var bodyParser = require('body-parser'); -// view engine setup -var hbs = require('express-handlebars')({ - defaultLayout: 'main', - extname: '.hbs' -}); -app.engine('hbs', hbs); -app.set('views', path.join(__dirname, 'views')); -app.set('view engine', 'hbs'); - -app.use(logger('tiny')); -app.use(bodyParser.json()); -app.use(bodyParser.urlencoded({ extended: false })); -app.use(cookieParser()); -app.use(express.static(path.join(__dirname, 'public'))); - -// Passport -app.use(session({ - secret: process.env.SECRET, - store: new MongoStore({ mongooseConnection: mongoose.connection }) -})); - - -app.use(passport.initialize()); -app.use(passport.session()); - -passport.serializeUser(function(user, done) { - done(null, user._id); -}); - -passport.deserializeUser(function(id, done) { - models.User.findById(id, done); -}); - -// passport strategy -passport.use(new LocalStrategy(function(username, password, done) { - // Find the user with the given username - models.User.findOne({ username: username }, function (err, user) { - // if there's an error, finish trying to authenticate (auth failed) - if (err) { - console.error('Error fetching user in LocalStrategy', err); - return done(err); - } - // if no user present, auth failed - if (!user) { - return done(null, false, { message: 'Incorrect username.' }); - } - // if passwords do not match, auth failed - if (user.password !== password) { - return done(null, false, { message: 'Incorrect password.' }); - } - // auth has has succeeded - return done(null, user); +/* BOT CODE */ +require('./bot'); +/* ******** */ +var oauth2Client = new OAuth2( + process.env.GOOGLE_CLIENT_ID, + process.env.GOOGLE_CLIENT_SECRET, + process.env.DOMAIN + '/connect/callback' //redirect url +); + +app.get('/connect', function(req, res){ + var url = oauth2Client.generateAuthUrl({ + access_type: 'offline', //'online' (default) or 'offline' (gets refresh_token) + prompt: 'consent', + scope: [ + 'https://www.googleapis.com/auth/userinfo.profile', + 'https://www.googleapis.com/auth/calendar' + ], // generate a url that asks permissions for Google+ and Google Calendar scopes + state: encodeURIComponent(JSON.stringify({ + auth_id: req.query.auth_id + })) // Optional property that passes state parameters to redirect URI }); -} -)); - -app.use('/', auth(passport)); -app.use('/', routes); - -// catch 404 and forward to error handler -app.use(function(req, res, next) { - var err = new Error('Not Found'); - err.status = 404; - next(err); + res.redirect('/connect/callback') +}) + +app.get('/connect/callback', function(req, res){ + oauth2Client.getToken(code, function (err, tokens) { + // Now tokens contains an access_token and an optional refresh_token. Save them. + if (!err) { + oauth2Client.setCredentials(tokens); + } }); + res.send(200) +}) -// error handlers -// development error handler -// will print stacktrace -if (app.get('env') === 'development') { - app.use(function(err, req, res, next) { - res.status(err.status || 500); - res.render('error', { - message: err.message, - error: err - }); - }); -} +app.post('/slack/interactive', function(req, res){ + var payload = JSON.parse(req.body.payload); + console.log("PAYLOAD", payload); + if(payload.actions[0].value === 'yes') { + res.send('Created reminder :white_check_mark:'); + } + res.send('Cancelled :x:'); +}) -// production error handler -// no stacktraces leaked to user -app.use(function(err, req, res, next) { - res.status(err.status || 500); - res.render('error', { - message: err.message, - error: {} - }); -}); var port = process.env.PORT || 3000; app.listen(port); console.log('Express started. Listening on port %s', port); + module.exports = app; diff --git a/bot.js b/bot.js index 734cc4a..7bca5dc 100644 --- a/bot.js +++ b/bot.js @@ -1,73 +1,120 @@ +require('./app'); -var RtmClient = require('@slack/client').RtmClient; -var RTM_EVENTS = require('@slack/client').RTM_EVENTS; -var WebClient = require('@slack/client').WebClient; +// CONNECTING TO MONGOOSE DB +var mongoose = require('mongoose'); +var models = require('./models'); +mongoose.connect(process.env.MONGODB_URI); -var obj = { - "text": "Would you like to play a game?", - "attachments": [ +var { RtmClient, WebClient, CLIENT_EVENTS, RTM_EVENTS } = require('@slack/client'); +var axios = require('axios'); + +function imReply(data) { + return ({"attachments": [ + { + "text": `Creating a reminder for '${data.result.parameters.subject}' on ${data.result.parameters.date}`, + "fallback": "You are unable to create reminder", + "callback_id": "reminder", + "color": "#3AA3E3", + "attachment_type": "default", + "actions": [ { - "text": "Choose a game to play", - "fallback": "You are unable to choose a game", - "callback_id": "wopr_game", - "color": "#3AA3E3", - "attachment_type": "default", - "actions": [ - { - "name": "game", - "text": "Chess", - "type": "button", - "value": "chess" - }, - { - "name": "game", - "text": "Falken's Maze", - "type": "button", - "value": "maze" - }, - { - "name": "game", - "text": "Thermonuclear War", - "style": "danger", - "type": "button", - "value": "war", - "confirm": { - "title": "Are you sure?", - "text": "Wouldn't you prefer a good game of chess?", - "ok_text": "Yes", - "dismiss_text": "No" - } - } - ] - } - ] + "name": "confrim", + "text": "Yes", + "type": "button", + "value": "yes" + }, + { + "name": "confirm", + "text": "No", + "type": "button", + "value": "no" + }, + ] + } + ]}) } - var token = process.env.SLACK_SECRET || ''; var web = new WebClient(token); var rtm = new RtmClient(token); rtm.start(); +rtm.on(CLIENT_EVENTS.RTM.AUTHENTICATED, (rtmStartData) => { + console.log(`logged in as ${rtmStartData.self.name} of team ${rtmStartData.team.name}, but not yet connected to a channel`); +}) + rtm.on(RTM_EVENTS.MESSAGE, function handleRtmMessage(message) { - console.log('Message:', message); - if(message && message.subtype === 'bot_message') { + var dm = rtm.dataStore.getDMByUserId(message.user); + console.log("DM--------", dm, "MESSAGE", message); + if (!dm || dm.id !== message.channel || message.type !== 'message') { + console.log('Message not send to DM, ignoring'); return; } - rtm.sendMessage("hello i am seeing and replying to your meesage", message.channel); - web.chat.postMessage(message.channel, 'Hello there', obj, function(err, res) { - if (err) { - console.log('Error:', err); - } else { - console.log('Message sent: ', res); + + var temp = encodeURIComponent(message.text); + //CHECK IF THEY ARE IN MONGO AS HAVING REGISTERED GOOGLE + var u = rtm.dataStore.getUserById(message.user); + + //CHECK FOR USER OR CREATE ONE + models.User.findOne({slack_ID: message.user}) + .then(function(user){ + if(!user){ + var user = new models.User({ + slack_ID: message.user, + slack_Username: u.profile.real_name, + slack_Email: u.profile.email, + slack_DM_ID: message.channel + }) + return user.save(); } + return user; + }) + .then(function(user){ + if(!user.googleAccount.access_token){ + //submit the link to grant access + web.chat.postMessage(message.channel, + 'Use this link to give access to your google cal account http://localhost:3000/connect?auth_id=' + + user._id); + return; + } + // rtm.sendMessage("hello i am seeing and replying to your meesage", message.channel); + axios.get('https://api.api.ai/api/query', { + params: { + v: 20150910, + lang: 'en', + timezone: '2017-07-17T16:58:21-0700', + query: message.text, + sessionId: message.user + }, + headers: { + Authorization: `Bearer ${process.env.API_AI_TOKEN}` + } + }) + .then(function( {data} ) { + console.log("DATA", data); + if(!data.result.actionIncomplete && data.result.parameters.date && data.result.parameters.subject ) { + // rtm.sendMessage(data.result.fulfillment.speech, message.channel); + web.chat.postMessage(message.channel, 'Ok', imReply(data), function(err, res) { + if (err) { + console.log('Error:', err); + } else { + console.log('Message sent: ', res); + } + }); + } else { + console.log("ACTION IS COMPLETE"); + } + }) + .catch(function(err) { + console.log("ERROR", err); + }) + }); }); -}); -rtm.on(RTM_EVENTS.REACTION_ADDED, function handleRtmReactionAdded(reaction) { - console.log('Reaction added:', reaction); -}); + rtm.on(RTM_EVENTS.REACTION_ADDED, function handleRtmReactionAdded(reaction) { + console.log('Reaction added:', reaction); + }); -rtm.on(RTM_EVENTS.REACTION_REMOVED, function handleRtmReactionRemoved(reaction) { - console.log('Reaction removed:', reaction); -}); + rtm.on(RTM_EVENTS.REACTION_REMOVED, function handleRtmReactionRemoved(reaction) { + console.log('Reaction removed:', reaction); + }); diff --git a/models.js b/models.js index 774d9ca..4b8147b 100644 --- a/models.js +++ b/models.js @@ -1,9 +1,15 @@ var mongoose = require('mongoose'); var userSchema = mongoose.Schema({ - slackId: String, - slackName: String, - googleProfileAccess: Boolean, + googleAccount: { + access_token: String, + refresh_token: String, + profile_ID: String + }, + slack_ID: String, + slack_Username: String, + slack_Email: String, + slack_DM_ID: String }); diff --git a/package.json b/package.json index 1a11d4d..1aa3567 100644 --- a/package.json +++ b/package.json @@ -7,15 +7,18 @@ }, "dependencies": { "@slack/client": "^3.10.0", - "body-parser": "~1.13.2", + "axios": "^0.16.2", + "body-parser": "^1.13.3", + "client-oauth2": "^4.1.0", "connect-mongo": "^1.3.2", "cookie-parser": "~1.3.5", "debug": "~2.2.0", "express": "~4.13.1", "express-handlebars": "^3.0.0", "express-session": "^1.13.0", + "googleapis": "^20.1.0", "hbs": "~3.1.0", - "mongoose": "^4.5.1", + "mongoose": "^4.11.3", "mongoose-findorcreate": "^0.1.2", "morgan": "~1.6.1", "multer": "^1.1.0", From 09228c04e24882918eb0e09babc31d462d6a7b33 Mon Sep 17 00:00:00 2001 From: danhuiZ Date: Tue, 18 Jul 2017 11:05:31 -0700 Subject: [PATCH 03/10] calendar auth works --- app.js | 25 ++++++++++++++++++++++--- bot.js | 2 +- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/app.js b/app.js index a5fc55d..6ae5f87 100644 --- a/app.js +++ b/app.js @@ -1,6 +1,8 @@ var express = require('express'); var google = require('googleapis'); -var OAuth2 = require('client-oauth2') +// var OAuth2 = require('client-oauth2') +var OAuth2 = google.auth.OAuth2; +var models = require('./models'); // REQUIRED SOURCE CHECKS var REQUIRED_ENV = "SLACK_SECRET MONGODB_URI".split(" "); @@ -19,6 +21,7 @@ var bodyParser = require('body-parser'); /* BOT CODE */ require('./bot'); /* ******** */ + var oauth2Client = new OAuth2( process.env.GOOGLE_CLIENT_ID, process.env.GOOGLE_CLIENT_SECRET, @@ -37,15 +40,31 @@ app.get('/connect', function(req, res){ auth_id: req.query.auth_id })) // Optional property that passes state parameters to redirect URI }); - res.redirect('/connect/callback') + // console.log(url); + res.redirect(url); }) app.get('/connect/callback', function(req, res){ - oauth2Client.getToken(code, function (err, tokens) { + oauth2Client.getToken(req.query.code, function (err, tokens) { + console.log(tokens); // Now tokens contains an access_token and an optional refresh_token. Save them. if (!err) { oauth2Client.setCredentials(tokens); } + var state = JSON.parse(decodeURIComponent(req.query.state)); + models.User.findByIdAndUpdate(state.auth_id, { + googleAccount: { + access_token: tokens.access_token, + refresh_token: tokens.refresh_token, + profile_ID: tokens.id_token + } + }) + .then(function(user){ + user.save(); + }) + .catch(function(err){ + console.log("Error", err); + }) }); res.send(200) }) diff --git a/bot.js b/bot.js index 7bca5dc..03e0ac5 100644 --- a/bot.js +++ b/bot.js @@ -2,8 +2,8 @@ require('./app'); // CONNECTING TO MONGOOSE DB var mongoose = require('mongoose'); -var models = require('./models'); mongoose.connect(process.env.MONGODB_URI); +var models = require('./models'); var { RtmClient, WebClient, CLIENT_EVENTS, RTM_EVENTS } = require('@slack/client'); var axios = require('axios'); From 878677b63e7c492672b114f11156da3c0dd170ef Mon Sep 17 00:00:00 2001 From: danhuiZ Date: Tue, 18 Jul 2017 11:21:24 -0700 Subject: [PATCH 04/10] Delete unnecessary stuff --- app.js | 2 ++ index.js | 20 ----------- public/scripts/script.js | 1 - public/stylesheets/style.css | 5 --- routes/auth.js | 53 ---------------------------- routes/routes.js | 39 --------------------- views/error.hbs | 3 -- views/home.hbs | 6 ---- views/layouts/main.hbs | 68 ------------------------------------ views/login.hbs | 22 ------------ views/protectedRoute.hbs | 8 ----- views/signup.hbs | 25 ------------- 12 files changed, 2 insertions(+), 250 deletions(-) delete mode 100644 index.js delete mode 100644 public/scripts/script.js delete mode 100644 public/stylesheets/style.css delete mode 100644 routes/auth.js delete mode 100644 routes/routes.js delete mode 100644 views/error.hbs delete mode 100644 views/home.hbs delete mode 100644 views/layouts/main.hbs delete mode 100644 views/login.hbs delete mode 100644 views/protectedRoute.hbs delete mode 100644 views/signup.hbs diff --git a/app.js b/app.js index 6ae5f87..b6b2896 100644 --- a/app.js +++ b/app.js @@ -71,8 +71,10 @@ app.get('/connect/callback', function(req, res){ app.post('/slack/interactive', function(req, res){ + var payload = JSON.parse(req.body.payload); console.log("PAYLOAD", payload); + var timeNow = Date.now(); if(payload.actions[0].value === 'yes') { res.send('Created reminder :white_check_mark:'); } diff --git a/index.js b/index.js deleted file mode 100644 index 72d15a1..0000000 --- a/index.js +++ /dev/null @@ -1,20 +0,0 @@ - -var RtmClient = require('@slack/client').RtmClient; -var RTM_EVENTS = require('@slack/client').RTM_EVENTS; - -var token = process.env.SLACK_API_TOKEN || ''; - -var rtm = new RtmClient(token, { logLevel: 'debug' }); -rtm.start(); - -rtm.on(RTM_EVENTS.MESSAGE, function handleRtmMessage(message) { - console.log('Message:', message); -}); - -rtm.on(RTM_EVENTS.REACTION_ADDED, function handleRtmReactionAdded(reaction) { - console.log('Reaction added:', reaction); -}); - -rtm.on(RTM_EVENTS.REACTION_REMOVED, function handleRtmReactionRemoved(reaction) { - console.log('Reaction removed:', reaction); -}); diff --git a/public/scripts/script.js b/public/scripts/script.js deleted file mode 100644 index 8057ee3..0000000 --- a/public/scripts/script.js +++ /dev/null @@ -1 +0,0 @@ -// YOUR JS CODE FOR ALL PAGES GOES HERE diff --git a/public/stylesheets/style.css b/public/stylesheets/style.css deleted file mode 100644 index 3b08471..0000000 --- a/public/stylesheets/style.css +++ /dev/null @@ -1,5 +0,0 @@ -body { - min-height: 75rem; - padding-top: 6.5rem; - font: 14px "Open Sans", Helvetica, Arial, sans-serif; -} diff --git a/routes/auth.js b/routes/auth.js deleted file mode 100644 index f3fb38a..0000000 --- a/routes/auth.js +++ /dev/null @@ -1,53 +0,0 @@ -// Add Passport-related auth routes here. -var express = require('express'); -var router = express.Router(); -var models = require('../models'); - -module.exports = function(passport) { - - // GET registration page - router.get('/signup', function(req, res) { - res.render('signup'); - }); - - router.post('/signup', function(req, res) { - // validation step - if (req.body.password!==req.body.passwordRepeat) { - return res.render('signup', { - error: "Passwords don't match." - }); - } - var u = new models.User({ - username: req.body.username, - password: req.body.password - }); - u.save(function(err, user) { - if (err) { - console.log(err); - res.status(500).redirect('/register'); - return; - } - console.log(user); - res.redirect('/login'); - }); - }); - - // GET Login page - router.get('/login', function(req, res) { - res.render('login'); - }); - - // POST Login page - router.post('/login', passport.authenticate('local',{ - successRedirect: '/protected', - failureRedirect: '/login' - })); - - // GET Logout page - router.get('/logout', function(req, res) { - req.logout(); - res.redirect('/'); - }); - - return router; -}; diff --git a/routes/routes.js b/routes/routes.js deleted file mode 100644 index 170b699..0000000 --- a/routes/routes.js +++ /dev/null @@ -1,39 +0,0 @@ -var express = require('express'); -var router = express.Router(); -var models = require('../models'); -var User = models.User; - - - -//////////////////////////////// PUBLIC ROUTES //////////////////////////////// -// Users who are not logged in can see these routes - -router.get('/', function(req, res, next) { - res.render('home'); -}); - -///////////////////////////// END OF PUBLIC ROUTES ///////////////////////////// - -router.use(function(req, res, next){ - if (!req.user) { - res.redirect('/login'); - } else { - return next(); - } -}); - -//////////////////////////////// PRIVATE ROUTES //////////////////////////////// -// Only logged in users can see these routes - -router.get('/protected', function(req, res, next) { - res.render('protectedRoute', { - username: req.user.username, - }); -}); - -///////////////////////////// END OF PRIVATE ROUTES ///////////////////////////// - - -router.post('') - -module.exports = router; diff --git a/views/error.hbs b/views/error.hbs deleted file mode 100644 index 0659765..0000000 --- a/views/error.hbs +++ /dev/null @@ -1,3 +0,0 @@ -

{{message}}

-

{{error.status}}

-
{{error.stack}}
diff --git a/views/home.hbs b/views/home.hbs deleted file mode 100644 index dace7f8..0000000 --- a/views/home.hbs +++ /dev/null @@ -1,6 +0,0 @@ -

Home

-

Everyone visiting your site will be able to see this page, no login required

- -
- -Visit a page that requires you to be logged in Here diff --git a/views/layouts/main.hbs b/views/layouts/main.hbs deleted file mode 100644 index 7d66a84..0000000 --- a/views/layouts/main.hbs +++ /dev/null @@ -1,68 +0,0 @@ - - - - - - TITLE OF YOUR APP HERE - - - - - - - - - - - - - -
- {{{body}}} -
- - - - - - - - - - - - diff --git a/views/login.hbs b/views/login.hbs deleted file mode 100644 index cad3680..0000000 --- a/views/login.hbs +++ /dev/null @@ -1,22 +0,0 @@ -{{#if error}} - -{{/if}} -
-

Login

-
- - -
-
- - -
-
- - Register -
-
diff --git a/views/protectedRoute.hbs b/views/protectedRoute.hbs deleted file mode 100644 index ccbc694..0000000 --- a/views/protectedRoute.hbs +++ /dev/null @@ -1,8 +0,0 @@ -

Protected Route!

-

Only logged in people will be able to see this route

- -

You are {{username}}

- -
- -Logout diff --git a/views/signup.hbs b/views/signup.hbs deleted file mode 100644 index 48b907a..0000000 --- a/views/signup.hbs +++ /dev/null @@ -1,25 +0,0 @@ -{{#if error}} - -{{/if}} -
-

Register

-
- - -
-
- - -
-
- - -
-
- -
-
From 35df4ea7f72fadf1d5946a2147a6f38f63aec3be Mon Sep 17 00:00:00 2001 From: danhuiZ Date: Tue, 18 Jul 2017 13:11:12 -0700 Subject: [PATCH 05/10] /slack/interactive works --- app.js | 8 ++++---- bot.js | 4 ++-- models.js | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/app.js b/app.js index b6b2896..bad408d 100644 --- a/app.js +++ b/app.js @@ -2,7 +2,7 @@ var express = require('express'); var google = require('googleapis'); // var OAuth2 = require('client-oauth2') var OAuth2 = google.auth.OAuth2; -var models = require('./models'); +var { User } = require('./models'); // REQUIRED SOURCE CHECKS var REQUIRED_ENV = "SLACK_SECRET MONGODB_URI".split(" "); @@ -17,6 +17,8 @@ REQUIRED_ENV.forEach(function(el) { // RUNNING SERVER var app = express(); var bodyParser = require('body-parser'); +app.use(bodyParser.json()); +app.use(bodyParser.urlencoded({ extended: false })); /* BOT CODE */ require('./bot'); @@ -52,7 +54,7 @@ app.get('/connect/callback', function(req, res){ oauth2Client.setCredentials(tokens); } var state = JSON.parse(decodeURIComponent(req.query.state)); - models.User.findByIdAndUpdate(state.auth_id, { + User.findByIdAndUpdate(state.auth_id, { googleAccount: { access_token: tokens.access_token, refresh_token: tokens.refresh_token, @@ -69,9 +71,7 @@ app.get('/connect/callback', function(req, res){ res.send(200) }) - app.post('/slack/interactive', function(req, res){ - var payload = JSON.parse(req.body.payload); console.log("PAYLOAD", payload); var timeNow = Date.now(); diff --git a/bot.js b/bot.js index 03e0ac5..1a40911 100644 --- a/bot.js +++ b/bot.js @@ -3,7 +3,7 @@ require('./app'); // CONNECTING TO MONGOOSE DB var mongoose = require('mongoose'); mongoose.connect(process.env.MONGODB_URI); -var models = require('./models'); +var { User } = require('./models'); var { RtmClient, WebClient, CLIENT_EVENTS, RTM_EVENTS } = require('@slack/client'); var axios = require('axios'); @@ -56,7 +56,7 @@ rtm.on(RTM_EVENTS.MESSAGE, function handleRtmMessage(message) { var u = rtm.dataStore.getUserById(message.user); //CHECK FOR USER OR CREATE ONE - models.User.findOne({slack_ID: message.user}) + User.findOne({slack_ID: message.user}) .then(function(user){ if(!user){ var user = new models.User({ diff --git a/models.js b/models.js index 4b8147b..3273201 100644 --- a/models.js +++ b/models.js @@ -1,4 +1,6 @@ var mongoose = require('mongoose'); +mongoose.Promise = global.Promise; +mongoose.connect(process.env.MONGODB_URI); var userSchema = mongoose.Schema({ googleAccount: { @@ -12,8 +14,6 @@ var userSchema = mongoose.Schema({ slack_DM_ID: String }); - - User = mongoose.model('User', userSchema); module.exports = { From 231eed3e0924d31ad603103a78388b1afeb89dab Mon Sep 17 00:00:00 2001 From: danhuiZ Date: Tue, 18 Jul 2017 16:21:33 -0700 Subject: [PATCH 06/10] commit to my branch --- app.js | 147 ++++++++++++++++++++++++++++++++++++++---------------- bot.js | 39 +++++++++------ models.js | 22 +++++--- 3 files changed, 145 insertions(+), 63 deletions(-) diff --git a/app.js b/app.js index bad408d..c1132ce 100644 --- a/app.js +++ b/app.js @@ -1,11 +1,10 @@ var express = require('express'); var google = require('googleapis'); -// var OAuth2 = require('client-oauth2') var OAuth2 = google.auth.OAuth2; var { User } = require('./models'); // REQUIRED SOURCE CHECKS -var REQUIRED_ENV = "SLACK_SECRET MONGODB_URI".split(" "); +var REQUIRED_ENV = "SLACK_SECRET MONGODB_URI GOOGLE_CLIENT_ID GOOGLE_CLIENT_SECRET DOMAIN".split(" "); REQUIRED_ENV.forEach(function(el) { if (!process.env[el]){ @@ -21,54 +20,76 @@ app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: false })); /* BOT CODE */ -require('./bot'); +var { rtm } = require('./bot'); /* ******** */ -var oauth2Client = new OAuth2( - process.env.GOOGLE_CLIENT_ID, - process.env.GOOGLE_CLIENT_SECRET, - process.env.DOMAIN + '/connect/callback' //redirect url -); +function getGoogleAuth() { + return new OAuth2( + process.env.GOOGLE_CLIENT_ID, + process.env.GOOGLE_CLIENT_SECRET, + process.env.DOMAIN + '/connect/callback' //redirect url + ); +} app.get('/connect', function(req, res){ - var url = oauth2Client.generateAuthUrl({ - access_type: 'offline', //'online' (default) or 'offline' (gets refresh_token) - prompt: 'consent', - scope: [ - 'https://www.googleapis.com/auth/userinfo.profile', - 'https://www.googleapis.com/auth/calendar' - ], // generate a url that asks permissions for Google+ and Google Calendar scopes - state: encodeURIComponent(JSON.stringify({ - auth_id: req.query.auth_id - })) // Optional property that passes state parameters to redirect URI - }); - // console.log(url); - res.redirect(url); + var userId = req.query.auth_id; + if (!userId) { + res.status(400).send("Missing user id"); + } else { + User.findById(userId) + .then(function(user){ + if (!user) { + res.status(404).send("Cannot find user"); + } else { + var googleAuth = getGoogleAuth(); + var url = googleAuth.generateAuthUrl({ + access_type: 'offline', //'online' (default) or 'offline' (gets refresh_token) + prompt: 'consent', + scope: [ + 'https://www.googleapis.com/auth/userinfo.profile', + 'https://www.googleapis.com/auth/calendar' + ], // generate a url that asks permissions for Google+ and Google Calendar scopes + // state: encodeURIComponent(JSON.stringify({ + // auth_id: req.query.auth_id + // })) // Optional property that passes state parameters to redirect URI + state: userId + }); + res.redirect(url); + } + }) + } }) app.get('/connect/callback', function(req, res){ - oauth2Client.getToken(req.query.code, function (err, tokens) { + var googleAuth = getGoogleAuth(); + googleAuth.getToken(req.query.code, function (err, tokens) { console.log(tokens); - // Now tokens contains an access_token and an optional refresh_token. Save them. - if (!err) { - oauth2Client.setCredentials(tokens); - } - var state = JSON.parse(decodeURIComponent(req.query.state)); - User.findByIdAndUpdate(state.auth_id, { - googleAccount: { - access_token: tokens.access_token, - refresh_token: tokens.refresh_token, - profile_ID: tokens.id_token + // Now tokens contains an access_token and an optional refresh_token. Save them. + if (err) { + res.status(500).json({error: err}); + } else { + googleAuth.setCredentials(tokens); + var plus = google.plus('v1'); + plus.people.get({auth: googleAuth, userId: 'me'}, function(err, googleUser) { + if (err) { + res.status(500).json({error: err}); + } else { + User.findById(req.query.state) + .then(function(mongoUser){ + mongoUser.googleAccount = tokens; + mongoUser.googleAccount.expiry_date = tokens.expiry_date; + mongoUser.googleAccount.profile_ID = googleUser.id; + mongoUser.googleAccount.profile_name = googleUser.displayName; + return mongoUser.save(); + }) + .then(function(mongoUser){ + res.send('You are connected to Google Calendar'); + rtm.sendMessage('You are connected to Google Calendar', mongoUser.slack_DM_ID) + }) + } + }) } - }) - .then(function(user){ - user.save(); - }) - .catch(function(err){ - console.log("Error", err); - }) -}); - res.send(200) + }); }) app.post('/slack/interactive', function(req, res){ @@ -77,8 +98,50 @@ app.post('/slack/interactive', function(req, res){ var timeNow = Date.now(); if(payload.actions[0].value === 'yes') { res.send('Created reminder :white_check_mark:'); + + // CONNECT TO API.AI NOW THAT YOU HAVE SET UP GOOGLE SHIT + var curTime = Date.now(); + console.log("CURRENT TIME " + curTime); + //FIND MONGODB ENTRY TO GET TOKENS AND EXPIRY DATE (maybe this goes in a route too) + User.findOne({slack_DM_ID: payload.channel.id}) + .then(function(user){ + if(curTime > user.googleAccount.expiry_date){ + /* CODE HERE TO REFRESH ACCESS TOKEN */ + return; + }else{ + console.log('token still good homie'); + return user; + } + }) + .then(function(user){ + //POST MESSAGE TO GOOGLE CALENDAR + if(user){ + //create calendar event here + var new_event = { + "end": { + "date": "2017-07-19" + }, + "start": { + "date": "2017-07-19" + }, + "description": "you are a gawd", + "summary": "EVENT1" + } + + axios.post(`https://www.googleapis.com/calendar/v3/calendars/primary/events?access_token=${user.googleAccount.access_token}`, new_event) + .then(function(response){ + console.log('SUCCESSFULLY POSTED TO CALENDAR'); + }) + .catch(function(err){ + console.log(err); + }) + } + }) + + + } else { + res.send('Cancelled :x:'); } - res.send('Cancelled :x:'); }) diff --git a/bot.js b/bot.js index 1a40911..a3e87d6 100644 --- a/bot.js +++ b/bot.js @@ -1,4 +1,4 @@ -require('./app'); +var app = require('./app'); // CONNECTING TO MONGOOSE DB var mongoose = require('mongoose'); @@ -50,8 +50,7 @@ rtm.on(RTM_EVENTS.MESSAGE, function handleRtmMessage(message) { console.log('Message not send to DM, ignoring'); return; } - - var temp = encodeURIComponent(message.text); + // var temp = encodeURIComponent(message.text); //CHECK IF THEY ARE IN MONGO AS HAVING REGISTERED GOOGLE var u = rtm.dataStore.getUserById(message.user); @@ -59,30 +58,31 @@ rtm.on(RTM_EVENTS.MESSAGE, function handleRtmMessage(message) { User.findOne({slack_ID: message.user}) .then(function(user){ if(!user){ - var user = new models.User({ + return new User({ slack_ID: message.user, + slack_DM_ID: message.channel, slack_Username: u.profile.real_name, slack_Email: u.profile.email, - slack_DM_ID: message.channel - }) - return user.save(); + }).save(); } return user; }) .then(function(user){ - if(!user.googleAccount.access_token){ + console.log("USER IS", user); + if(!user.googleAccount){ //submit the link to grant access + rtm.sendMessage("Hello This is Scheduler bot. In order to schedule reminders for you, I need access to you Google calendar", message.channel); web.chat.postMessage(message.channel, 'Use this link to give access to your google cal account http://localhost:3000/connect?auth_id=' + user._id); return; } - // rtm.sendMessage("hello i am seeing and replying to your meesage", message.channel); + axios.get('https://api.api.ai/api/query', { params: { v: 20150910, lang: 'en', - timezone: '2017-07-17T16:58:21-0700', + // timezone: '2017-07-17T16:58:21-0700', query: message.text, sessionId: message.user }, @@ -91,23 +91,30 @@ rtm.on(RTM_EVENTS.MESSAGE, function handleRtmMessage(message) { } }) .then(function( {data} ) { - console.log("DATA", data); + console.log("DATA", data, "messages", data.result.fulfillment.messages); if(!data.result.actionIncomplete && data.result.parameters.date && data.result.parameters.subject ) { // rtm.sendMessage(data.result.fulfillment.speech, message.channel); - web.chat.postMessage(message.channel, 'Ok', imReply(data), function(err, res) { + web.chat.postMessage(message.channel, 'Chill homie', imReply(data), function(err, res) { if (err) { console.log('Error:', err); } else { console.log('Message sent: ', res); } }); - } else { - console.log("ACTION IS COMPLETE"); + } else if(data.result.parameters.date){ + console.log('NO SUBJECT'); + // state.date = data.result.parameters.date; + rtm.sendMessage(data.result.fulfillment.speech, message.channel); + } else if(data.result.parameters.subject){ + console.log('NO DATE'); + // state.subject = data.result.parameters.subject; + rtm.sendMessage(data.result.fulfillment.speech, message.channel); } }) .catch(function(err) { console.log("ERROR", err); }) + }); }); @@ -118,3 +125,7 @@ rtm.on(RTM_EVENTS.MESSAGE, function handleRtmMessage(message) { rtm.on(RTM_EVENTS.REACTION_REMOVED, function handleRtmReactionRemoved(reaction) { console.log('Reaction removed:', reaction); }); + +module.exports = { + rtm +}; diff --git a/models.js b/models.js index 3273201..869b5ae 100644 --- a/models.js +++ b/models.js @@ -3,15 +3,23 @@ mongoose.Promise = global.Promise; mongoose.connect(process.env.MONGODB_URI); var userSchema = mongoose.Schema({ - googleAccount: { - access_token: String, - refresh_token: String, - profile_ID: String + // googleAccount: { + // access_token: String, + // refresh_token: String, + // profile_ID: String, + // profile_name: String + // }, + googleAccount: {}, + slack_ID: { + type: String, + required: true + }, + slack_DM_ID: { + type: String, + required: true }, - slack_ID: String, slack_Username: String, - slack_Email: String, - slack_DM_ID: String + slack_Email: String }); User = mongoose.model('User', userSchema); From c1a40c35ea0601a0481464c4fe2029589aac2cb8 Mon Sep 17 00:00:00 2001 From: danhuiZ Date: Tue, 18 Jul 2017 22:43:03 -0700 Subject: [PATCH 07/10] Still cannot schedule reminder --- app.js | 69 ++++++++---- bot.js | 38 ++++--- cronjob.js | 43 ++++++++ master.js | 308 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 426 insertions(+), 32 deletions(-) create mode 100644 cronjob.js create mode 100644 master.js diff --git a/app.js b/app.js index c1132ce..7130866 100644 --- a/app.js +++ b/app.js @@ -2,10 +2,10 @@ var express = require('express'); var google = require('googleapis'); var OAuth2 = google.auth.OAuth2; var { User } = require('./models'); +var axios = require('axios'); // REQUIRED SOURCE CHECKS var REQUIRED_ENV = "SLACK_SECRET MONGODB_URI GOOGLE_CLIENT_ID GOOGLE_CLIENT_SECRET DOMAIN".split(" "); - REQUIRED_ENV.forEach(function(el) { if (!process.env[el]){ console.error("Missing required env var " + el); @@ -19,9 +19,10 @@ var bodyParser = require('body-parser'); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: false })); -/* BOT CODE */ -var { rtm } = require('./bot'); -/* ******** */ +// BOT CODE +var { rtm, pendingState } = require('./bot'); +console.log("JUST GOT PENDING STATE OH YEAH", pendingState); + function getGoogleAuth() { return new OAuth2( @@ -30,6 +31,7 @@ function getGoogleAuth() { process.env.DOMAIN + '/connect/callback' //redirect url ); } +var googleAuth = getGoogleAuth(); app.get('/connect', function(req, res){ var userId = req.query.auth_id; @@ -61,30 +63,28 @@ app.get('/connect', function(req, res){ }) app.get('/connect/callback', function(req, res){ - var googleAuth = getGoogleAuth(); googleAuth.getToken(req.query.code, function (err, tokens) { - console.log(tokens); - // Now tokens contains an access_token and an optional refresh_token. Save them. + console.log("HERE ARE THE TOKENS", tokens); // Now tokens contains an access_token and an optional refresh_token. Save them. if (err) { res.status(500).json({error: err}); } else { googleAuth.setCredentials(tokens); var plus = google.plus('v1'); plus.people.get({auth: googleAuth, userId: 'me'}, function(err, googleUser) { + console.log("GOOGLEUSER! ME!", googleUser); if (err) { res.status(500).json({error: err}); } else { User.findById(req.query.state) .then(function(mongoUser){ mongoUser.googleAccount = tokens; - mongoUser.googleAccount.expiry_date = tokens.expiry_date; mongoUser.googleAccount.profile_ID = googleUser.id; mongoUser.googleAccount.profile_name = googleUser.displayName; return mongoUser.save(); }) .then(function(mongoUser){ - res.send('You are connected to Google Calendar'); - rtm.sendMessage('You are connected to Google Calendar', mongoUser.slack_DM_ID) + res.send('You are connected to Google Calendar'); //To /connect/callback webpage + rtm.sendMessage('You are connected to Google Calendar. Now set your first reminder by talking to me!', mongoUser.slack_DM_ID) //To slack channel }) } }) @@ -95,8 +95,14 @@ app.get('/connect/callback', function(req, res){ app.post('/slack/interactive', function(req, res){ var payload = JSON.parse(req.body.payload); console.log("PAYLOAD", payload); - var timeNow = Date.now(); if(payload.actions[0].value === 'yes') { + // Manually delete user from MongoDB + // User.remove({slack_DM_ID: payload.channel.id}, function(err) { + // if(err){ + // console.log("error removing user", err); + // } + // }) + res.send('Created reminder :white_check_mark:'); // CONNECT TO API.AI NOW THAT YOU HAVE SET UP GOOGLE SHIT @@ -105,8 +111,15 @@ app.post('/slack/interactive', function(req, res){ //FIND MONGODB ENTRY TO GET TOKENS AND EXPIRY DATE (maybe this goes in a route too) User.findOne({slack_DM_ID: payload.channel.id}) .then(function(user){ + console.log("HERE HERE HERE HERE USER IS HERE", user); if(curTime > user.googleAccount.expiry_date){ - /* CODE HERE TO REFRESH ACCESS TOKEN */ + console.log('fuck did i make it here'); + console.log("BEFORE REFRESHING", user.googleAccount.access_token); + googleAuth.refreshAccessToken(function(err, tokens) { + console.log("REFRESHED token", tokens); + user.googleAccount.access_token = tokens.access_token; + }); + console.log("AFTER REFRESHING", user.googleAccount.access_token); return; }else{ console.log('token still good homie'); @@ -116,31 +129,49 @@ app.post('/slack/interactive', function(req, res){ .then(function(user){ //POST MESSAGE TO GOOGLE CALENDAR if(user){ + console.log("CHECK PENDING STATE", pendingState); //create calendar event here var new_event = { "end": { - "date": "2017-07-19" + "date": pendingState.date }, "start": { - "date": "2017-07-19" + "date": pendingState.date }, "description": "you are a gawd", - "summary": "EVENT1" + "summary": pendingState.subject } axios.post(`https://www.googleapis.com/calendar/v3/calendars/primary/events?access_token=${user.googleAccount.access_token}`, new_event) .then(function(response){ - console.log('SUCCESSFULLY POSTED TO CALENDAR'); + console.log('SUCCESSFULLY POSTED TO CALENDAR'); + console.log('THIS IS THE INFORMATION THE USER HAS', user); + console.log('this is the state', pendingState); + var reminder = new Reminder({ + subject: pendingState.subject, + day: pendingState.date, + googCalID: user.googleAccount.profile_ID, + reqID: user._id + }) + console.log('this is the REMINDER', reminder); + reminder.save(function(err) { + if(err) { + console.log("Error saving reminder, I cry", err); + } + }); + //reset pendingState + pendingState = { + date: '', + subject: '' + } }) .catch(function(err){ console.log(err); }) } }) - - } else { - res.send('Cancelled :x:'); + res.send('Cancelled :x: :pray: :100: :fire:'); } }) diff --git a/bot.js b/bot.js index a3e87d6..44a6881 100644 --- a/bot.js +++ b/bot.js @@ -1,10 +1,9 @@ var app = require('./app'); -// CONNECTING TO MONGOOSE DB +// CONNECTING TO MONGO_DB var mongoose = require('mongoose'); mongoose.connect(process.env.MONGODB_URI); var { User } = require('./models'); - var { RtmClient, WebClient, CLIENT_EVENTS, RTM_EVENTS } = require('@slack/client'); var axios = require('axios'); @@ -43,22 +42,27 @@ rtm.on(CLIENT_EVENTS.RTM.AUTHENTICATED, (rtmStartData) => { console.log(`logged in as ${rtmStartData.self.name} of team ${rtmStartData.team.name}, but not yet connected to a channel`); }) +var pendingState = { + subject: "", + date: "" +}; + rtm.on(RTM_EVENTS.MESSAGE, function handleRtmMessage(message) { var dm = rtm.dataStore.getDMByUserId(message.user); - console.log("DM--------", dm, "MESSAGE", message); + console.log("DM--------", dm, "MESSAGE-------", message); if (!dm || dm.id !== message.channel || message.type !== 'message') { console.log('Message not send to DM, ignoring'); return; } - // var temp = encodeURIComponent(message.text); //CHECK IF THEY ARE IN MONGO AS HAVING REGISTERED GOOGLE var u = rtm.dataStore.getUserById(message.user); - //CHECK FOR USER OR CREATE ONE User.findOne({slack_ID: message.user}) .then(function(user){ + //SET UP INITIAL SLACK INFO IN MONGO if(!user){ return new User({ + default_meeting_len: 30, slack_ID: message.user, slack_DM_ID: message.channel, slack_Username: u.profile.real_name, @@ -70,7 +74,7 @@ rtm.on(RTM_EVENTS.MESSAGE, function handleRtmMessage(message) { .then(function(user){ console.log("USER IS", user); if(!user.googleAccount){ - //submit the link to grant access + //submit the link to grant Google access rtm.sendMessage("Hello This is Scheduler bot. In order to schedule reminders for you, I need access to you Google calendar", message.channel); web.chat.postMessage(message.channel, 'Use this link to give access to your google cal account http://localhost:3000/connect?auth_id=' @@ -90,10 +94,11 @@ rtm.on(RTM_EVENTS.MESSAGE, function handleRtmMessage(message) { Authorization: `Bearer ${process.env.API_AI_TOKEN}` } }) - .then(function( {data} ) { - console.log("DATA", data, "messages", data.result.fulfillment.messages); + .then(function( { data } ) { + console.log("DATA", data, "DATA-messages", data.result.fulfillment.messages); if(!data.result.actionIncomplete && data.result.parameters.date && data.result.parameters.subject ) { // rtm.sendMessage(data.result.fulfillment.speech, message.channel); + pendingState = data.result.parameters; web.chat.postMessage(message.channel, 'Chill homie', imReply(data), function(err, res) { if (err) { console.log('Error:', err); @@ -101,15 +106,19 @@ rtm.on(RTM_EVENTS.MESSAGE, function handleRtmMessage(message) { console.log('Message sent: ', res); } }); - } else if(data.result.parameters.date){ + } else if(data.result.parameters.date && !data.result.parameters.subject){ console.log('NO SUBJECT'); - // state.date = data.result.parameters.date; + pendingState.date = data.result.parameters.date; rtm.sendMessage(data.result.fulfillment.speech, message.channel); - } else if(data.result.parameters.subject){ + } else if(data.result.parameters.subject && !data.result.parameters.date){ console.log('NO DATE'); - // state.subject = data.result.parameters.subject; + pendingState.subject = data.result.parameters.subject; + rtm.sendMessage(data.result.fulfillment.speech, message.channel); + } else { rtm.sendMessage(data.result.fulfillment.speech, message.channel); } + console.log("HOW IS PENDING STATE LOOKING RIGHT NOW? HMM?", pendingState); + return pendingState; }) .catch(function(err) { console.log("ERROR", err); @@ -126,6 +135,9 @@ rtm.on(RTM_EVENTS.MESSAGE, function handleRtmMessage(message) { console.log('Reaction removed:', reaction); }); +console.log("I'M NOT GIVING UP, PEDNING STATE IS HERE", pendingState); + module.exports = { - rtm + rtm: rtm, + pendingState: pendingState }; diff --git a/cronjob.js b/cronjob.js new file mode 100644 index 0000000..22241f2 --- /dev/null +++ b/cronjob.js @@ -0,0 +1,43 @@ +var mongoose = require('mongoose'); +mongoose.connect(process.env.MONGODB_URI); + +var { User, Reminder } = require('./models'); +var { rtm } = require('./app'); + +Reminder.find({}, function(err, reminders) { + console.log("REMINDERS", reminders); + if(err) { + console.log('There was an error with finding the reminders'); + } else { + // reminders is an array of reminder JSONs + const curDate = new Date().toLocaleDateString(); + //sets up the next day + const tomDay = parseInt(curDate.split('/')[1]) + 1; + let tomDate = curDate.split('/') + tomDate[1] = parseInt(tomDate[1]) + 1; + tomDate = tomDate.join('/') + console.log("TODAY DATE", curDate, "TOMORROW DATE", tomDate); + + reminders.forEach(function(reminder) { + if( curDate === reminder.day ) { //On due day of reminder, send Slack msg & delete the reminder doc + console.log("Reminder now", reminder); + console.log('need to send RTM message here'); + User.findById(reminder.reqID, function(err, user) { + console.log("TODAY, USER iS", user); + rtm.sendMessage(`Reminder! You gotta remember to ${reminder.subject} today bro!`, user.slack_DM_ID) + if(!err) { + Reminder.remove({reqID: reminder.reqID}, function(err) { + if(err) { + console.log("Error removing reminder for today!"); + } + }) + } + }) + } else if ( tomDate === reminder.day ) { //On day before due day of reminder, send Slack msg to app user + User.findById(reminder.reqID, function(err, user) { + rtm.sendMessage(`Reminder! You gotta remember to ${reminder.subject} tomorrow bro!`, user.slack_DM_ID) + }) + } + }) + } +}) diff --git a/master.js b/master.js new file mode 100644 index 0000000..17adb26 --- /dev/null +++ b/master.js @@ -0,0 +1,308 @@ +var express = require('express'); +var bodyParser = require('body-parser'); +var google = require('googleapis'); +var RtmClient = require('@slack/client').RtmClient; +var RTM_EVENTS = require('@slack/client').RTM_EVENTS; +var WebClient = require('@slack/client').WebClient; + +var mongoose = require('mongoose'); +var models = require('./models'); +var axios = require('axios'); + + +var token = process.env.SLACK_SECRET || ''; +var web = new WebClient(token); +var rtm = new RtmClient(token); +var app = express(); +var plus = google.plus('v1') +rtm.start(); + +var OAuth2 = google.auth.OAuth2; +mongoose.connect(process.env.MONGODB_URI); + +// REQUIRED SOURCE CHECKS +var REQUIRED_ENV = "SLACK_SECRET MONGODB_URI GOOGLE_CLIENT_ID GOOGLE_CLIENT_SECRET DOMAIN".split(" "); + +REQUIRED_ENV.forEach(function(el) { + if (!process.env[el]){ + console.error("Missing required env var " + el); + process.exit(1); + } +}); + +var obj = { + "attachments": [ + { + "text": "Is this ok?", + "fallback": "You are unable to choose a game", + "callback_id": "wopr_game", + "color": "#3AA3E3", + "attachment_type": "default", + "actions": [ + { + "name": "confrim", + "text": "Yes", + "type": "button", + "value": "yes" + }, + { + "name": "confirm", + "text": "Cancel", + "type": "button", + "value": "cancel" + }, + ] + } + ] +} + +var state = { + subject: "", + date: "" +}; + + +var handlerFunction = function(data, message){ + console.log('this is supposed to be the data', data); + if(data.result.parameters.date && data.result.parameters.subject){ + state.date = data.result.parameters.date; state.subject = data.result.parameters.subject; + obj.attachments[0].text = `Subject:${state.subject} ---- Time:${data.result.parameters.date}`; + web.chat.postMessage(message.channel, "Confirm this request", obj, function(err, res) { + if (err) { + console.log('Error:', err); + } else { + console.log('Message sent: ', res); + } + }); + } else if(data.result.parameters.subject){ + state.subject = data.result.parameters.subject; + rtm.sendMessage(data.result.fulfillment.speech, message.channel); + } +} + +var responseFunction = function(data, message){ + if(!state.date) { + state.date = data.result.parameters.date; + } + if(!state.subject) { + state.subject = data.result.parameters.subject + } + obj.attachments[0].text = `Subject:${state.subject} ---- Time:${data.result.parameters.date}`; + web.chat.postMessage(message.channel, "Confirm this request", obj, function(err, res){ + if (err) { + console.log('Error:', err); + } else { + console.log('Message sent: ', res); + } + }) +} + +rtm.on(RTM_EVENTS.MESSAGE, function handleRtmMessage(message) { + var dm = rtm.dataStore.getDMByUserId(message.user); + if (!dm || dm.id !== message.channel || message.type !== 'message') { + return; + } + ////////////////////////////////////////////////ANDREWS FLOW HERE////////////////////////////// + var u = rtm.dataStore.getUserById(message.user); + //CHECK FOR USER OR CREATE ONE + models.User.findOne({slack_ID: message.user}) + .then(function(user){ + //SET UP INITIAL SLACK INFO IN MONGO + if(!user){ + var user = new models.User({ + default_meeting_len: 30, + slack_ID: message.user, + slack_Username: u.profile.real_name, + slack_Email: u.profile.email, + slack_DM_ID: message.channel + }) + return user.save(); + } else{ + return user; + } + }) + //at this point there is a user model + .then(function(user){ + //AUTHORIZE GOOGLE ACCOUNT LINK + if(!user.googleAccount.access_token){ + web.chat.postMessage(message.channel, + 'Use this link to give access to your google cal account http://localhost:3000/connect?auth_id=' + + user._id); + return; + } else { + console.log('the first time it gets here'); + var temp = encodeURIComponent(message.text); + axios.get(`https://api.api.ai/api/query?v=20150910&query=${temp}&lang=en&sessionId=${message.user}`, { + "headers": { + "Authorization":"Bearer 678861ee7c0d455287f791fd46d1b344" + }, + }) + .then(function({ data }){ + + if(state.subject && !state.date){ + console.log('I AM MADE, YEAH I MADE It'); + responseFunction(data, message); + } else if(state.date && !state.subject){ + responseFunction(data, message) + } else if(state.date && state.subject){ + rtm.sendMessage("Reply to previous task status", message.channel); + } else { + handlerFunction(data, message); + } + + }) + .catch(function(error){ + console.log(error); + }) + + } + + }) + + }) + + rtm.on(RTM_EVENTS.REACTION_ADDED, function handleRtmReactionAdded(reaction) { + console.log('Reaction added:', reaction); + }); + + rtm.on(RTM_EVENTS.REACTION_REMOVED, function handleRtmReactionRemoved(reaction) { + console.log('Reaction removed:', reaction); + }); + + + app.use(bodyParser.urlencoded({ extended: false })); + app.use(bodyParser.json()); + + var oauth2Client = new OAuth2( + process.env.GOOGLE_CLIENT_ID, + process.env.GOOGLE_CLIENT_SECRET, + process.env.DOMAIN + '/connect/callback' + ); + + app.get('/connect', function(req, res){ + var url = oauth2Client.generateAuthUrl({ + access_type: 'offline', + prompt: 'consent', + scope: [ + 'https://www.googleapis.com/auth/userinfo.profile', + 'https://www.googleapis.com/auth/calendar' + ], + state: encodeURIComponent(JSON.stringify({ + auth_id: req.query.auth_id + })) + }); + res.redirect(url); + }) + + + app.get('/connect/callback', function(req, res){ + oauth2Client.getToken(req.query.code, function (err, tokens) { + // Now tokens contains an access_token and an optional refresh_token. Save them. + oauth2Client.setCredentials(tokens); + + plus.people.get({auth: oauth2Client, userId: 'me'}, function(err, googleUser) { + + //UPDATE GOOGLE CREDENTIALS FOR USER + var state = JSON.parse(decodeURIComponent(req.query.state)) + + models.User.findByIdAndUpdate(state.auth_id, { + googleAccount: { + access_token: tokens.access_token, + refresh_token: tokens.refresh_token, + profile_ID: googleUser.id, + expiry_date: tokens.expiry_date, + profile_name: googleUser.displayName + } + }) + .then(function(user){ + user.save(); + }) + .catch(function(err){ + console.log('ERROR ' + err); + }) + }) + + }); + + res.send(``); + + }) + + app.get('/', function(req,res){ + res.send("reached home"); + }) + + app.post('/bot-test', function(req,res){ + + // CONNECT TO API.AI NOW THAT YOU HAVE SET UP GOOGLE SHIT + var curTime = Date.now(); + + console.log(state); + //FIND MONGODB ENTRY TO GET TOKENS AND EXPIRY DATE (maybe this goes in a route too) + models.User.findOne({slack_ID: JSON.parse(req.body.payload).user.id}) + .then(function(user){ + if(curTime > user.googleAccount.expiry_date){ + console.log('fuck did i make it here'); + return; + }else{ + console.log('token still good homie'); + return user; + } + }) + //this part needs to be moved into the post request + .then(function(user) { + //POST MESSAGE TO GOOGLE CALENDAR + if(user){ + //create calendar event here + var new_event = { + "end": { + "date": state.date + }, + "start": { + "date": state.date + }, + "description": "Chief Keef is a fucking legend", + "summary": state.subject + } + + axios.post(`https://www.googleapis.com/calendar/v3/calendars/primary/events?access_token=${user.googleAccount.access_token}`, new_event) + .then(function(response){ + console.log('SUCCESSFULLY POSTED TO CALENDAR'); + console.log('THIS IS THE INFORMATION THE USER HAS', user); + console.log('this is the state', state); + var reminder = new models.Reminder({ + subject: state.subject, + day: state.date, + googCalID: user.googleAccount.profile_ID, + reqID: user.slack_ID + }) + + console.log('this is the REMINDER', reminder); + reminder.save(function(err) { + if(err) { + console.log('there is an error', err); + } else { + console.log('YOUNG BUT IM MAKING MILLION TO WORK THE NIGHT SHIFT'); + } + }); + + state = { + date: '', + subject: '' + } + + }) + .catch(function(err){ + console.log(err); + }) + } + + }) + + res.send(':pray: :100: :fire:') + + }) + + app.listen(3000); From e4776b2f290718e301d466304bc56016e64c5be6 Mon Sep 17 00:00:00 2001 From: danhuiZ Date: Tue, 18 Jul 2017 23:15:32 -0700 Subject: [PATCH 08/10] Yay it works --- app.js | 136 +++++++++++++++++++++++- bot.js | 285 +++++++++++++++++++++++++------------------------- master.js | 308 ------------------------------------------------------ 3 files changed, 275 insertions(+), 454 deletions(-) delete mode 100644 master.js diff --git a/app.js b/app.js index 7130866..a5a382d 100644 --- a/app.js +++ b/app.js @@ -19,9 +19,139 @@ var bodyParser = require('body-parser'); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: false })); -// BOT CODE -var { rtm, pendingState } = require('./bot'); -console.log("JUST GOT PENDING STATE OH YEAH", pendingState); +/* BOT CODE */ +// CONNECTING TO MONGO_DB +var mongoose = require('mongoose'); +mongoose.connect(process.env.MONGODB_URI); +var { RtmClient, WebClient, CLIENT_EVENTS, RTM_EVENTS } = require('@slack/client'); + +function imReply(data) { + return ({"attachments": [ + { + "text": `Creating a reminder for '${data.result.parameters.subject}' on ${data.result.parameters.date}`, + "fallback": "You are unable to create reminder", + "callback_id": "reminder", + "color": "#3AA3E3", + "attachment_type": "default", + "actions": [ + { + "name": "confrim", + "text": "Yes", + "type": "button", + "value": "yes" + }, + { + "name": "confirm", + "text": "No", + "type": "button", + "value": "no" + }, + ] + } + ]}) +} + +var token = process.env.SLACK_SECRET || ''; +var web = new WebClient(token); +var rtm = new RtmClient(token); +rtm.start(); + +rtm.on(CLIENT_EVENTS.RTM.AUTHENTICATED, (rtmStartData) => { + console.log(`logged in as ${rtmStartData.self.name} of team ${rtmStartData.team.name}, but not yet connected to a channel`); +}) + +var pendingState = { + subject: "", + date: "" +}; + +rtm.on(RTM_EVENTS.MESSAGE, function handleRtmMessage(message) { + var dm = rtm.dataStore.getDMByUserId(message.user); + console.log("DM--------", dm, "MESSAGE-------", message); + if (!dm || dm.id !== message.channel || message.type !== 'message') { + console.log('Message not send to DM, ignoring'); + return; + } + //CHECK IF THEY ARE IN MONGO AS HAVING REGISTERED GOOGLE + var u = rtm.dataStore.getUserById(message.user); + //CHECK FOR USER OR CREATE ONE + User.findOne({slack_ID: message.user}) + .then(function(user){ + //SET UP INITIAL SLACK INFO IN MONGO + if(!user){ + return new User({ + default_meeting_len: 30, + slack_ID: message.user, + slack_DM_ID: message.channel, + slack_Username: u.profile.real_name, + slack_Email: u.profile.email, + }).save(); + } + return user; + }) + .then(function(user){ + console.log("USER IS", user); + if(!user.googleAccount){ + //submit the link to grant Google access + rtm.sendMessage("Hello This is Scheduler bot. In order to schedule reminders for you, I need access to you Google calendar", message.channel); + web.chat.postMessage(message.channel, + 'Use this link to give access to your google cal account http://localhost:3000/connect?auth_id=' + + user._id); + return; + } + + axios.get('https://api.api.ai/api/query', { + params: { + v: 20150910, + lang: 'en', + // timezone: '2017-07-17T16:58:21-0700', + query: message.text, + sessionId: message.user + }, + headers: { + Authorization: `Bearer ${process.env.API_AI_TOKEN}` + } + }) + .then(function( { data } ) { + console.log("DATA", data, "DATA-messages", data.result.fulfillment.messages); + if(!data.result.actionIncomplete && data.result.parameters.date && data.result.parameters.subject ) { + // rtm.sendMessage(data.result.fulfillment.speech, message.channel); + pendingState = data.result.parameters; + web.chat.postMessage(message.channel, 'Chill homie', imReply(data), function(err, res) { + if (err) { + console.log('Error:', err); + } else { + console.log('Message sent: ', res); + } + }); + } else if(data.result.parameters.date && !data.result.parameters.subject){ + console.log('NO SUBJECT'); + pendingState.date = data.result.parameters.date; + rtm.sendMessage(data.result.fulfillment.speech, message.channel); + } else if(data.result.parameters.subject && !data.result.parameters.date){ + console.log('NO DATE'); + pendingState.subject = data.result.parameters.subject; + rtm.sendMessage(data.result.fulfillment.speech, message.channel); + } else { + rtm.sendMessage(data.result.fulfillment.speech, message.channel); + } + console.log("HOW IS PENDING STATE LOOKING RIGHT NOW? HMM?", pendingState); + return pendingState; + }) + .catch(function(err) { + console.log("ERROR", err); + }) + + }); + }); + + rtm.on(RTM_EVENTS.REACTION_ADDED, function handleRtmReactionAdded(reaction) { + console.log('Reaction added:', reaction); + }); + + rtm.on(RTM_EVENTS.REACTION_REMOVED, function handleRtmReactionRemoved(reaction) { + console.log('Reaction removed:', reaction); + }); function getGoogleAuth() { diff --git a/bot.js b/bot.js index 44a6881..1cd9954 100644 --- a/bot.js +++ b/bot.js @@ -1,143 +1,142 @@ -var app = require('./app'); - -// CONNECTING TO MONGO_DB -var mongoose = require('mongoose'); -mongoose.connect(process.env.MONGODB_URI); -var { User } = require('./models'); -var { RtmClient, WebClient, CLIENT_EVENTS, RTM_EVENTS } = require('@slack/client'); -var axios = require('axios'); - -function imReply(data) { - return ({"attachments": [ - { - "text": `Creating a reminder for '${data.result.parameters.subject}' on ${data.result.parameters.date}`, - "fallback": "You are unable to create reminder", - "callback_id": "reminder", - "color": "#3AA3E3", - "attachment_type": "default", - "actions": [ - { - "name": "confrim", - "text": "Yes", - "type": "button", - "value": "yes" - }, - { - "name": "confirm", - "text": "No", - "type": "button", - "value": "no" - }, - ] - } - ]}) -} - -var token = process.env.SLACK_SECRET || ''; -var web = new WebClient(token); -var rtm = new RtmClient(token); -rtm.start(); - -rtm.on(CLIENT_EVENTS.RTM.AUTHENTICATED, (rtmStartData) => { - console.log(`logged in as ${rtmStartData.self.name} of team ${rtmStartData.team.name}, but not yet connected to a channel`); -}) - -var pendingState = { - subject: "", - date: "" -}; - -rtm.on(RTM_EVENTS.MESSAGE, function handleRtmMessage(message) { - var dm = rtm.dataStore.getDMByUserId(message.user); - console.log("DM--------", dm, "MESSAGE-------", message); - if (!dm || dm.id !== message.channel || message.type !== 'message') { - console.log('Message not send to DM, ignoring'); - return; - } - //CHECK IF THEY ARE IN MONGO AS HAVING REGISTERED GOOGLE - var u = rtm.dataStore.getUserById(message.user); - //CHECK FOR USER OR CREATE ONE - User.findOne({slack_ID: message.user}) - .then(function(user){ - //SET UP INITIAL SLACK INFO IN MONGO - if(!user){ - return new User({ - default_meeting_len: 30, - slack_ID: message.user, - slack_DM_ID: message.channel, - slack_Username: u.profile.real_name, - slack_Email: u.profile.email, - }).save(); - } - return user; - }) - .then(function(user){ - console.log("USER IS", user); - if(!user.googleAccount){ - //submit the link to grant Google access - rtm.sendMessage("Hello This is Scheduler bot. In order to schedule reminders for you, I need access to you Google calendar", message.channel); - web.chat.postMessage(message.channel, - 'Use this link to give access to your google cal account http://localhost:3000/connect?auth_id=' - + user._id); - return; - } - - axios.get('https://api.api.ai/api/query', { - params: { - v: 20150910, - lang: 'en', - // timezone: '2017-07-17T16:58:21-0700', - query: message.text, - sessionId: message.user - }, - headers: { - Authorization: `Bearer ${process.env.API_AI_TOKEN}` - } - }) - .then(function( { data } ) { - console.log("DATA", data, "DATA-messages", data.result.fulfillment.messages); - if(!data.result.actionIncomplete && data.result.parameters.date && data.result.parameters.subject ) { - // rtm.sendMessage(data.result.fulfillment.speech, message.channel); - pendingState = data.result.parameters; - web.chat.postMessage(message.channel, 'Chill homie', imReply(data), function(err, res) { - if (err) { - console.log('Error:', err); - } else { - console.log('Message sent: ', res); - } - }); - } else if(data.result.parameters.date && !data.result.parameters.subject){ - console.log('NO SUBJECT'); - pendingState.date = data.result.parameters.date; - rtm.sendMessage(data.result.fulfillment.speech, message.channel); - } else if(data.result.parameters.subject && !data.result.parameters.date){ - console.log('NO DATE'); - pendingState.subject = data.result.parameters.subject; - rtm.sendMessage(data.result.fulfillment.speech, message.channel); - } else { - rtm.sendMessage(data.result.fulfillment.speech, message.channel); - } - console.log("HOW IS PENDING STATE LOOKING RIGHT NOW? HMM?", pendingState); - return pendingState; - }) - .catch(function(err) { - console.log("ERROR", err); - }) - - }); - }); - - rtm.on(RTM_EVENTS.REACTION_ADDED, function handleRtmReactionAdded(reaction) { - console.log('Reaction added:', reaction); - }); - - rtm.on(RTM_EVENTS.REACTION_REMOVED, function handleRtmReactionRemoved(reaction) { - console.log('Reaction removed:', reaction); - }); - -console.log("I'M NOT GIVING UP, PEDNING STATE IS HERE", pendingState); - -module.exports = { - rtm: rtm, - pendingState: pendingState -}; +// var app = require('./app'); +// +// // CONNECTING TO MONGO_DB +// var mongoose = require('mongoose'); +// mongoose.connect(process.env.MONGODB_URI); +// var { User } = require('./models'); +// var { RtmClient, WebClient, CLIENT_EVENTS, RTM_EVENTS } = require('@slack/client'); +// var axios = require('axios'); +// +// function imReply(data) { +// return ({"attachments": [ +// { +// "text": `Creating a reminder for '${data.result.parameters.subject}' on ${data.result.parameters.date}`, +// "fallback": "You are unable to create reminder", +// "callback_id": "reminder", +// "color": "#3AA3E3", +// "attachment_type": "default", +// "actions": [ +// { +// "name": "confrim", +// "text": "Yes", +// "type": "button", +// "value": "yes" +// }, +// { +// "name": "confirm", +// "text": "No", +// "type": "button", +// "value": "no" +// }, +// ] +// } +// ]}) +// } +// +// var token = process.env.SLACK_SECRET || ''; +// var web = new WebClient(token); +// var rtm = new RtmClient(token); +// rtm.start(); +// +// rtm.on(CLIENT_EVENTS.RTM.AUTHENTICATED, (rtmStartData) => { +// console.log(`logged in as ${rtmStartData.self.name} of team ${rtmStartData.team.name}, but not yet connected to a channel`); +// }) +// +// var pendingState = { +// subject: "", +// date: "" +// }; +// +// rtm.on(RTM_EVENTS.MESSAGE, function handleRtmMessage(message) { +// var dm = rtm.dataStore.getDMByUserId(message.user); +// console.log("DM--------", dm, "MESSAGE-------", message); +// if (!dm || dm.id !== message.channel || message.type !== 'message') { +// console.log('Message not send to DM, ignoring'); +// return; +// } +// //CHECK IF THEY ARE IN MONGO AS HAVING REGISTERED GOOGLE +// var u = rtm.dataStore.getUserById(message.user); +// //CHECK FOR USER OR CREATE ONE +// User.findOne({slack_ID: message.user}) +// .then(function(user){ +// //SET UP INITIAL SLACK INFO IN MONGO +// if(!user){ +// return new User({ +// default_meeting_len: 30, +// slack_ID: message.user, +// slack_DM_ID: message.channel, +// slack_Username: u.profile.real_name, +// slack_Email: u.profile.email, +// }).save(); +// } +// return user; +// }) +// .then(function(user){ +// console.log("USER IS", user); +// if(!user.googleAccount){ +// //submit the link to grant Google access +// rtm.sendMessage("Hello This is Scheduler bot. In order to schedule reminders for you, I need access to you Google calendar", message.channel); +// web.chat.postMessage(message.channel, +// 'Use this link to give access to your google cal account http://localhost:3000/connect?auth_id=' +// + user._id); +// return; +// } +// +// axios.get('https://api.api.ai/api/query', { +// params: { +// v: 20150910, +// lang: 'en', +// // timezone: '2017-07-17T16:58:21-0700', +// query: message.text, +// sessionId: message.user +// }, +// headers: { +// Authorization: `Bearer ${process.env.API_AI_TOKEN}` +// } +// }) +// .then(function( { data } ) { +// console.log("DATA", data, "DATA-messages", data.result.fulfillment.messages); +// if(!data.result.actionIncomplete && data.result.parameters.date && data.result.parameters.subject ) { +// // rtm.sendMessage(data.result.fulfillment.speech, message.channel); +// pendingState = data.result.parameters; +// web.chat.postMessage(message.channel, 'Chill homie', imReply(data), function(err, res) { +// if (err) { +// console.log('Error:', err); +// } else { +// console.log('Message sent: ', res); +// } +// }); +// } else if(data.result.parameters.date && !data.result.parameters.subject){ +// console.log('NO SUBJECT'); +// pendingState.date = data.result.parameters.date; +// rtm.sendMessage(data.result.fulfillment.speech, message.channel); +// } else if(data.result.parameters.subject && !data.result.parameters.date){ +// console.log('NO DATE'); +// pendingState.subject = data.result.parameters.subject; +// rtm.sendMessage(data.result.fulfillment.speech, message.channel); +// } else { +// rtm.sendMessage(data.result.fulfillment.speech, message.channel); +// } +// console.log("HOW IS PENDING STATE LOOKING RIGHT NOW? HMM?", pendingState); +// return pendingState; +// }) +// .catch(function(err) { +// console.log("ERROR", err); +// }) +// +// }); +// }); +// +// rtm.on(RTM_EVENTS.REACTION_ADDED, function handleRtmReactionAdded(reaction) { +// console.log('Reaction added:', reaction); +// }); +// +// rtm.on(RTM_EVENTS.REACTION_REMOVED, function handleRtmReactionRemoved(reaction) { +// console.log('Reaction removed:', reaction); +// }); +// +// +// module.exports = { +// rtm: rtm, +// pendingState: pendingState // this doesn't work!!! +// }; diff --git a/master.js b/master.js deleted file mode 100644 index 17adb26..0000000 --- a/master.js +++ /dev/null @@ -1,308 +0,0 @@ -var express = require('express'); -var bodyParser = require('body-parser'); -var google = require('googleapis'); -var RtmClient = require('@slack/client').RtmClient; -var RTM_EVENTS = require('@slack/client').RTM_EVENTS; -var WebClient = require('@slack/client').WebClient; - -var mongoose = require('mongoose'); -var models = require('./models'); -var axios = require('axios'); - - -var token = process.env.SLACK_SECRET || ''; -var web = new WebClient(token); -var rtm = new RtmClient(token); -var app = express(); -var plus = google.plus('v1') -rtm.start(); - -var OAuth2 = google.auth.OAuth2; -mongoose.connect(process.env.MONGODB_URI); - -// REQUIRED SOURCE CHECKS -var REQUIRED_ENV = "SLACK_SECRET MONGODB_URI GOOGLE_CLIENT_ID GOOGLE_CLIENT_SECRET DOMAIN".split(" "); - -REQUIRED_ENV.forEach(function(el) { - if (!process.env[el]){ - console.error("Missing required env var " + el); - process.exit(1); - } -}); - -var obj = { - "attachments": [ - { - "text": "Is this ok?", - "fallback": "You are unable to choose a game", - "callback_id": "wopr_game", - "color": "#3AA3E3", - "attachment_type": "default", - "actions": [ - { - "name": "confrim", - "text": "Yes", - "type": "button", - "value": "yes" - }, - { - "name": "confirm", - "text": "Cancel", - "type": "button", - "value": "cancel" - }, - ] - } - ] -} - -var state = { - subject: "", - date: "" -}; - - -var handlerFunction = function(data, message){ - console.log('this is supposed to be the data', data); - if(data.result.parameters.date && data.result.parameters.subject){ - state.date = data.result.parameters.date; state.subject = data.result.parameters.subject; - obj.attachments[0].text = `Subject:${state.subject} ---- Time:${data.result.parameters.date}`; - web.chat.postMessage(message.channel, "Confirm this request", obj, function(err, res) { - if (err) { - console.log('Error:', err); - } else { - console.log('Message sent: ', res); - } - }); - } else if(data.result.parameters.subject){ - state.subject = data.result.parameters.subject; - rtm.sendMessage(data.result.fulfillment.speech, message.channel); - } -} - -var responseFunction = function(data, message){ - if(!state.date) { - state.date = data.result.parameters.date; - } - if(!state.subject) { - state.subject = data.result.parameters.subject - } - obj.attachments[0].text = `Subject:${state.subject} ---- Time:${data.result.parameters.date}`; - web.chat.postMessage(message.channel, "Confirm this request", obj, function(err, res){ - if (err) { - console.log('Error:', err); - } else { - console.log('Message sent: ', res); - } - }) -} - -rtm.on(RTM_EVENTS.MESSAGE, function handleRtmMessage(message) { - var dm = rtm.dataStore.getDMByUserId(message.user); - if (!dm || dm.id !== message.channel || message.type !== 'message') { - return; - } - ////////////////////////////////////////////////ANDREWS FLOW HERE////////////////////////////// - var u = rtm.dataStore.getUserById(message.user); - //CHECK FOR USER OR CREATE ONE - models.User.findOne({slack_ID: message.user}) - .then(function(user){ - //SET UP INITIAL SLACK INFO IN MONGO - if(!user){ - var user = new models.User({ - default_meeting_len: 30, - slack_ID: message.user, - slack_Username: u.profile.real_name, - slack_Email: u.profile.email, - slack_DM_ID: message.channel - }) - return user.save(); - } else{ - return user; - } - }) - //at this point there is a user model - .then(function(user){ - //AUTHORIZE GOOGLE ACCOUNT LINK - if(!user.googleAccount.access_token){ - web.chat.postMessage(message.channel, - 'Use this link to give access to your google cal account http://localhost:3000/connect?auth_id=' - + user._id); - return; - } else { - console.log('the first time it gets here'); - var temp = encodeURIComponent(message.text); - axios.get(`https://api.api.ai/api/query?v=20150910&query=${temp}&lang=en&sessionId=${message.user}`, { - "headers": { - "Authorization":"Bearer 678861ee7c0d455287f791fd46d1b344" - }, - }) - .then(function({ data }){ - - if(state.subject && !state.date){ - console.log('I AM MADE, YEAH I MADE It'); - responseFunction(data, message); - } else if(state.date && !state.subject){ - responseFunction(data, message) - } else if(state.date && state.subject){ - rtm.sendMessage("Reply to previous task status", message.channel); - } else { - handlerFunction(data, message); - } - - }) - .catch(function(error){ - console.log(error); - }) - - } - - }) - - }) - - rtm.on(RTM_EVENTS.REACTION_ADDED, function handleRtmReactionAdded(reaction) { - console.log('Reaction added:', reaction); - }); - - rtm.on(RTM_EVENTS.REACTION_REMOVED, function handleRtmReactionRemoved(reaction) { - console.log('Reaction removed:', reaction); - }); - - - app.use(bodyParser.urlencoded({ extended: false })); - app.use(bodyParser.json()); - - var oauth2Client = new OAuth2( - process.env.GOOGLE_CLIENT_ID, - process.env.GOOGLE_CLIENT_SECRET, - process.env.DOMAIN + '/connect/callback' - ); - - app.get('/connect', function(req, res){ - var url = oauth2Client.generateAuthUrl({ - access_type: 'offline', - prompt: 'consent', - scope: [ - 'https://www.googleapis.com/auth/userinfo.profile', - 'https://www.googleapis.com/auth/calendar' - ], - state: encodeURIComponent(JSON.stringify({ - auth_id: req.query.auth_id - })) - }); - res.redirect(url); - }) - - - app.get('/connect/callback', function(req, res){ - oauth2Client.getToken(req.query.code, function (err, tokens) { - // Now tokens contains an access_token and an optional refresh_token. Save them. - oauth2Client.setCredentials(tokens); - - plus.people.get({auth: oauth2Client, userId: 'me'}, function(err, googleUser) { - - //UPDATE GOOGLE CREDENTIALS FOR USER - var state = JSON.parse(decodeURIComponent(req.query.state)) - - models.User.findByIdAndUpdate(state.auth_id, { - googleAccount: { - access_token: tokens.access_token, - refresh_token: tokens.refresh_token, - profile_ID: googleUser.id, - expiry_date: tokens.expiry_date, - profile_name: googleUser.displayName - } - }) - .then(function(user){ - user.save(); - }) - .catch(function(err){ - console.log('ERROR ' + err); - }) - }) - - }); - - res.send(``); - - }) - - app.get('/', function(req,res){ - res.send("reached home"); - }) - - app.post('/bot-test', function(req,res){ - - // CONNECT TO API.AI NOW THAT YOU HAVE SET UP GOOGLE SHIT - var curTime = Date.now(); - - console.log(state); - //FIND MONGODB ENTRY TO GET TOKENS AND EXPIRY DATE (maybe this goes in a route too) - models.User.findOne({slack_ID: JSON.parse(req.body.payload).user.id}) - .then(function(user){ - if(curTime > user.googleAccount.expiry_date){ - console.log('fuck did i make it here'); - return; - }else{ - console.log('token still good homie'); - return user; - } - }) - //this part needs to be moved into the post request - .then(function(user) { - //POST MESSAGE TO GOOGLE CALENDAR - if(user){ - //create calendar event here - var new_event = { - "end": { - "date": state.date - }, - "start": { - "date": state.date - }, - "description": "Chief Keef is a fucking legend", - "summary": state.subject - } - - axios.post(`https://www.googleapis.com/calendar/v3/calendars/primary/events?access_token=${user.googleAccount.access_token}`, new_event) - .then(function(response){ - console.log('SUCCESSFULLY POSTED TO CALENDAR'); - console.log('THIS IS THE INFORMATION THE USER HAS', user); - console.log('this is the state', state); - var reminder = new models.Reminder({ - subject: state.subject, - day: state.date, - googCalID: user.googleAccount.profile_ID, - reqID: user.slack_ID - }) - - console.log('this is the REMINDER', reminder); - reminder.save(function(err) { - if(err) { - console.log('there is an error', err); - } else { - console.log('YOUNG BUT IM MAKING MILLION TO WORK THE NIGHT SHIFT'); - } - }); - - state = { - date: '', - subject: '' - } - - }) - .catch(function(err){ - console.log(err); - }) - } - - }) - - res.send(':pray: :100: :fire:') - - }) - - app.listen(3000); From 99e5a67578e8f3c5179222a195101510efab8b70 Mon Sep 17 00:00:00 2001 From: danhuiZ Date: Wed, 19 Jul 2017 00:22:08 -0700 Subject: [PATCH 09/10] change stuff for cronjob --- app.js | 6 ++++-- cronjob.js | 22 ++++++++++++++-------- models.js | 20 ++++++++++++++++++-- 3 files changed, 36 insertions(+), 12 deletions(-) diff --git a/app.js b/app.js index a5a382d..1ac73a3 100644 --- a/app.js +++ b/app.js @@ -281,7 +281,7 @@ app.post('/slack/interactive', function(req, res){ subject: pendingState.subject, day: pendingState.date, googCalID: user.googleAccount.profile_ID, - reqID: user._id + reqID: user.slack_ID }) console.log('this is the REMINDER', reminder); reminder.save(function(err) { @@ -311,4 +311,6 @@ app.listen(port); console.log('Express started. Listening on port %s', port); -module.exports = app; +module.exports = { + app, rtm +}; diff --git a/cronjob.js b/cronjob.js index 22241f2..927a3c6 100644 --- a/cronjob.js +++ b/cronjob.js @@ -10,19 +10,25 @@ Reminder.find({}, function(err, reminders) { console.log('There was an error with finding the reminders'); } else { // reminders is an array of reminder JSONs - const curDate = new Date().toLocaleDateString(); - //sets up the next day - const tomDay = parseInt(curDate.split('/')[1]) + 1; - let tomDate = curDate.split('/') - tomDate[1] = parseInt(tomDate[1]) + 1; - tomDate = tomDate.join('/') + // const curDate = new Date().toLocaleDateString(); + const curDate = new Date().toISOString().split('T')[0]; + // sets up the next day + const tomDate = new Date(new Date().getTime() + 24 * 60 * 60 * 1000).toISOString().split('T')[0]; + // const tomDay = parseInt(curDate.split('/')[1]) + 1; + // let tomDate = curDate.split('/') + // tomDate[1] = parseInt(tomDate[1]) + 1; + // tomDate = tomDate.join('/') console.log("TODAY DATE", curDate, "TOMORROW DATE", tomDate); + User.find({}, function(err, users) { + console.log("YO! I FOUND USERS!", users); + }); + reminders.forEach(function(reminder) { if( curDate === reminder.day ) { //On due day of reminder, send Slack msg & delete the reminder doc console.log("Reminder now", reminder); console.log('need to send RTM message here'); - User.findById(reminder.reqID, function(err, user) { + User.findOne({slack_ID: reminder.reqID}, function(err, user) { console.log("TODAY, USER iS", user); rtm.sendMessage(`Reminder! You gotta remember to ${reminder.subject} today bro!`, user.slack_DM_ID) if(!err) { @@ -34,7 +40,7 @@ Reminder.find({}, function(err, reminders) { } }) } else if ( tomDate === reminder.day ) { //On day before due day of reminder, send Slack msg to app user - User.findById(reminder.reqID, function(err, user) { + User.findOne({slack_ID: reminder.reqID}, function(err, user) { rtm.sendMessage(`Reminder! You gotta remember to ${reminder.subject} tomorrow bro!`, user.slack_DM_ID) }) } diff --git a/models.js b/models.js index 869b5ae..414a3ba 100644 --- a/models.js +++ b/models.js @@ -22,8 +22,24 @@ var userSchema = mongoose.Schema({ slack_Email: String }); -User = mongoose.model('User', userSchema); +var reminderSchema = mongoose.Schema({ + // slack_DM_ID: String, + subject: { + required: true, + type: String + }, + day: { + required: true, + type: String + }, + googCalID: String, + reqID: String +}) + +var User = mongoose.model('User', userSchema); +var Reminder = mongoose.model('Reminder', reminderSchema); module.exports = { - User: User + User: User, + Reminder: Reminder }; From 0cfa4898652648f478b97bac1a4572ffe3581f18 Mon Sep 17 00:00:00 2001 From: danhuiZ Date: Wed, 19 Jul 2017 10:44:44 -0700 Subject: [PATCH 10/10] refresh --- app.js | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/app.js b/app.js index 1ac73a3..f94ef50 100644 --- a/app.js +++ b/app.js @@ -1,7 +1,7 @@ var express = require('express'); var google = require('googleapis'); var OAuth2 = google.auth.OAuth2; -var { User } = require('./models'); +var { User, Reminder } = require('./models'); var axios = require('axios'); // REQUIRED SOURCE CHECKS @@ -161,7 +161,6 @@ function getGoogleAuth() { process.env.DOMAIN + '/connect/callback' //redirect url ); } -var googleAuth = getGoogleAuth(); app.get('/connect', function(req, res){ var userId = req.query.auth_id; @@ -193,6 +192,7 @@ app.get('/connect', function(req, res){ }) app.get('/connect/callback', function(req, res){ + var googleAuth = getGoogleAuth(); googleAuth.getToken(req.query.code, function (err, tokens) { console.log("HERE ARE THE TOKENS", tokens); // Now tokens contains an access_token and an optional refresh_token. Save them. if (err) { @@ -242,22 +242,36 @@ app.post('/slack/interactive', function(req, res){ User.findOne({slack_DM_ID: payload.channel.id}) .then(function(user){ console.log("HERE HERE HERE HERE USER IS HERE", user); + //console.log("time now ", curTime); if(curTime > user.googleAccount.expiry_date){ - console.log('fuck did i make it here'); - console.log("BEFORE REFRESHING", user.googleAccount.access_token); + console.log("access_token has expired"); + var googleAuth = getGoogleAuth(); + googleAuth.setCredentials(user.googleAccount); googleAuth.refreshAccessToken(function(err, tokens) { - console.log("REFRESHED token", tokens); - user.googleAccount.access_token = tokens.access_token; - }); - console.log("AFTER REFRESHING", user.googleAccount.access_token); - return; - }else{ + console.log("enters this function first...", tokens); + user.googleAccount = tokens; + user.save(function(err) { + if(err){ + console.log("blah blah err", err); + } else { + console.log("no error"); + } + return user; + }) + }) + .then(function(user){ + console.log("this is second console before final console", user); + return user; + }) + //return user; + } else { console.log('token still good homie'); return user; } }) .then(function(user){ //POST MESSAGE TO GOOGLE CALENDAR + console.log("final console", user); if(user){ console.log("CHECK PENDING STATE", pendingState); //create calendar event here