Implement Delete Event Button
Additionally moved pathIdxSeparator and Ender to eventUtils
This commit is contained in:
parent
5bf0de06ee
commit
9051792ff3
|
@ -19,6 +19,8 @@ const actions = [
|
|||
'btn-joinReqApprove',
|
||||
'btn-joinReqDeny',
|
||||
'btn-joinReqAlt',
|
||||
'btn-delEvent',
|
||||
'btn-confirmDelEvent',
|
||||
];
|
||||
for (const action of actions) {
|
||||
await dbClient.execute('INSERT INTO command_cnt(command) values(?)', [action]).catch((e) => {
|
||||
|
|
|
@ -9,6 +9,8 @@ import { leaveEventButton } from './live-event/leaveEvent.ts';
|
|||
import { alternateEventButton } from './live-event/alternateEvent.ts';
|
||||
import { joinRequestButton } from './live-event/joinRequest.ts';
|
||||
import { alternateRequestButton } from './live-event/alternateRequest.ts';
|
||||
import { deleteEventButton } from './live-event/deleteEvent.ts';
|
||||
import { deleteConfirmedButton } from './live-event/deleteConfirmed.ts';
|
||||
|
||||
export const buttons: Array<Button> = [
|
||||
gameSelectionButton,
|
||||
|
@ -21,4 +23,6 @@ export const buttons: Array<Button> = [
|
|||
alternateEventButton,
|
||||
joinRequestButton,
|
||||
alternateRequestButton,
|
||||
deleteEventButton,
|
||||
deleteConfirmedButton,
|
||||
];
|
||||
|
|
|
@ -2,8 +2,8 @@ import { ActionRow, ApplicationCommandFlags, ApplicationCommandTypes, Bot, Butto
|
|||
import { infoColor1, somethingWentWrong } from '../../commandUtils.ts';
|
||||
import { CommandDetails } from '../../types/commandTypes.ts';
|
||||
import { Activities } from './activities.ts';
|
||||
import { addTokenToMap, deleteTokenEarly, generateActionRow, generateMapId, getNestedActivity, pathIdxEnder, pathIdxSeparator, selfDestructMessage, tokenMap } from './utils.ts';
|
||||
import { idSeparator, LfgEmbedIndexes, lfgStartTimeName } from '../eventUtils.ts';
|
||||
import { addTokenToMap, deleteTokenEarly, generateActionRow, generateMapId, getNestedActivity, selfDestructMessage, tokenMap } from './utils.ts';
|
||||
import { idSeparator, LfgEmbedIndexes, lfgStartTimeName, pathIdxEnder, pathIdxSeparator } from '../eventUtils.ts';
|
||||
import utils from '../../utils.ts';
|
||||
import { customId as createCustomActivityBtnId } from './step1a-openCustomModal.ts';
|
||||
import { customId as finalizeEventBtnId } from './step2-finalize.ts';
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Bot, Interaction, InteractionResponseTypes, MessageComponentTypes, TextStyles } from '../../../deps.ts';
|
||||
import { deleteTokenEarly, pathIdxSeparator } from './utils.ts';
|
||||
import { idSeparator } from '../eventUtils.ts';
|
||||
import { deleteTokenEarly } from './utils.ts';
|
||||
import { idSeparator, pathIdxSeparator } from '../eventUtils.ts';
|
||||
import { customId as verifyCustomActivityId } from './step1b-verifyCustomActivity.ts';
|
||||
import utils from '../../utils.ts';
|
||||
import { dbClient, queries } from '../../db.ts';
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import config from '../../../config.ts';
|
||||
import { ApplicationCommandFlags, Bot, ButtonStyles, Interaction, InteractionResponseTypes, MessageComponentTypes } from '../../../deps.ts';
|
||||
import { failColor, infoColor1, safelyDismissMsg, somethingWentWrong } from '../../commandUtils.ts';
|
||||
import { addTokenToMap, pathIdxEnder, pathIdxSeparator, selfDestructMessage } from './utils.ts';
|
||||
import { idSeparator } from '../eventUtils.ts';
|
||||
import { addTokenToMap, selfDestructMessage } from './utils.ts';
|
||||
import { idSeparator, pathIdxEnder, pathIdxSeparator } from '../eventUtils.ts';
|
||||
import { activityMaxPlayersId, activitySubtitleId, activityTitleId } from './step1a-openCustomModal.ts';
|
||||
import { customId as gameSelectionId } from './step1-gameSelection.ts';
|
||||
import { customId as openCustomModalId } from './step1a-openCustomModal.ts';
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { Bot, Interaction } from '../../../deps.ts';
|
||||
import { somethingWentWrong } from '../../commandUtils.ts';
|
||||
import { eventDateId, eventDescriptionId, eventTimeId, eventTimeZoneId } from './step1-gameSelection.ts';
|
||||
import { addTokenToMap, createLFGPost, getFinalActivity, pathIdxSeparator } from './utils.ts';
|
||||
import { idSeparator } from '../eventUtils.ts';
|
||||
import { addTokenToMap, createLFGPost, getFinalActivity } from './utils.ts';
|
||||
import { idSeparator, pathIdxSeparator } from '../eventUtils.ts';
|
||||
import { Activities, Activity } from './activities.ts';
|
||||
import { getDateFromRawInput } from './dateTimeUtils.ts';
|
||||
import utils from '../../utils.ts';
|
||||
|
|
|
@ -22,6 +22,8 @@ import {
|
|||
joinEventBtnStr,
|
||||
leaveEventBtnStr,
|
||||
lfgStartTimeName,
|
||||
pathIdxEnder,
|
||||
pathIdxSeparator,
|
||||
requestToJoinEventBtnStr,
|
||||
} from '../eventUtils.ts';
|
||||
import { successColor } from '../../commandUtils.ts';
|
||||
|
@ -31,12 +33,11 @@ import { customId as createEventCustomId } from './step3-createEvent.ts';
|
|||
import { customId as joinEventCustomId } from '../live-event/joinEvent.ts';
|
||||
import { customId as leaveEventCustomId } from '../live-event/leaveEvent.ts';
|
||||
import { customId as alternateEventCustomId } from '../live-event/alternateEvent.ts';
|
||||
import { customId as deleteEventCustomId } from '../live-event/deleteEvent.ts';
|
||||
|
||||
// Discord Interaction Tokens last 15 minutes, we will self kill after 14.5 minutes
|
||||
const tokenTimeoutS = (15 * 60) - 30;
|
||||
export const tokenTimeoutMS = tokenTimeoutS * 1000;
|
||||
export const pathIdxSeparator = '|';
|
||||
export const pathIdxEnder = '&';
|
||||
export const selfDestructMessage = (currentTime: number) =>
|
||||
`**Please note:** This message will self destruct <t:${Math.floor((currentTime + tokenTimeoutMS) / 1000)}:R> due to limits imposed by the Discord API.`;
|
||||
|
||||
|
@ -147,7 +148,7 @@ export const generateLFGButtons = (whitelist: boolean): [ButtonComponent, Button
|
|||
type: MessageComponentTypes.Button,
|
||||
label: '',
|
||||
style: ButtonStyles.Secondary,
|
||||
customId: 'deleteEvent', // TODO: replace with proper id
|
||||
customId: deleteEventCustomId,
|
||||
emoji: {
|
||||
name: '🗑️',
|
||||
},
|
||||
|
|
|
@ -12,6 +12,8 @@ export enum LfgEmbedIndexes {
|
|||
|
||||
// Common strings
|
||||
export const idSeparator = '@';
|
||||
export const pathIdxSeparator = '|';
|
||||
export const pathIdxEnder = '&';
|
||||
export const lfgStartTimeName = 'Start Time:';
|
||||
export const noMembersStr = 'None';
|
||||
export const joinEventBtnStr = 'Join';
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
import { ApplicationCommandFlags, Bot, Interaction, InteractionResponseTypes } from '../../../deps.ts';
|
||||
import { dbClient, generateGuildSettingKey, lfgChannelSettings, queries } from '../../db.ts';
|
||||
import { failColor, infoColor1, infoColor2, safelyDismissMsg, somethingWentWrong, successColor } from '../../commandUtils.ts';
|
||||
import { idSeparator, pathIdxEnder, pathIdxSeparator } from '../eventUtils.ts';
|
||||
import utils from '../../utils.ts';
|
||||
import config from '../../../config.ts';
|
||||
|
||||
export const customId = 'deleteConfirmed';
|
||||
export const confirmedCustomId = 'confirmedCustomId';
|
||||
export const confirmStr = 'yes';
|
||||
|
||||
const execute = async (bot: Bot, interaction: Interaction) => {
|
||||
if (interaction?.data?.customId && interaction?.data?.components?.length && interaction.channelId && interaction.guildId && interaction.member) {
|
||||
// Light Telemetry
|
||||
dbClient.execute(queries.callIncCnt('btn-confirmDelEvent')).catch((e) => utils.commonLoggers.dbError('deleteConfirmed.ts@incCnt', 'call sproc INC_CNT on', e));
|
||||
|
||||
// Parse out our data
|
||||
const tempDataMap: Map<string, string> = new Map();
|
||||
for (const row of interaction.data.components) {
|
||||
if (row.components?.[0]) {
|
||||
const textField = row.components[0];
|
||||
tempDataMap.set(textField.customId || 'missingCustomId', textField.value || 'missingValue');
|
||||
}
|
||||
}
|
||||
const actionByManager = interaction.data.customId.endsWith(pathIdxEnder);
|
||||
const [evtChannelId, evtMessageId] = (interaction.data.customId.replaceAll(pathIdxEnder, '').split(idSeparator)[1] || '').split(pathIdxSeparator).map((id) => BigInt(id || '0'));
|
||||
const lfgChannelSetting = lfgChannelSettings.get(generateGuildSettingKey(interaction.guildId, interaction.channelId)) || {
|
||||
managed: false,
|
||||
managerRoleId: 0n,
|
||||
logChannelId: 0n,
|
||||
};
|
||||
|
||||
if (tempDataMap.get(confirmedCustomId)?.toLowerCase() === confirmStr) {
|
||||
const eventMessage = await bot.helpers.getMessage(evtChannelId, evtMessageId).catch((e: Error) => utils.commonLoggers.messageGetError('deleteConfirmed.ts', 'get eventMessage', e));
|
||||
const userId = interaction.member.id;
|
||||
// Delete event
|
||||
bot.helpers.deleteMessage(evtChannelId, evtMessageId, 'User deleted event').then(() => {
|
||||
dbClient.execute(queries.deleteEvent, [evtChannelId, evtMessageId]).catch((e) => utils.commonLoggers.dbError('deleteConfirmed.ts@deleteEvent', 'delete event from', e));
|
||||
|
||||
// Acknowledge user so discord doesn't get annoyed
|
||||
bot.helpers.sendInteractionResponse(interaction.id, interaction.token, {
|
||||
type: InteractionResponseTypes.ChannelMessageWithSource,
|
||||
data: {
|
||||
flags: ApplicationCommandFlags.Ephemeral,
|
||||
embeds: [{
|
||||
color: successColor,
|
||||
title: 'Event successfully deleted.',
|
||||
description: safelyDismissMsg,
|
||||
}],
|
||||
},
|
||||
}).catch((e: Error) => utils.commonLoggers.interactionSendError('deleteConfirmed.ts', interaction, e));
|
||||
|
||||
if (actionByManager) {
|
||||
const eventEmbed = eventMessage?.embeds[0] || { title: 'Event not found', color: failColor };
|
||||
bot.helpers.sendMessage(lfgChannelSetting.logChannelId, {
|
||||
embeds: [{
|
||||
color: infoColor2,
|
||||
title: `Event deleted by a ${config.name} Manager`,
|
||||
description: `The following event was deleted by <@${userId}>.`,
|
||||
timestamp: new Date().getTime(),
|
||||
}, eventEmbed],
|
||||
}).catch((e: Error) => utils.commonLoggers.messageSendError('deleteConfirmed.ts', 'send log message', e));
|
||||
}
|
||||
}).catch((e) => {
|
||||
utils.commonLoggers.messageDeleteError('deleteConfirmed.ts', 'deleteEventFailedDB', e);
|
||||
somethingWentWrong(bot, interaction, 'deleteEventMessageInDeleteConfirmedButton');
|
||||
});
|
||||
} else {
|
||||
// User either did not type yes confirm field was missing, lets see which it was
|
||||
if (tempDataMap.get(confirmedCustomId)) {
|
||||
// User did not type yes.
|
||||
bot.helpers.sendInteractionResponse(interaction.id, interaction.token, {
|
||||
type: InteractionResponseTypes.ChannelMessageWithSource,
|
||||
data: {
|
||||
flags: ApplicationCommandFlags.Ephemeral,
|
||||
embeds: [{
|
||||
color: infoColor1,
|
||||
title: 'Event not deleted.',
|
||||
description: `If you are trying to delete the event, please make sure you type \`${confirmStr}\` into the field provided.
|
||||
|
||||
${safelyDismissMsg}`,
|
||||
}],
|
||||
},
|
||||
}).catch((e: Error) => utils.commonLoggers.interactionSendError('deleteConfirmed.ts', interaction, e));
|
||||
} else {
|
||||
// Field was missing
|
||||
somethingWentWrong(bot, interaction, 'noIdsFromDeleteConfirmedButton');
|
||||
}
|
||||
}
|
||||
} else {
|
||||
somethingWentWrong(bot, interaction, 'noDataFromDeleteConfirmedButton');
|
||||
}
|
||||
};
|
||||
|
||||
export const deleteConfirmedButton = {
|
||||
customId,
|
||||
execute,
|
||||
};
|
|
@ -0,0 +1,56 @@
|
|||
import { Bot, Interaction, InteractionResponseTypes, MessageComponentTypes, TextStyles } from '../../../deps.ts';
|
||||
import { dbClient, generateGuildSettingKey, lfgChannelSettings, queries } from '../../db.ts';
|
||||
import { somethingWentWrong, stopThat } from '../../commandUtils.ts';
|
||||
import { idSeparator, pathIdxEnder, pathIdxSeparator } from '../eventUtils.ts';
|
||||
import { confirmedCustomId, confirmStr, customId as deleteConfirmedCustomId } from './deleteConfirmed.ts';
|
||||
import utils from '../../utils.ts';
|
||||
|
||||
export const customId = 'deleteEvent';
|
||||
|
||||
const execute = async (bot: Bot, interaction: Interaction) => {
|
||||
if (interaction.data?.customId && interaction.member && interaction.member.user && interaction.channelId && interaction.guildId && interaction.message && interaction.message.embeds[0]) {
|
||||
// Light Telemetry
|
||||
dbClient.execute(queries.callIncCnt('btn-delEvent')).catch((e) => utils.commonLoggers.dbError('deleteEvent.ts', 'call sproc INC_CNT on', e));
|
||||
|
||||
const ownerId = BigInt(interaction.message.embeds[0].footer?.iconUrl?.split('#')[1] || '0');
|
||||
const lfgChannelSetting = lfgChannelSettings.get(generateGuildSettingKey(interaction.guildId, interaction.channelId)) || {
|
||||
managed: false,
|
||||
managerRoleId: 0n,
|
||||
logChannelId: 0n,
|
||||
};
|
||||
|
||||
if (interaction.member.user.id === ownerId || (lfgChannelSetting.managed && interaction.member.roles.includes(lfgChannelSetting.managerRoleId))) {
|
||||
const actionByManager = interaction.member.user.id !== ownerId;
|
||||
// Open Delete Confirmation
|
||||
bot.helpers.sendInteractionResponse(interaction.id, interaction.token, {
|
||||
type: InteractionResponseTypes.Modal,
|
||||
data: {
|
||||
title: 'Are you sure you want to delete this event?',
|
||||
customId: `${deleteConfirmedCustomId}${idSeparator}${interaction.channelId}${pathIdxSeparator}${interaction.message.id}${actionByManager ? pathIdxEnder : ''}`,
|
||||
components: [{
|
||||
type: MessageComponentTypes.ActionRow,
|
||||
components: [{
|
||||
type: MessageComponentTypes.InputText,
|
||||
customId: confirmedCustomId,
|
||||
label: `To confirm, type '${confirmStr}' in the field below:`,
|
||||
placeholder: 'To cancel, just click cancel on this modal.',
|
||||
style: TextStyles.Short,
|
||||
minLength: 3,
|
||||
maxLength: 3,
|
||||
}],
|
||||
}],
|
||||
},
|
||||
}).catch((e: Error) => utils.commonLoggers.interactionSendError('step1a-openCustomModal.ts:modal', interaction, e));
|
||||
} else {
|
||||
// Not owner or manager, tell user they can't
|
||||
stopThat(bot, interaction, 'delete');
|
||||
}
|
||||
} else {
|
||||
somethingWentWrong(bot, interaction, 'noDataFromDeleteEventButton');
|
||||
}
|
||||
};
|
||||
|
||||
export const deleteEventButton = {
|
||||
customId,
|
||||
execute,
|
||||
};
|
|
@ -24,6 +24,7 @@ export const isLFGChannel = (guildId: bigint, channelId: bigint) => {
|
|||
return (lfgChannelSettings.has(generateGuildSettingKey(guildId, channelId)) || channelId === 0n || guildId === 0n) ? ApplicationCommandFlags.Ephemeral : undefined;
|
||||
};
|
||||
|
||||
// Tell user to try again or report issue
|
||||
export const somethingWentWrong = async (bot: Bot, interaction: Interaction, errorCode: string) =>
|
||||
bot.helpers.sendInteractionResponse(interaction.id, interaction.token, {
|
||||
type: InteractionResponseTypes.ChannelMessageWithSource,
|
||||
|
@ -39,7 +40,23 @@ export const somethingWentWrong = async (bot: Bot, interaction: Interaction, err
|
|||
}],
|
||||
}],
|
||||
},
|
||||
}).catch((e: Error) => utils.commonLoggers.interactionSendError('commandUtils.ts', interaction, e));
|
||||
}).catch((e: Error) => utils.commonLoggers.interactionSendError('commandUtils.ts@somethingWentWrong', interaction, e));
|
||||
|
||||
// Smack the user for trying to modify an event that isn't theirs
|
||||
export const stopThat = async (bot: Bot, interaction: Interaction, stopWhat: string) =>
|
||||
bot.helpers.sendInteractionResponse(interaction.id, interaction.token, {
|
||||
type: InteractionResponseTypes.ChannelMessageWithSource,
|
||||
data: {
|
||||
flags: ApplicationCommandFlags.Ephemeral,
|
||||
embeds: [{
|
||||
color: warnColor,
|
||||
title: 'Hey! Stop that!',
|
||||
description: `You are neither the owner of this event nor a ${config.name} manager in this guild, meaning you are not allowed to ${stopWhat} this event.
|
||||
|
||||
${safelyDismissMsg}`,
|
||||
}],
|
||||
},
|
||||
}).catch((e: Error) => utils.commonLoggers.interactionSendError('commandUtils.ts@stopThat', interaction, e));
|
||||
|
||||
// Send DM to User
|
||||
export const sendDirectMessage = async (bot: Bot, userId: bigint, message: CreateMessage) => {
|
||||
|
|
|
@ -14,6 +14,7 @@ export const dbClient = await new Client().connect({
|
|||
export const queries = {
|
||||
callIncCnt: (cmdName: string) => `CALL INC_CNT("${cmdName}");`,
|
||||
insertEvent: 'INSERT INTO active_event(messageId,channelId,guildId,ownerId,eventTime) values(?,?,?,?,?)',
|
||||
deleteEvent: 'DELETE FROM active_event WHERE channelId = ? AND messageId = ?',
|
||||
};
|
||||
|
||||
export const lfgChannelSettings: Map<string, LfgChannelSetting> = new Map();
|
||||
|
|
Loading…
Reference in New Issue