implement new sendTo method

This commit is contained in:
Evert Prants 2021-10-01 20:31:10 +03:00
parent 215215c536
commit 265bdef5a5
Signed by: evert
GPG Key ID: 1688DA83D222D0B5
3 changed files with 90 additions and 17 deletions

View File

@ -2,7 +2,7 @@
"main": "plugin.js", "main": "plugin.js",
"name": "discord", "name": "discord",
"description": "Discord Service for Squeebot 3", "description": "Discord Service for Squeebot 3",
"version": "1.2.1", "version": "1.2.2",
"tags": ["service", "discord"], "tags": ["service", "discord"],
"dependencies": ["control?"], "dependencies": ["control?"],
"npmDependencies": ["discord.js@^13.1.0"] "npmDependencies": ["discord.js@^13.1.0"]

View File

@ -7,7 +7,7 @@ import {
import util from 'util'; import util from 'util';
import Discord, { Intents } from 'discord.js'; import Discord, { ClientUser, Intents, Permissions, TextChannel, User } from 'discord.js';
import { logger } from '@squeebot/core/lib/core'; import { logger } from '@squeebot/core/lib/core';
import { thousandsSeparator, timeSince, toHHMMSS } from '@squeebot/core/lib/common'; import { thousandsSeparator, timeSince, toHHMMSS } from '@squeebot/core/lib/common';
@ -156,6 +156,7 @@ class DiscordProtocol extends Protocol {
Intents.FLAGS.DIRECT_MESSAGE_REACTIONS, Intents.FLAGS.DIRECT_MESSAGE_REACTIONS,
Intents.FLAGS.DIRECT_MESSAGE_TYPING, Intents.FLAGS.DIRECT_MESSAGE_TYPING,
], ],
partials: ['CHANNEL', 'GUILD_MEMBER', 'MESSAGE', 'USER'],
}); });
private eventsAttached = false; private eventsAttached = false;
@ -167,19 +168,21 @@ class DiscordProtocol extends Protocol {
this.me.id = this.client.user.id; this.me.id = this.client.user.id;
this.me.name = this.client.user.username; this.me.name = this.client.user.username;
} }
this.emit('running');
}); });
this.attachEvents(); this.attachEvents();
try { this.client.on('error', (e: Error) => {
this.client.login(this.config.token); this.emit('error', e.message);
} catch (e: any) { });
this.client.on('error', (e: Error) => { this.client.on('disconnect', () => this.stop(true));
this.emit('error', e.message);
this.client.login(this.config.token)
.then(() => this.emit('running'),
(reason) => {
this.emit('error', reason);
this.stop(true);
}); });
this.client.on('disconnect', () => this.stop(true));
}
} }
public stop(force = false): void { public stop(force = false): void {
@ -221,7 +224,7 @@ class DiscordProtocol extends Protocol {
message, message,
this, this,
{ name: message.author.username, id: message.author.id }, { name: message.author.username, id: message.author.id },
{ name: chanName, id: message.channel.id, server: message.guild ? message.guild.id : undefined }); { name: chanName, id: message.channel.id, server: message.guildId || undefined });
this.plugin.stream.emitTo('channel', 'message', msg); this.plugin.stream.emitTo('channel', 'message', msg);
}); });
@ -256,9 +259,81 @@ class DiscordProtocol extends Protocol {
} }
public resolve(msg: DiscordMessageAdapter, ...data: any[]): void { public resolve(msg: DiscordMessageAdapter, ...data: any[]): void {
const toDiscord = this.fromSend(...data);
if (!toDiscord) {
return;
}
// Check send permission
if (msg.data.guildId) {
const perms = msg.data.channel.permissionsFor(this.client.user as ClientUser);
if (perms && !perms.has(Permissions.FLAGS.SEND_MESSAGES, true)) {
return;
}
}
msg.data.channel.send(toDiscord).catch((e: Error) => {
logger.error(e);
});
}
public async sendTo(target: string, ...data: any[]): Promise<boolean> {
const rxSplit = target.split('/');
if (rxSplit[0] !== 'discord' || rxSplit[1] !== this.name) {
// Invalid protocol, we do not want this!;
return false;
}
const toDiscord = this.fromSend(...data);
if (!toDiscord) {
return false;
}
let channel: TextChannel | User | null = null;
// Message to guild
if (rxSplit.length === 4) {
// Fetch the guild and ensure it's available
const guildId = rxSplit[2].substring(2);
const guild = await this.client.guilds.fetch(guildId);
if (!guild || !guild.available || !guild.channels) {
return false;
}
// Fetch the channel and ensure we can send to it
const channelId = rxSplit[3];
channel = await guild.channels.fetch(channelId) as TextChannel;
if (!channel || !(channel.isText || channel.isThread) || !channel.viewable) {
return false;
}
// Check send permission
const perms = channel.permissionsFor(this.client.user as ClientUser);
if (perms) {
if (!perms.has(Permissions.FLAGS.SEND_MESSAGES, true)) {
return false;
}
}
// Message to user
} else if (rxSplit.length === 3) {
const userId = rxSplit[2];
channel = await this.client.users.fetch(userId);
if (!channel) {
return false;
}
} else {
return false;
}
await channel!.send(toDiscord);
return true;
}
private fromSend(...data: any[]): { embeds?: object[]; content?: string } | null {
let response = util.format(data[0], ...data.slice(1)); let response = util.format(data[0], ...data.slice(1));
if (!response) { if (!response) {
return; return null;
} }
if (Array.isArray(data[0])) { if (Array.isArray(data[0])) {
@ -266,7 +341,7 @@ class DiscordProtocol extends Protocol {
response = this.format.compose(data[0]); response = this.format.compose(data[0]);
} catch (e: any) { } catch (e: any) {
logger.error('[%s] Failed to compose message:', this.fullName, e.message); logger.error('[%s] Failed to compose message:', this.fullName, e.message);
return; return null;
} }
} }
// Discord supports sending objects to the channel for things like embeds // Discord supports sending objects to the channel for things like embeds
@ -281,9 +356,7 @@ class DiscordProtocol extends Protocol {
toDiscord.content = response; toDiscord.content = response;
} }
msg.data.channel.send(toDiscord).catch((e: Error) => { return toDiscord;
logger.error(e);
});
} }
} }

View File

@ -3,7 +3,7 @@
"plugins": [ "plugins": [
{ {
"name": "discord", "name": "discord",
"version": "1.2.1" "version": "1.2.2"
} }
], ],
"typescript": true "typescript": true