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
JavaScript
"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;