UNPKG

munar-adapter-uwave

Version:

üWave adapter for Munar

309 lines (248 loc) 7.42 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _got = _interopRequireDefault(require("got")); var _ws = _interopRequireDefault(require("ws")); var _events = _interopRequireDefault(require("events")); var _qs = require("qs"); var _munarCore = require("munar-core"); var _promiseRetry = _interopRequireDefault(require("promise-retry")); var _once = _interopRequireDefault(require("once")); var _Message = _interopRequireDefault(require("./Message")); var _Waitlist = _interopRequireDefault(require("./Waitlist")); var _DJBooth = _interopRequireDefault(require("./DJBooth")); var _DJHistory = _interopRequireDefault(require("./DJHistory")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } const debug = require('debug')('munar:adapter:uwave'); class UwaveAdapter extends _munarCore.Adapter { constructor(bot, options) { super(bot); this.users = []; this.socketEvents = new _events.default(); this.socketHandlers = { chatMessage(data) { const message = new _Message.default(this, data, this.getUser(data.userID)); this.receive('message', message); }, join(user) { const botUser = this.toBotUser(user); this.users.push(botUser); this.receive('user:join', botUser); }, leave(userID) { const user = this.users.find(user => user.id === userID); this.users = this.users.filter(user => user.id !== userID); this.receive('user:leave', user); }, nameChange({ userID, username }) { const user = this.getUser(userID); user.username = username; user.sourceUser.username = username; this.receive('user:update', user, { username }); }, roleChange({ userID, role }) { const user = this.getUser(userID); user.sourceUser.role = role; this.receive('user:update', user, { role }); } }; this.onSocketMessage = message => { // Ignore pings if (message === '-') { return; } let command; let data; try { ({ command, data } = JSON.parse(message)); } catch (e) { console.error(e.stack || e); return; } this.socketEvents.emit(command, data); if (command in this.socketHandlers) { this.socketHandlers[command].call(this, data); } }; this.options = options; this.apiUrl = options.api.replace(/\/+$/, ''); this.waitlist = new _Waitlist.default(this); this.djBooth = new _DJBooth.default(this); this.djHistory = new _DJHistory.default(this); } // Base Adapter async connect() { this.shouldClose = false; if (!this.options.token) { const { body } = await this.request('post', 'auth/login', { email: this.options.email, password: this.options.password }); if (body && body.meta && body.meta.jwt) { this.options.token = body.meta.jwt; } else { throw new Error('Could not log in.'); } } await (0, _promiseRetry.default)(async (retry, n) => { try { const state = await this.getNow(); await this.connectSocket(state.socketToken); } catch (err) { debug('retry connect', err); retry(err); } }); } async disconnect() { this.shouldClose = true; this.socket.close(); await this.request('delete', 'auth'); } reply(message, text) { this.send(`@${message.username} ${text}`); } send(text) { const message = JSON.stringify({ command: 'sendChat', data: text }); this.socket.send(message); } getSelf() { return this.self; } getUsers() { return this.users; } getChannels() { return [this]; } getChannel(str) { if (str !== 'main') { throw new Error(`Channel ${str} does not exist`); } return this; } canExecute(message, command) { const user = message.user.sourceUser; const userRole = user.roles && user.roles.length > 0 ? getRoleFromList(user.roles) : getRoleFromId(user.role); const requiredRole = command.role; debug('canExecute', requiredRole, userRole, user.roles, user.role); return userRole >= requiredRole; function getRoleFromList(list) { if (list.includes('*') || list.includes('admin')) return _munarCore.permissions.ADMIN; if (list.includes('moderator')) return _munarCore.permissions.MODERATOR; if (list.includes('special')) return _munarCore.permissions.REGULAR; return _munarCore.permissions.NONE; } function getRoleFromId(id) { if (id >= 4) return _munarCore.permissions.ADMIN; if (id >= 2) return _munarCore.permissions.MODERATOR; if (id === 1) return _munarCore.permissions.REGULAR; return _munarCore.permissions.NONE; } } // HTTP API request(method, endpoint, data) { let url = `${this.apiUrl}/${endpoint}`; const options = { method, headers: { authorization: `JWT ${this.options.token}` }, json: true }; if (method === 'get') { options.query = data; } else { options.body = data; } // For nested query parameters (like page[offset]) if (options.query) { options.query = (0, _qs.stringify)(options.query, { encode: false }); } debug('request', url, options.query, options.body); return (0, _got.default)(url, options); } async getNow() { const { body } = await this.request('get', 'now'); this.users = body.users.map(this.toBotUser, this); this.self = this.toBotUser(body.user); this.waitlist.waitlist = body.waitlist; return body; } async deleteMessage(id) { return await this.request('delete', `chat/${id}`); } // Local state getWaitlist() { return this.waitlist; } getDJBooth() { return this.djBooth; } getDJHistory() { return this.djHistory; } toBotUser(user) { return new _munarCore.User(this, user._id, user.username, user); } // Sockets async getSocketAuth() { const { body } = await this.request('get', 'auth/socket'); return body.data.socketToken; } async connectSocket(socketToken) { if (!socketToken) socketToken = await this.getSocketAuth(); return await new Promise((resolve, reject) => { let sent = false; debug('connecting socket', socketToken); this.socket = new _ws.default(this.options.socket); this.socket.on('open', () => { sent = true; debug('send', socketToken); this.socket.send(socketToken); resolve(); }); this.socket.on('message', this.onSocketMessage); const reconnect = (0, _once.default)(() => { debug('reconnecting in 1000ms'); setTimeout(() => { this.connect(); }, 1000); }); this.socket.on('error', err => { debug(err); if (!sent) reject(err);else reconnect(); }); this.socket.on('close', () => { debug('closed'); if (!this.shouldClose && sent) reconnect(); }); }); } toString() { return 'üWave'; } } exports.default = UwaveAdapter; UwaveAdapter.adapterName = 'uwave';