feat: add editing support to InternalPoster
This commit is contained in:
parent
ecd9a5863c
commit
31f18ba27f
6 changed files with 113 additions and 39 deletions
|
@ -16,6 +16,16 @@ export class Webhooks extends BaseRepository {
|
|||
return entity;
|
||||
}
|
||||
|
||||
async find(id: string): Promise<Webhook | null> {
|
||||
const result = await this.repository.findOne({
|
||||
where: {
|
||||
id,
|
||||
},
|
||||
});
|
||||
|
||||
return result ? this._processEntityFromDB(result) : null;
|
||||
}
|
||||
|
||||
async findByChannelId(channelId: string): Promise<Webhook | null> {
|
||||
const result = await this.repository.findOne({
|
||||
where: {
|
||||
|
|
|
@ -56,8 +56,12 @@ export async function postCaseToCaseLogChannel(
|
|||
const [channelId, messageId] = theCase.log_message_id.split("-");
|
||||
|
||||
try {
|
||||
const poster = pluginData.getPlugin(InternalPosterPlugin);
|
||||
const channel = pluginData.guild.channels.resolve(channelId as Snowflake) as TextChannel;
|
||||
await channel.messages.edit(messageId as Snowflake, caseEmbed);
|
||||
const message = await channel.messages.fetch(messageId);
|
||||
if (message) {
|
||||
await poster.editMessage(message, caseEmbed);
|
||||
}
|
||||
return;
|
||||
} catch {} // tslint:disable-line:no-empty
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import { mapToPublicFn } from "../../pluginUtils";
|
|||
import { Webhooks } from "../../data/Webhooks";
|
||||
import { Queue } from "../../Queue";
|
||||
import { sendMessage } from "./functions/sendMessage";
|
||||
import { editMessage } from "./functions/editMessage";
|
||||
|
||||
const defaultOptions: PluginOptions<InternalPosterPluginType> = {
|
||||
config: {},
|
||||
|
@ -28,6 +29,7 @@ export const InternalPosterPlugin = zeppelinGuildPlugin<InternalPosterPluginType
|
|||
// prettier-ignore
|
||||
public: {
|
||||
sendMessage: mapToPublicFn(sendMessage),
|
||||
editMessage: mapToPublicFn(editMessage),
|
||||
},
|
||||
|
||||
async beforeLoad(pluginData) {
|
||||
|
|
46
backend/src/plugins/InternalPoster/functions/editMessage.ts
Normal file
46
backend/src/plugins/InternalPoster/functions/editMessage.ts
Normal file
|
@ -0,0 +1,46 @@
|
|||
import { Message, MessageOptions, NewsChannel, TextChannel, WebhookClient } from "discord.js";
|
||||
import { GuildPluginData } from "knub";
|
||||
import { InternalPosterPluginType } from "../types";
|
||||
import { isDiscordAPIError, noop } from "../../../utils";
|
||||
|
||||
/**
|
||||
* Sends a message using a webhook or direct API requests, preferring webhooks when possible.
|
||||
*/
|
||||
export async function editMessage(
|
||||
pluginData: GuildPluginData<InternalPosterPluginType>,
|
||||
message: Message,
|
||||
content: MessageOptions,
|
||||
): Promise<void> {
|
||||
if (!(message.channel instanceof TextChannel || message.channel instanceof NewsChannel)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const channel = message.channel as TextChannel | NewsChannel;
|
||||
|
||||
await pluginData.state.queue.add(async () => {
|
||||
if (message.webhookId) {
|
||||
const webhook = await pluginData.state.webhooks.find(message.webhookId);
|
||||
if (!webhook) {
|
||||
// Webhook message but we're missing the token -> can't edit
|
||||
return;
|
||||
}
|
||||
|
||||
const webhookClient = new WebhookClient({
|
||||
id: webhook.id,
|
||||
token: webhook.token,
|
||||
});
|
||||
await webhookClient.editMessage(message.id, content).catch(async (err) => {
|
||||
// Unknown Webhook, remove from DB
|
||||
if (isDiscordAPIError(err) && err.code === 10015) {
|
||||
await pluginData.state.webhooks.delete(webhookClient.id);
|
||||
return;
|
||||
}
|
||||
|
||||
throw err;
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
await message.edit(content).catch(noop);
|
||||
});
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
import { GuildPluginData } from "knub";
|
||||
import { InternalPosterPluginType } from "../types";
|
||||
import { NewsChannel, TextChannel, WebhookClient } from "discord.js";
|
||||
import { getOrCreateWebhookForChannel } from "./getOrCreateWebhookForChannel";
|
||||
|
||||
export async function getOrCreateWebhookClientForChannel(
|
||||
pluginData: GuildPluginData<InternalPosterPluginType>,
|
||||
channel: TextChannel | NewsChannel,
|
||||
): Promise<WebhookClient | null> {
|
||||
if (!pluginData.state.webhookClientCache.has(channel.id)) {
|
||||
const webhookInfo = await getOrCreateWebhookForChannel(pluginData, channel);
|
||||
if (webhookInfo) {
|
||||
const client = new WebhookClient({
|
||||
id: webhookInfo[0],
|
||||
token: webhookInfo[1],
|
||||
});
|
||||
pluginData.state.webhookClientCache.set(channel.id, client);
|
||||
} else {
|
||||
pluginData.state.webhookClientCache.set(channel.id, null);
|
||||
}
|
||||
}
|
||||
|
||||
return pluginData.state.webhookClientCache.get(channel.id) ?? null;
|
||||
}
|
|
@ -4,6 +4,7 @@ import { InternalPosterPluginType } from "../types";
|
|||
import { getOrCreateWebhookForChannel } from "./getOrCreateWebhookForChannel";
|
||||
import { APIMessage } from "discord-api-types";
|
||||
import { isDiscordAPIError } from "../../../utils";
|
||||
import { getOrCreateWebhookClientForChannel } from "./getOrCreateWebhookClientForChannel";
|
||||
|
||||
export type InternalPosterMessageResult = {
|
||||
id: string;
|
||||
|
@ -29,47 +30,34 @@ export async function sendMessage(
|
|||
content: MessageOptions,
|
||||
): Promise<InternalPosterMessageResult | null> {
|
||||
return pluginData.state.queue.add(async () => {
|
||||
if (!pluginData.state.webhookClientCache.has(channel.id)) {
|
||||
const webhookInfo = await getOrCreateWebhookForChannel(pluginData, channel);
|
||||
if (webhookInfo) {
|
||||
const client = new WebhookClient({
|
||||
id: webhookInfo[0],
|
||||
token: webhookInfo[1],
|
||||
});
|
||||
pluginData.state.webhookClientCache.set(channel.id, client);
|
||||
} else {
|
||||
pluginData.state.webhookClientCache.set(channel.id, null);
|
||||
}
|
||||
const webhookClient = await getOrCreateWebhookClientForChannel(pluginData, channel);
|
||||
if (!webhookClient) {
|
||||
return sendDirectly(channel, content);
|
||||
}
|
||||
|
||||
const webhookClient = pluginData.state.webhookClientCache.get(channel.id);
|
||||
if (webhookClient) {
|
||||
return webhookClient
|
||||
.send({
|
||||
...content,
|
||||
...(pluginData.client.user && {
|
||||
username: pluginData.client.user.username,
|
||||
avatarURL: pluginData.client.user.avatarURL() || pluginData.client.user.defaultAvatarURL,
|
||||
}),
|
||||
})
|
||||
.then((apiMessage) => ({
|
||||
id: apiMessage.id,
|
||||
channelId: apiMessage.channel_id,
|
||||
}))
|
||||
.catch(async (err) => {
|
||||
// Unknown Webhook
|
||||
if (isDiscordAPIError(err) && err.code === 10015) {
|
||||
await pluginData.state.webhooks.delete(webhookClient.id);
|
||||
pluginData.state.webhookClientCache.delete(channel.id);
|
||||
return webhookClient
|
||||
.send({
|
||||
...content,
|
||||
...(pluginData.client.user && {
|
||||
username: pluginData.client.user.username,
|
||||
avatarURL: pluginData.client.user.avatarURL() || pluginData.client.user.defaultAvatarURL,
|
||||
}),
|
||||
})
|
||||
.then((apiMessage) => ({
|
||||
id: apiMessage.id,
|
||||
channelId: apiMessage.channel_id,
|
||||
}))
|
||||
.catch(async (err) => {
|
||||
// Unknown Webhook
|
||||
if (isDiscordAPIError(err) && err.code === 10015) {
|
||||
await pluginData.state.webhooks.delete(webhookClient.id);
|
||||
pluginData.state.webhookClientCache.delete(channel.id);
|
||||
|
||||
// Fallback to regular message for this log message
|
||||
return sendDirectly(channel, content);
|
||||
}
|
||||
// Fallback to regular message for this log message
|
||||
return sendDirectly(channel, content);
|
||||
}
|
||||
|
||||
throw err;
|
||||
});
|
||||
}
|
||||
|
||||
return sendDirectly(channel, content);
|
||||
throw err;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue