'use strict'; const google = require('googleapis'); const plus = google.plus('v1'); const googleAuth = require('google-auth-library'); const calendar = google.calendar('v3'); const fs = require('fs'); const path = require('path'); const yamlConfig = require('node-yaml-config'); const config = yamlConfig.load(path.join(__dirname, '/../../config/config.yml')); const moment = require('moment') const Promise = require('bluebird') const Mongoose = Promise.promisifyAll(require('mongoose')); const Token = Mongoose.model('Token'); const console = process.console; /** * ดึงค่ามาจาก config.yml */ const CALENDAR_ID = config.google.calendar_id; const REDIRECT_URL = config.google.redirect_url; const CLIENT_ID = config.google.client_id; const CLIENT_SECRET = config.google.client_secret; /** * เรียกใช้ oauth2Client * @type {GoogleAuth} */ const auth = google.auth.OAuth2; const oauth2Client = new auth(CLIENT_ID, CLIENT_SECRET, REDIRECT_URL); const SCOPES = ['https://www.googleapis.com/auth/calendar', 'https://www.googleapis.com/auth/userinfo.email']; const TOKEN_DIR = (process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE) + '/.credentials/'; const TOKEN_PATH = TOKEN_DIR + 'calendar-nodejs-quickstart.json'; function hasTimezone(timezone) { if (timezone) { return timezone } else { return 'Asia/Bangkok' } } function getNewToken(oauth2Client, callback) { var authUrl = oauth2Client.generateAuthUrl({ access_type: 'offline', scope: SCOPES }); // console.log('Authorize this app by visiting this url: ', authUrl); return authUrl; } function setNewToken(code) { oauth2Client.getToken(code, function (err, token) { if (err) { console.log('Error while trying to retrieve access token', err); return; } oauth2Client.credentials = token; storeToken(token); callback(oauth2Client); }) } function storeToken(token, emails) { var tokendb; token.email = emails[0].value try { // ** new tokendb = new Token(token); // -- old // fs.mkdirSync(TOKEN_DIR); } catch (err) { throw err; } // ** new Promise.try(function () {}) .then(function () { tokendb.save(function (err, result) { if (err) { console.error(err) } else { console.log(result); } }); }); // -- old // fs.writeFile(TOKEN_PATH, JSON.stringify(token)); // console.log('Token stored to ' + TOKEN_PATH); } module.exports = { authorize: (callback) => { var setToken = {} // set token from callback Token.findOne({ email: 'zentoriono@gmail.com' }, function (err, token) { if (err) { return callback(null, null, getNewToken(oauth2Client, callback)); } else if (token) { setToken = { access_token: token.access_token, refresh_token: token.refresh_token, token_type: token.token_type, expiry_date: token.expiry_date }; // console.log(setToken) oauth2Client.credentials = setToken; return callback(null, oauth2Client); } else { return callback(null, null, getNewToken(oauth2Client, callback)); } }); }, setNewToken: (code, callback) => { Token.findOne({ email: 'zentoriono@gmail.com' }, function (err, token) { if (token) { oauth2Client.credentials = JSON.parse(token); return callback(null, oauth2Client); } else { oauth2Client.getToken(code, function (err, token) { if (err) { console.log('Error while trying to retrieve access token', err); return; } else { oauth2Client.credentials = token; var params = { userId: 'me', fields: 'emails', auth: oauth2Client }; plus.people.get(params, function (err, response) { if (err) { console.error(err) } else { storeToken(token, response.emails); } }); return callback(null, oauth2Client); } }) } }); }, listCalendar: (auth, callback) => { calendar.calendarList.list({ auth: auth, minAccessRole: 'owner' }, (err, response) => { if (err) return callback(err); return callback(null, response); }); }, listEvents: (auth, callback) => { calendar.events.list({ auth: auth, calendarId: CALENDAR_ID || 'primary', //CALENDAR_ID || 'primary' maxResults: 50, singleEvents: true, orderBy: 'startTime' }, (err, response) => { if (err) return callback(err); return callback(null, response); }); }, createEvent: (options, callback) => { calendar.events.insert({ auth: options.auth, calendarId: CALENDAR_ID || 'primary', resource: options }, (err, response) => { if (err) return callback(err); return callback(null, response); }); }, deleteEvent: (options, callback) => { calendar.events.delete({ auth: options.auth, calendarId: CALENDAR_ID || 'primary', eventId: options.eventId }, (err, response) => { if (err) return callback(err); return callback(null, response); }); }, updateEvent: (options, callback) => { calendar.events.update({ auth: options.auth, calendarId: CALENDAR_ID || 'primary', eventId: options.eventId, resource: options }, (err, response) => { if (err) return callback(err); return callback(null, response); }); }, eventBuilder: (payload) => { var buildPayload = {} try { buildPayload.summary = payload.Title buildPayload.description = payload.Description buildPayload.start = { dateTime: new Date(payload.Start), timezone: hasTimezone(payload.StartTimezone) } buildPayload.end = { dateTime: new Date(payload.End), timeZone: hasTimezone(payload.EndTimezone) } if (payload.email) { buildPayload.attendees = [{ email: payload.email }] } if (payload.reminders) { buildPayload.reminders = { useDefault: false, overrides: [{ method: 'email', minutes: 24 * 60 }] } } if (payload.EventTypeID) { buildPayload.extendedProperties = { "private": { "eventTypeID": payload.EventTypeID } } } if (payload.PropertyID) { buildPayload.extendedProperties.private.propertyID = payload.PropertyID; } } catch (error) { console.error(error.message) } finally { return buildPayload } }, deleteBuilder: (payload) => { var buildPayload = {} try { buildPayload.calendarId = CALENDAR_ID buildPayload.eventId = payload.TaskID } catch (error) { console.error(error.message) } finally { return buildPayload } }, /** * สร้าง JSON สำหรับส่งไปอัพเดตข้อมูล event ปฏิทิน * @param payload * @returns {{}} */ updateBuilder: (payload) => { var buildPayload = {}; try { buildPayload.calendarId = CALENDAR_ID; buildPayload.eventId = payload.TaskID; buildPayload.summary = payload.Title; buildPayload.description = payload.Description; buildPayload.start = { dateTime: moment(payload.Start).format("YYYY-MM-DDTHH:mm:ssZ"), timeZone: hasTimezone(payload.StartTimezone) }; buildPayload.end = { dateTime: moment(payload.End).format("YYYY-MM-DDTHH:mm:ssZ"), timeZone: hasTimezone(payload.EndTimezone) }; if (payload.email) { buildPayload.attendees = [{ email: payload.email }] } if (payload.reminders) { buildPayload.reminders = { useDefault: false, overrides: [{ method: 'email', minutes: 24 * 60 }] } } if (payload.EventTypeID) { buildPayload.extendedProperties = { "private": { "eventTypeID": payload.EventTypeID } } } if (payload.PropertyID) { buildPayload.extendedProperties.private.propertyID = payload.PropertyID; } if (payload.extendedProperties) { buildPayload.extendedProperties = payload.extendedProperties } } catch (error) { console.error(error.message) } finally { return buildPayload } }, /** * API สร้างปฏิทิน อิงตาม summary(จะกลายเป็นชื่อของปฏิทิน) ที่มาจาก request * @googleAPI https://developers.google.com/apis-explorer/#p/calendar/v3/calendar.calendars.insert * @param options * @param callback */ createCalendar: (options, callback) => { calendar.calendars.insert({ auth: options.auth, resource: options }, (err, response) => { if (err) return callback(err); return callback(null, response); }); }, /** * API เรียกข้อมูลปฏิทิน อิงตาม id ที่มาจาก request * @googleAPI https://developers.google.com/apis-explorer/#p/calendar/v3/calendar.calendarList.get * @param auth * @param callback */ getCalendar: (auth, callback) => { calendar.calendars.get({ auth: auth, calendarId: CALENDAR_ID || 'primary' }, (err, response) => { if (err) return callback(err); return callback(null, response); }); }, /** * API ลบปฏิทินโดย อิงตาม id ที่มาจาก request * @googleAPI https://developers.google.com/apis-explorer/#p/calendar/v3/calendar.calendars.delete * @param options * @param callback */ deleteCalendar: (options, callback) => { calendar.calendars.delete({ auth: options.auth, calendarId: options.calendarId }, (err, response) => { if (err) return callback(err); return callback(null, response); }); }, refreshToken: (options, callback) => { oauth2Client.setCredentials(options.auth); oauth2Client.refreshAccessToken(function(err, tokens) { // your access_token is now refreshed and stored in oauth2Client // store these new tokens in a safe place (e.g. database) if (err) return callback(err); return callback(null, tokens); }); } };