UNPKG

ringcentral-personal-chatbot

Version:
294 lines (251 loc) 7.77 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.subscribeInterval = exports.User = void 0; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _pick2 = _interopRequireDefault(require("lodash/pick")); var _sequelize = _interopRequireDefault(require("sequelize")); var _sequelize2 = _interopRequireDefault(require("./sequelize")); var _timeoutAsPromise = _interopRequireDefault(require("timeout-as-promise")); var _uid = _interopRequireDefault(require("../common/uid")); var _constants = require("../common/constants"); var _buildTurnOffWarn = _interopRequireDefault(require("../common/build-turn-off-warn")); var _sendMsg = require("../common/send-msg"); function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } const subscribeInterval = () => '/restapi/v1.0/subscription/~?threshold=120&interval=35'; exports.subscribeInterval = subscribeInterval; const User = _sequelize2.default.define('user', { id: { type: _sequelize.default.STRING, primaryKey: true, defaultValue: _uid.default }, name: { type: _sequelize.default.STRING }, firstName: { type: _sequelize.default.STRING }, lastName: { type: _sequelize.default.STRING }, email: { type: _sequelize.default.STRING }, timezone: { type: _sequelize.default.JSON }, turnOffDesc: { type: _sequelize.default.STRING }, token: { type: _sequelize.default.JSON }, enabled: { type: _sequelize.default.BOOLEAN, defaultValue: true }, signed: { type: _sequelize.default.BOOLEAN, defaultValue: true }, privateChatOnly: { type: _sequelize.default.BOOLEAN, defaultValue: false }, lastUseTime: { type: _sequelize.default.INTEGER }, tokenUpdateTime: { type: _sequelize.default.INTEGER }, data: { // all other data associcated with this user type: _sequelize.default.JSON } }); exports.User = User; User.init = async ({ code, state }) => { const rc = await (0, _constants.createRc)(); await rc.authorize({ redirect_uri: rc.redirectUrl, code }).then(d => d.data); const rcToken = rc.token; const info = await rc.get('/restapi/v1.0/account/~/extension/~').then(r => r.data); const { timezone } = (info === null || info === void 0 ? void 0 : info.regionalSettings) || {}; const rcId = rcToken.owner_id; let user = await User.findByPk(rcId); const now = Date.now(); const up = _objectSpread({ enabled: true, token: rcToken, timezone, lastUseTime: now, tokenUpdateTime: now, name: info.name }, (0, _pick2.default)(info.contact, ['firstName', 'lastName', 'email'])); const q = { where: { id: rcId } }; if (!user) { user = await User.create(_objectSpread({ id: rcId }, up)); } else { Object.assign(user, up); await User.update(up, q); } await user.ensureWebHook(); return rcId; }; User.prototype.rc = async function () { const rc = await (0, _constants.createRc)(); if (this.token) { rc.token = this.token; } return rc; }; User.prototype.removeWebHook = async function () { return this.ensureWebHook(true); }; User.prototype.ensureWebHook = async function (removeOnly = false) { await this.tryRefresh(); const rc = await this.rc(); const r = await rc.get('/restapi/v1.0/subscription').then(d => d.data).catch(e => { console.log(e, 'list WebHook error'); }); if (r && r.records) { for (const sub of r.records) { if (sub.deliveryMode.address === process.env.RINGCENTRAL_CHATBOT_SERVER + '/rc/webhook') { await rc.delete(`/restapi/v1.0/subscription/${sub.id}`).catch(e => { console.log(e, 'del WebHook error, id:', sub.id); }); } } } if (!removeOnly) { return this.trySetupWebHook(); } }; User.prototype.trySetupWebHook = async function () { let count = 0; let done = false; while (count < 5 && !done) { if (count > 0) { console.log('retry setup webhook'); } done = await this.setupWebHook(); count = count + 1; await (0, _timeoutAsPromise.default)(1); } if (!done) { await this.turnOff(); } }; User.prototype.setupWebHook = async function () { await this.tryRefresh(); const rc = await this.rc(); return rc.post('/restapi/v1.0/subscription', { eventFilters: ['/restapi/v1.0/glip/posts', '/restapi/v1.0/glip/groups', subscribeInterval()], expiresIn: 1799, deliveryMode: { transportType: 'WebHook', address: process.env.RINGCENTRAL_CHATBOT_SERVER + '/rc/webhook' } }).then(() => true).catch(async e => { console.log('setupWebHook error', e); }); }; User.prototype.getSubscriptions = async function () { await this.tryRefresh(); const rc = await this.rc(); return rc.get('/restapi/v1.0/subscription').then(d => d.data.records).catch(e => { console.log('getSubscriptions error', e); return []; }); }; User.prototype.tryRefresh = async function () { const now = Date.now(); const { lastRefreshTime } = this; // console.log('now', now) // console.log('lastRefreshTime', lastRefreshTime) // console.log('diff', now - lastRefreshTime) // console.log('tokenExpireTime', tokenExpireTime) if (now - lastRefreshTime < _constants.tokenExpireTime) { return false; } return this.refresh(); }; User.prototype.refresh = async function () { try { const rc = await this.rc(); await rc.refresh(); const { token } = rc; const now = Date.now(); const up = { token, lastRefreshTime: now }; await User.update(up, { where: { id: this.id } }); Object.assign(this, up); return true; } catch (e) { console.log('User refresh token error', e); await this.turnOff(); console.log(`User ${this.id} refresh token has expired`); return false; } }; User.prototype.turnOff = async function (groupId) { if (!this.enabled) { return 1; } const up = { enabled: false, turnOffDesc: 'fail' }; await User.update(up, { where: { id: this.id } }); Object.assign(this, up); const msg = await (0, _buildTurnOffWarn.default)(this); await (0, _sendMsg.sendPrivateMsg)(this, msg); }; User.prototype.getGroup = async function (groupId) { await this.tryRefresh(); const rc = await this.rc(); return rc.get(`/restapi/v1.0/glip/groups/${groupId}`).then(d => d.data).catch(e => { console.log('get group error', e); return null; }); }; User.prototype.sendMessage = async function (groupId, messageObj) { await this.tryRefresh(); const rc = await this.rc(); const r = await rc.post(`/restapi/v1.0/glip/groups/${groupId}/posts`, messageObj).then(d => d.data).catch(err => { console.log('send msg error', err); }); return { sendResult: r }; };