UNPKG

yamdbf-addon-dm-manager

Version:

YAMDBF addon for viewing and replying to DMs sent to your discord bot

168 lines (167 loc) 7.21 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; const yamdbf_1 = require("yamdbf"); const discord_js_1 = require("discord.js"); const Util_1 = require("./Util"); class DMManager { constructor(bot, guild) { this.client = bot; if (!this.client.guilds.has(guild)) throw new Error(`DMManager: Failed to find guild with ID '${guild}'`); this.storage = new yamdbf_1.LocalStorage('storage/DMManager'); this.guild = guild; if (!this._guild.member(this.client.user).hasPermissions(['MANAGE_CHANNELS', 'MANAGE_MESSAGES'])) throw new Error('DMManager: Bot must have MANAGE_CHANNELS, MANAGE_MESSAGES permissions in the supplied guild'); this.channels = new discord_js_1.Collection((this.storage.getItem('openChannels') || []).map((c) => [c[0], this._guild.channels.get(c[1])]) || []); this.client.on('message', (message) => this.handleMessage(message)); this.client.on('channelDelete', (channel) => { if (this.channels.find((c) => c.id === channel.id)) { this.channels.delete(this.channels.findKey((c) => c.id === channel.id)); this.storeOpenChannels(); } }); } get guild() { return this._guild.id; } /** * If guild does not match the guild in storage, assume * the manager has been assigned to a new guild and remove * open channels from storage as they no longer need to be * tracked */ set guild(value) { this._guild = this.client.guilds.get(value); if (this.storage.exists('guild') && this.storage.getItem('guild') !== value) this.clearOpenChannels(); } /** * Update open managed channels in storage */ storeOpenChannels() { this.storage.setItem('openChannels', Array.from(this.channels.entries()) .map((c) => [c[0], c[1].id])); } /** * Remove any open channels from storage */ clearOpenChannels() { this.storage.setItem('openChannels', []); this.channels = new discord_js_1.Collection(); } /** * Create a new managed channel for the user in the dm manager * guild and add it to the channels cache and stored openChannels */ createNewChannel(user) { return __awaiter(this, void 0, void 0, function* () { let newChannel; try { newChannel = (yield this._guild .createChannel(`${Util_1.normalize(user.username) || 'unicode'}-${user.discriminator}`, 'text')); this.channels.set(user.id, newChannel); this.storeOpenChannels(); } catch (err) { this.sendError(`DMManager: Failed to create channel: '${Util_1.normalize(user.username)}-${user.discriminator}'\n${err}`); } if (newChannel) yield newChannel.sendEmbed(this.buildUserInfo(user)); return newChannel; }); } /** * Create an embed for user info used at the start * of a new managed channel */ buildUserInfo(user) { return new discord_js_1.RichEmbed() .setColor(8450847) .setAuthor(`${user.username}#${user.discriminator} (${user.id})`, user.avatarURL) .setFooter('DM channel started') .setTimestamp(); } /** * Handle incoming messages. If it's a DM, find the channel * belonging to the user. If it doesn't exist, create one */ handleMessage(message) { return __awaiter(this, void 0, void 0, function* () { if (message.embeds[0] && message.channel.type !== 'dm') return; if (message.channel.type !== 'dm' && message.guild.id !== this.guild) return; if (message.guild && message.channel.id === message.guild.id) return; if (message.author.id !== this.client.user.id && !this.channels.has(message.author.id) && !message.guild) yield this.createNewChannel(message.author); if (message.channel.type === 'dm') { const channelID = message.author.id === this.client.user.id ? message.channel.recipient.id : message.author.id; const channel = this.channels.get(channelID); if (!channel) return; if (message.embeds[0]) message.content += '\n\n**[RichEmbed]**'; yield this.send(channel, message.author, message.content) .catch(err => this.sendError(`Failed to send message in #${this.channels.get(channelID).name}\n${err}`)); } else { message.delete(); const user = yield this.fetchUser(message.channel); try { yield user.send(message.content); } catch (err) { message.channel.sendEmbed(new discord_js_1.RichEmbed() .setColor('#FF0000') .setTitle('There was an error while sending the message') .setDescription(err)); } } }); } /** * Fetch the user object the managed channel represents contact with */ fetchUser(channel) { return __awaiter(this, void 0, void 0, function* () { const id = this.channels.findKey('id', channel.id); return yield this.client.fetchUser(id); }); } /** * Send a text message to a managed channel as an embed, spoofing * the provided user to simulate messages from that user */ send(channel, user, message) { return __awaiter(this, void 0, void 0, function* () { return yield channel.sendEmbed(new discord_js_1.RichEmbed() .setColor(8450847) .setAuthor(`${user.username}#${user.discriminator}`, user.avatarURL) .setDescription(message) .setTimestamp()); }); } /** * Send an error to the default channel of the DMManager guild */ sendError(message) { return __awaiter(this, void 0, void 0, function* () { return yield this._guild.defaultChannel.sendEmbed(new discord_js_1.RichEmbed() .setColor('#FF0000') .setTitle('DMManager error') .setDescription(message) .setTimestamp()); }); } } Object.defineProperty(exports, "__esModule", { value: true }); exports.default = DMManager;