UNPKG

@yamdbf/dm-manager

Version:

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

191 lines (189 loc) 7.83 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.DMManager = void 0; /* eslint-disable require-atomic-updates */ const core_1 = require("@yamdbf/core"); const discord_js_1 = require("discord.js"); const DMManagerUsageError_1 = require("./DMManagerUsageError"); const dmManagerFactory_1 = require("./dmManagerFactory"); const Util_1 = require("./Util"); class DMManager extends core_1.Plugin { constructor(client, guild = '', defaultChannel = '') { super(); this.name = 'DMManager'; this._client = client; if (!guild || !defaultChannel) throw new DMManagerUsageError_1.DMManagerUsageError('Import "dmManager" and pass to plugins with a guild ID and default channel ID'); if (!this._client.guilds.cache.has(guild)) throw new Error(`DMManager: Failed to find guild with ID '${guild}'`); if (!this._client.guilds.cache.get(guild).channels.cache.has(defaultChannel)) throw new Error(`DMManager: Failed to find a default channel in guild '${guild}' with ID '${defaultChannel}`); this._guildID = guild; this._defaultChannelID = defaultChannel; } async init(storage) { var _a; this._storage = storage; this._guild = this._client.guilds.cache.get(this._guildID); if (await this._storage.exists('guild') && await this._storage.get('guild') !== this._guildID) await this._clearOpenChannels(); await this._storage.set('guild', this._guildID); if (!this._guild.member(this._client.user).permissions.has(['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(((_a = await this._storage.get('openChannels')) !== null && _a !== void 0 ? _a : []) .map((c) => [c[0], this._guild.channels.cache.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(); } }); this._client.on('blacklistAdd', (user, global) => { if (global) this.blacklist(user); }); this._client.on('blacklistRemove', (user, global) => { if (global) this.whitelist(user); }); } /** * Add a user to the DMManager blacklist */ async blacklist(user) { await this._storage.set(`blacklist.${user.id}`, true); } /** * Remove a user from the DMManager blacklist */ async whitelist(user) { await this._storage.remove(`blacklist.${user.id}`); } /** * Return whether or not a user is blacklisted from the DMManager */ async _isBlacklisted(user) { return this._storage.exists(`blacklist.${user.id}`); } /** * Update open managed channels in storage */ async _storeOpenChannels() { await this._storage.set('openChannels', Array.from(this._channels.entries()) .map((c) => [c[0], c[1].id])); } /** * Remove any open channels from storage */ async _clearOpenChannels() { await this._storage.set('openChannels', []); this._channels.clear(); } /** * Create a new managed channel for the user in the dm manager * guild and add it to the channels cache and stored openChannels */ async _createNewChannel(user) { let newChannel; const channelName = `${Util_1.normalize(user.username) || 'unicode'}-${user.discriminator}`; try { newChannel = await this._guild.channels.create(channelName, { type: 'text' }); this._channels.set(user.id, newChannel); this._storeOpenChannels(); } catch (err) { this._sendError(`DMManager: Failed to create channel: '${channelName}'\n${err}`); } if (newChannel) await newChannel.send({ embed: 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.MessageEmbed() .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 */ async _handleMessage(message) { if (await this._isBlacklisted(message.author)) return; if (message.embeds[0] && message.channel.type !== 'dm') return; if (message.channel.type !== 'dm' && message.guild.id !== this._guildID) 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) await 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**[MessageEmbed]**'; await this._send(channel, message.author, message.content) .catch(async (err) => this._sendError(`Failed to send message in #${this._channels.get(channelID).name}\n${err}`)); } else { message.delete(); const user = await this._fetchUser(message.channel); try { await user.send(message.content); } catch (err) { message.channel.send(new discord_js_1.MessageEmbed() .setColor('#FF0000') .setTitle('There was an error while sending the message') .setDescription(err)); } } } /** * Fetch the user object the managed channel represents contact with */ async _fetchUser(channel) { const id = this._channels.findKey(c => c.id === channel.id); return this._client.users.fetch(id); } /** * Send a text message to a managed channel as an embed, spoofing * the provided user to simulate messages from that user */ async _send(channel, user, message) { return channel.send({ embed: new discord_js_1.MessageEmbed() .setColor(8450847) .setAuthor(`${user.username}#${user.discriminator}`, user.avatarURL()) .setDescription(message) .setTimestamp() }); } /** * Send an error to the default channel of the DMManager guild */ async _sendError(message) { return this._guild.channels.cache.get(this._defaultChannelID) .send({ embed: new discord_js_1.MessageEmbed() .setColor('#FF0000') .setTitle('DMManager error') .setDescription(message) .setTimestamp() }); } } exports.DMManager = DMManager; DMManager.default = dmManagerFactory_1.dmManagerFactory; DMManager.dmManager = dmManagerFactory_1.dmManagerFactory; DMManager.DMManager = DMManager; //# sourceMappingURL=DMManager.js.map