index.js 12.1 KB
'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);
        });
    }


};