103 lines
3.3 KiB
JavaScript
103 lines
3.3 KiB
JavaScript
import { EventEmitter } from "events";
|
|
import { wait } from "./common.js";
|
|
|
|
class WatchedGuild extends EventEmitter {
|
|
constructor() {
|
|
super();
|
|
|
|
this.knownWebhooks = new Map();
|
|
this.upstreamGuildId = null;
|
|
}
|
|
|
|
pushEvent(e) {
|
|
this.emit("pushed", e);
|
|
}
|
|
|
|
holdForEvent(timeout) {
|
|
return new Promise((outerResolve, outerReject) => {
|
|
let handler;
|
|
Promise.race([
|
|
new Promise((resolve, reject) => {
|
|
// potential memory leak here when too many promises are created and waiting
|
|
handler = (event) => {
|
|
resolve(event);
|
|
};
|
|
this.once("pushed", handler);
|
|
}),
|
|
wait(timeout, true)
|
|
]).then((result) => {
|
|
if (handler)
|
|
this.removeListener("pushed", handler);
|
|
outerResolve(result);
|
|
}).catch(() => {
|
|
if (handler)
|
|
this.removeListener("pushed", handler);
|
|
outerResolve(null);
|
|
});
|
|
});
|
|
}
|
|
|
|
discordConnect(bot) {
|
|
this.bot = bot;
|
|
this.guildObject = this.bot.guilds.find(e => e.id === this.upstreamGuildId);
|
|
|
|
if (!this.guildObject) {
|
|
throw new Error("Could not find guild object from bot cache by id (is the upstreamGuildId valid and does the bot have access to it?)");
|
|
}
|
|
|
|
this.bot.on("GUILD_CREATE", (guild) => {
|
|
if (guild.id === this.upstreamGuildId)
|
|
this.guildObject = guild;
|
|
});
|
|
|
|
this.bot.on("GUILD_UPDATE", (guild) => {
|
|
if (guild.id === this.upstreamGuildId)
|
|
this.guildObject = guild;
|
|
});
|
|
|
|
this.bot.on("MESSAGE_CREATE", (message) => {
|
|
if (message.guild_id !== this.upstreamGuildId)
|
|
return;
|
|
|
|
const maybeKnownWebhook = this.knownWebhooks.get(message.channel_id);
|
|
if (maybeKnownWebhook && maybeKnownWebhook.id === message.webhook_id)
|
|
return; // ignore messages coming from our webhook
|
|
|
|
this.pushEvent({
|
|
eventType: "MESSAGE_CREATE",
|
|
message: message
|
|
});
|
|
});
|
|
}
|
|
|
|
userFacingChannelList() {
|
|
return this.guildObject.channels.map(channel => ({ id: channel.id, name: channel.name, position: channel.position, type: channel.type, nsfw: channel.nsfw }));
|
|
}
|
|
|
|
async discordSendMessage(content, channelId, username, avatarURL=undefined) {
|
|
let webhook = this.knownWebhooks.get(channelId);
|
|
if (!webhook) {
|
|
webhook = (await this.bot.api(["GET", `/channels/${channelId}/webhooks`]))
|
|
.find(e => e.name === "well_known__bridge");
|
|
|
|
if (!webhook)
|
|
webhook = await this.bot.api(["POST", `/channels/${channelId}/webhooks`], {
|
|
name: "well_known__bridge"
|
|
});
|
|
|
|
this.knownWebhooks.set(channelId, webhook);
|
|
}
|
|
|
|
await this.bot.api(["POST", `/webhooks/${webhook.id}/${webhook.token}?wait=true`], {
|
|
content,
|
|
username,
|
|
avatar_url: avatarURL,
|
|
tts: false,
|
|
allowed_mentions: {
|
|
parse: ["users"]
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
export default WatchedGuild;
|