Update ticket and appeal handlers
This commit is contained in:
+45
-16
@@ -1,9 +1,10 @@
|
||||
import { ActionRowBuilder, ButtonBuilder, ButtonStyle, Client, EmbedBuilder } from 'discord.js';
|
||||
import { ActionRowBuilder, APIEmbedField, ButtonBuilder, ButtonStyle, Client, DiscordAPIError, EmbedBuilder, Message } from 'discord.js';
|
||||
import { config } from '../config';
|
||||
import { Database } from '../shared/Database';
|
||||
import { Appeal, AppealUpdate } from '../types';
|
||||
import { Appeal, AppealUpdate, E621Post, PostFlag } from '../types';
|
||||
import { getAuthor, getColor, getDescription, getFields } from './event-utils';
|
||||
import { humanizeCapitalization } from './string-utils';
|
||||
import { getE621Post, getE621PostFlag } from './e621-utils';
|
||||
|
||||
export async function appealUpdateHandler(client: Client, update: string) {
|
||||
const data: AppealUpdate = JSON.parse(update);
|
||||
@@ -26,13 +27,16 @@ async function postAppeal(client: Client, data: AppealUpdate) {
|
||||
|
||||
const appeal = data.appeal;
|
||||
|
||||
const embed = await createEmbedFromAppeal(appeal);
|
||||
const flag = await getE621PostFlag(appeal.target_id);
|
||||
const post = await getE621Post(flag!.post_id);
|
||||
|
||||
const row = await getButtons(appeal);
|
||||
const embed = await createEmbedFromAppeal(appeal, flag!, post!);
|
||||
|
||||
const row = await getButtons(appeal, flag!, post!);
|
||||
|
||||
const message = await channel.send({ embeds: [embed], components: row.components.length > 0 ? [row] : [] });
|
||||
|
||||
await Database.putAppeal(appeal.id, message.id);
|
||||
await Database.putAppealOrUpdate(appeal.id, message.id);
|
||||
}
|
||||
|
||||
async function updateAppeal(client: Client, data: AppealUpdate) {
|
||||
@@ -48,16 +52,24 @@ async function updateAppeal(client: Client, data: AppealUpdate) {
|
||||
|
||||
if (!messageId) return postAppeal(client, data);
|
||||
|
||||
const message = await channel.messages.fetch(messageId);
|
||||
const embed = await createEmbedFromAppeal(data.appeal);
|
||||
let message: Message | undefined;
|
||||
|
||||
if (!message || message.author.id != config.DISCORD_CLIENT_ID) {
|
||||
const newMessage = await channel.send({ embeds: [embed] });
|
||||
await Database.removeAppeal(data.appeal.id);
|
||||
await Database.putAppeal(data.appeal.id, newMessage.id);
|
||||
} else {
|
||||
await message.edit({ embeds: [embed] });
|
||||
try {
|
||||
message = await channel.messages.fetch(messageId);
|
||||
} catch (e) {
|
||||
// Ignore unknown message errors
|
||||
if (!(e instanceof DiscordAPIError && e.code == 10008)) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
if (!message || message.author.id != config.DISCORD_CLIENT_ID) return postAppeal(client, data);
|
||||
|
||||
const flag = await getE621PostFlag(data.appeal.target_id);
|
||||
const post = await getE621Post(flag!.post_id);
|
||||
|
||||
const embed = await createEmbedFromAppeal(data.appeal, flag!, post!);
|
||||
await message.edit({ embeds: [embed] });
|
||||
}
|
||||
|
||||
function getTitle(appeal: Appeal): string {
|
||||
@@ -75,18 +87,28 @@ function getURL(appeal: Appeal): string {
|
||||
return `${config.E621_BASE_URL}/appeals/${appeal.id}`;
|
||||
}
|
||||
|
||||
async function createEmbedFromAppeal(appeal: Appeal): Promise<EmbedBuilder> {
|
||||
function getCustomFields(appeal: Appeal, flag: PostFlag, post: E621Post): APIEmbedField[] {
|
||||
return [
|
||||
{
|
||||
name: 'Deletion Reason',
|
||||
value: flag.reason,
|
||||
inline: true
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
async function createEmbedFromAppeal(appeal: Appeal, flag: PostFlag, post: E621Post): Promise<EmbedBuilder> {
|
||||
return new EmbedBuilder()
|
||||
.setTitle(getTitle(appeal))
|
||||
.setURL(await getURL(appeal))
|
||||
.setDescription(await getDescription(appeal))
|
||||
.setAuthor(getAuthor(appeal))
|
||||
.setColor(getColor(appeal))
|
||||
.setFields(...getFields(appeal))
|
||||
.setFields(...getFields(appeal), ...getCustomFields(appeal, flag, post))
|
||||
.setFooter({ text: `Appeal #${appeal.id}` });
|
||||
}
|
||||
|
||||
async function getButtons(appeal: Appeal): Promise<ActionRowBuilder<ButtonBuilder>> {
|
||||
async function getButtons(appeal: Appeal, flag: PostFlag, post: E621Post): Promise<ActionRowBuilder<ButtonBuilder>> {
|
||||
const row = new ActionRowBuilder<ButtonBuilder>();
|
||||
|
||||
const primaryButton = new ButtonBuilder()
|
||||
@@ -100,5 +122,12 @@ async function getButtons(appeal: Appeal): Promise<ActionRowBuilder<ButtonBuilde
|
||||
row.addComponents(primaryButton);
|
||||
}
|
||||
|
||||
const button = new ButtonBuilder()
|
||||
.setLabel('Open Post')
|
||||
.setStyle(ButtonStyle.Link)
|
||||
.setURL(`${config.E621_BASE_URL}/posts/${post.id}`);
|
||||
|
||||
row.addComponents(button);
|
||||
|
||||
return row;
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
import { formatMarkdown, parseDTextToAST } from '@clynamic/dmark';
|
||||
|
||||
export function dtextToMarkdown(dtext: string): string {
|
||||
return formatMarkdown(parseDTextToAST(dtext)).output;
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import { config } from '../config';
|
||||
import { E621Post, E621User, Record } from '../types';
|
||||
import { E621Post, E621User, PostFlag, Record } from '../types';
|
||||
|
||||
const BLACKLISTED_TAGS: string[] = [];
|
||||
const BLACKLISTED_NONSAFE_TAGS: string[] = ['young'];
|
||||
@@ -35,11 +35,15 @@ export async function getE621User(idOrName: string | number): Promise<E621User |
|
||||
}
|
||||
|
||||
export async function getE621Post(id: string | number): Promise<E621Post | null> {
|
||||
return (await request(`/posts/${id}`))?.post as E621Post ?? null;
|
||||
return (await request(`/posts/${id}`, { v2: 'true' })) as E621Post ?? null;
|
||||
}
|
||||
|
||||
export async function getE621PostByMd5(md5: string): Promise<E621Post | null> {
|
||||
return (await request('/posts', { md5 }))?.post as E621Post ?? null;
|
||||
return (await request('/posts', { md5, v2: 'true' })) as E621Post ?? null;
|
||||
}
|
||||
|
||||
export async function getE621PostFlag(id: number): Promise<PostFlag | null> {
|
||||
return await request(`/post_flags/${id}`) as PostFlag ?? null;
|
||||
}
|
||||
|
||||
export const enum PostAction {
|
||||
|
||||
@@ -2,7 +2,7 @@ import { APIEmbedField, EmbedAuthorOptions } from 'discord.js';
|
||||
import { config } from '../config';
|
||||
import { getE621Post, PostAction, spoilerOrBlacklist } from './e621-utils';
|
||||
import { appealIDRegex, blipIDRegex, commentIDRegex, flagIDRegex, forumTopicIDRegex, poolIDRegex, postIDRegex, recordIDRegex, searchLinkRegex, setIDRegex, takedownIDRegex, ticketIDRegex, userIDRegex, wikiLinkRegex } from './message-matcher-regex';
|
||||
import { dtextToMarkdown } from './dtext-utils';
|
||||
import { parseDTextToMarkdown } from '@clynamic/dmark';
|
||||
|
||||
// TODO: Condense this and the message event handler regex array.
|
||||
const linkReplacers = [
|
||||
@@ -135,7 +135,7 @@ export async function getLinks(input: string, limit: number = Number.MAX_SAFE_IN
|
||||
}
|
||||
|
||||
export async function getDescription(data: { reason: string }): Promise<string> {
|
||||
return dtextToMarkdown(data.reason.length <= MAX_DESCRIPTION_LENGTH ? await getLinks(data.reason) : await getLinks(data.reason, MAX_DESCRIPTION_LENGTH));
|
||||
return parseDTextToMarkdown(data.reason.length <= MAX_DESCRIPTION_LENGTH ? await getLinks(data.reason) : await getLinks(data.reason, MAX_DESCRIPTION_LENGTH)).output;
|
||||
}
|
||||
|
||||
export function getAuthor(data: { user_id: number, user: string }): EmbedAuthorOptions {
|
||||
|
||||
@@ -8,7 +8,6 @@ export * from './channel-utils';
|
||||
export * from './commands';
|
||||
export * from './debug-utils';
|
||||
export * from './discord-user-utils';
|
||||
export * from './dtext-utils';
|
||||
export * from './e621-utils';
|
||||
export * from './embed-utils';
|
||||
export * from './event-log-utils';
|
||||
|
||||
+16
-10
@@ -1,4 +1,4 @@
|
||||
import { ActionRowBuilder, ButtonBuilder, ButtonStyle, Client, EmbedBuilder, SendableChannels } from 'discord.js';
|
||||
import { ActionRowBuilder, ButtonBuilder, ButtonStyle, Client, DiscordAPIError, EmbedBuilder, Message, SendableChannels } from 'discord.js';
|
||||
import { config } from '../config';
|
||||
import { Database } from '../shared/Database';
|
||||
import { Ticket, TicketPhrase, TicketUpdate } from '../types';
|
||||
@@ -34,7 +34,7 @@ async function postTicket(client: Client, data: TicketUpdate) {
|
||||
|
||||
const message = await channel.send({ embeds: [embed], components: [row] });
|
||||
|
||||
await Database.putTicket(ticket.id, message.id);
|
||||
await Database.putTicketOrUpdate(ticket.id, message.id);
|
||||
|
||||
sendTicketAlerts(ticket, channel);
|
||||
}
|
||||
@@ -52,16 +52,22 @@ async function updateTicket(client: Client, data: TicketUpdate) {
|
||||
|
||||
if (!messageId) return postTicket(client, data);
|
||||
|
||||
const message = await channel.messages.fetch(messageId);
|
||||
let message: Message | undefined;
|
||||
|
||||
try {
|
||||
message = await channel.messages.fetch(messageId);
|
||||
} catch (e) {
|
||||
// Ignore unknown message errors
|
||||
if (!(e instanceof DiscordAPIError && e.code == 10008)) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
if (!message || message.author.id != config.DISCORD_CLIENT_ID) return postTicket(client, data);
|
||||
|
||||
const embed = await createEmbedFromTicket(data.ticket);
|
||||
|
||||
if (!message || message.author.id != config.DISCORD_CLIENT_ID) {
|
||||
const newMessage = await channel.send({ embeds: [embed] });
|
||||
await Database.removeTicket(data.ticket.id);
|
||||
await Database.putTicket(data.ticket.id, newMessage.id);
|
||||
} else {
|
||||
await message.edit({ embeds: [embed] });
|
||||
}
|
||||
await message.edit({ embeds: [embed] });
|
||||
}
|
||||
|
||||
function getTitle(ticket: Ticket): string {
|
||||
|
||||
Reference in New Issue
Block a user