Finalize event creation
Add active_event db table Rename gameSelection button to gameSelection for consistency Fix prefill for DateTime modal to correctly parse time and to not misparse other embeds Add autoCleanup to finalize step Add whole createEvent step Code usability updates to event-creation utils
This commit is contained in:
parent
be4caa1fb1
commit
e609654761
|
@ -13,6 +13,7 @@ console.log('Attempt to drop all tables');
|
||||||
await dbClient.execute(`DROP PROCEDURE IF EXISTS INC_CNT;`);
|
await dbClient.execute(`DROP PROCEDURE IF EXISTS INC_CNT;`);
|
||||||
await dbClient.execute(`DROP TABLE IF EXISTS command_cnt;`);
|
await dbClient.execute(`DROP TABLE IF EXISTS command_cnt;`);
|
||||||
await dbClient.execute(`DROP TABLE IF EXISTS guild_settings;`);
|
await dbClient.execute(`DROP TABLE IF EXISTS guild_settings;`);
|
||||||
|
await dbClient.execute(`DROP TABLE IF EXISTS active_event;`);
|
||||||
console.log('Tables dropped');
|
console.log('Tables dropped');
|
||||||
|
|
||||||
console.log('Attempting to create table command_cnt');
|
console.log('Attempting to create table command_cnt');
|
||||||
|
@ -51,5 +52,20 @@ await dbClient.execute(`
|
||||||
`);
|
`);
|
||||||
console.log('Table created');
|
console.log('Table created');
|
||||||
|
|
||||||
|
console.log('Attempting to create table active_event');
|
||||||
|
await dbClient.execute(`
|
||||||
|
CREATE TABLE active_event (
|
||||||
|
messageId bigint unsigned NOT NULL,
|
||||||
|
channelId bigint unsigned NOT NULL,
|
||||||
|
guildId bigint unsigned NOT NULL,
|
||||||
|
ownerId bigint unsigned NOT NULL,
|
||||||
|
eventTime timestamp NOT NULL,
|
||||||
|
notifiedFlag tinyint(1) NOT NULL DEFAULT 0,
|
||||||
|
lockedFlag tinyint(1) NOT NULL DEFAULT 0,
|
||||||
|
PRIMARY KEY (messageId, channelId)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
`);
|
||||||
|
console.log('Table created');
|
||||||
|
|
||||||
await dbClient.close();
|
await dbClient.close();
|
||||||
console.log('Done!');
|
console.log('Done!');
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
import { Button } from '../types/commandTypes.ts';
|
import { Button } from '../types/commandTypes.ts';
|
||||||
import { createEventButton } from './event-creation/step1-gameSelection.ts';
|
import { gameSelectionButton } from './event-creation/step1-gameSelection.ts';
|
||||||
import { createCustomEventButton } from './event-creation/step1a-openCustomModal.ts';
|
import { createCustomEventButton } from './event-creation/step1a-openCustomModal.ts';
|
||||||
import { verifyCustomEventButton } from './event-creation/step1b-verifyCustomActivity.ts';
|
import { verifyCustomEventButton } from './event-creation/step1b-verifyCustomActivity.ts';
|
||||||
import { finalizeEventButton } from './event-creation/step2-finalize.ts';
|
import { finalizeEventButton } from './event-creation/step2-finalize.ts';
|
||||||
|
import { createEventButton } from './event-creation/step3-createEvent.ts';
|
||||||
|
|
||||||
export const buttons: Array<Button> = [createEventButton, createCustomEventButton, verifyCustomEventButton, finalizeEventButton];
|
export const buttons: Array<Button> = [gameSelectionButton, createCustomEventButton, verifyCustomEventButton, finalizeEventButton, createEventButton];
|
||||||
|
|
|
@ -14,6 +14,7 @@ import {
|
||||||
pathIdxSeparator,
|
pathIdxSeparator,
|
||||||
selfDestructMessage,
|
selfDestructMessage,
|
||||||
tokenMap,
|
tokenMap,
|
||||||
|
lfgStartTimeName,
|
||||||
} from './utils.ts';
|
} from './utils.ts';
|
||||||
import utils from '../../utils.ts';
|
import utils from '../../utils.ts';
|
||||||
import { customId as createCustomActivityBtnId } from './step1a-openCustomModal.ts';
|
import { customId as createCustomActivityBtnId } from './step1a-openCustomModal.ts';
|
||||||
|
@ -57,10 +58,10 @@ const execute = async (bot: Bot, interaction: Interaction) => {
|
||||||
let prefillTimeZone = '';
|
let prefillTimeZone = '';
|
||||||
let prefillDate = '';
|
let prefillDate = '';
|
||||||
let prefillDescription = '';
|
let prefillDescription = '';
|
||||||
if (interaction.message && interaction.message.embeds[0].fields) {
|
if (interaction.message && interaction.message.embeds[0].fields && interaction.message.embeds[0].fields[LfgEmbedIndexes.StartTime].name === lfgStartTimeName) {
|
||||||
let rawEventDateTime = interaction.message.embeds[0].fields[LfgEmbedIndexes.StartTime].value.split('\n')[0].split(' ');
|
let rawEventDateTime = interaction.message.embeds[0].fields[LfgEmbedIndexes.StartTime].value.split('\n')[0].split(' ');
|
||||||
const monthIdx = rawEventDateTime.findIndex((item) => monthsShort.includes(item.toUpperCase()));
|
const monthIdx = rawEventDateTime.findIndex((item) => monthsShort.includes(item.toUpperCase()));
|
||||||
prefillTime = rawEventDateTime.slice(0, monthIdx - 2).join(' ').trim();
|
prefillTime = rawEventDateTime.slice(0, monthIdx - 1).join(' ').trim();
|
||||||
prefillTimeZone = rawEventDateTime[monthIdx - 1].trim();
|
prefillTimeZone = rawEventDateTime[monthIdx - 1].trim();
|
||||||
prefillDate = rawEventDateTime.slice(monthIdx).join(' ').trim();
|
prefillDate = rawEventDateTime.slice(monthIdx).join(' ').trim();
|
||||||
prefillDescription = interaction.message.embeds[0].fields[LfgEmbedIndexes.Description].value.trim();
|
prefillDescription = interaction.message.embeds[0].fields[LfgEmbedIndexes.Description].value.trim();
|
||||||
|
@ -180,12 +181,12 @@ const execute = async (bot: Bot, interaction: Interaction) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const createEventCommand = {
|
export const gameSelectionCommand = {
|
||||||
details,
|
details,
|
||||||
execute,
|
execute,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const createEventButton = {
|
export const gameSelectionButton = {
|
||||||
customId,
|
customId,
|
||||||
execute,
|
execute,
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { Bot, Interaction, InteractionResponseTypes, MessageComponentTypes, TextStyles } from '../../../deps.ts';
|
import { Bot, Interaction } from '../../../deps.ts';
|
||||||
import { somethingWentWrong } from '../../commandUtils.ts';
|
import { somethingWentWrong } from '../../commandUtils.ts';
|
||||||
import { eventDateId, eventDescriptionId, eventTimeId, eventTimeZoneId } from './step1-gameSelection.ts';
|
import { eventDateId, eventDescriptionId, eventTimeId, eventTimeZoneId } from './step1-gameSelection.ts';
|
||||||
import { createLFGPost, getFinalActivity, idSeparator, pathIdxSeparator } from './utils.ts';
|
import { createLFGPost, getFinalActivity, idSeparator, pathIdxSeparator, addTokenToMap } from './utils.ts';
|
||||||
import { Activities, Activity } from './activities.ts';
|
import { Activities, Activity } from './activities.ts';
|
||||||
import { getDateFromRawInput } from './dateTimeUtils.ts';
|
import { getDateFromRawInput } from './dateTimeUtils.ts';
|
||||||
|
|
||||||
|
@ -53,13 +53,27 @@ const execute = async (bot: Bot, interaction: Interaction) => {
|
||||||
// Get Date Object from user input
|
// Get Date Object from user input
|
||||||
const [eventDateTime, eventDateTimeStr] = getDateFromRawInput(rawEventTime, rawEventTimeZone, rawEventDate);
|
const [eventDateTime, eventDateTimeStr] = getDateFromRawInput(rawEventTime, rawEventTimeZone, rawEventDate);
|
||||||
|
|
||||||
|
addTokenToMap(bot, interaction, interaction.guildId, interaction.channelId, interaction.member.id);
|
||||||
bot.helpers.sendInteractionResponse(
|
bot.helpers.sendInteractionResponse(
|
||||||
interaction.id,
|
interaction.id,
|
||||||
interaction.token,
|
interaction.token,
|
||||||
createLFGPost(category, activity, eventDateTime, eventDateTimeStr, eventDescription, interaction.member.id, interaction.member.user.username, [], [], customIdIdxPath, true),
|
createLFGPost(
|
||||||
|
category,
|
||||||
|
activity,
|
||||||
|
eventDateTime,
|
||||||
|
eventDateTimeStr,
|
||||||
|
eventDescription,
|
||||||
|
interaction.member.id,
|
||||||
|
interaction.member.user.username,
|
||||||
|
[{
|
||||||
|
id: interaction.member.id,
|
||||||
|
name: interaction.member.user.username,
|
||||||
|
}],
|
||||||
|
[],
|
||||||
|
customIdIdxPath,
|
||||||
|
true,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
// somethingWentWrong(bot, interaction, `TESTING@${rawEventTime}_${rawEventTimeZone}_${rawEventDate}`);
|
|
||||||
} else {
|
} else {
|
||||||
somethingWentWrong(bot, interaction, 'noDataFromEventDescriptionModal');
|
somethingWentWrong(bot, interaction, 'noDataFromEventDescriptionModal');
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
import { Bot, Interaction, InteractionResponseTypes, MessageComponentTypes } from '../../../deps.ts';
|
||||||
|
import { deleteTokenEarly, LfgEmbedIndexes, generateLFGButtons, idSeparator } from './utils.ts';
|
||||||
|
import { somethingWentWrong } from '../../commandUtils.ts';
|
||||||
|
import { dbClient, queries } from '../../db.ts';
|
||||||
|
import utils from '../../utils.ts';
|
||||||
|
|
||||||
|
export const customId = 'createEvent';
|
||||||
|
|
||||||
|
const execute = async (bot: Bot, interaction: Interaction) => {
|
||||||
|
if (interaction.data?.customId && interaction.member && interaction.guildId && interaction.channelId && interaction.message && interaction.message.embeds[0] && interaction.message.embeds[0].fields) {
|
||||||
|
deleteTokenEarly(bot, interaction, interaction.guildId, interaction.channelId, interaction.member.id);
|
||||||
|
|
||||||
|
// Get OwnerId and EventTime from embed for DB
|
||||||
|
const ownerId: bigint = BigInt(interaction.message.embeds[0].footer?.iconUrl?.split('#')[1] || '0');
|
||||||
|
const eventTime: Date = new Date(parseInt(interaction.message.embeds[0].fields[LfgEmbedIndexes.ICSLink].value.split('?t=')[1].split('&n=')[0] || '0'));
|
||||||
|
|
||||||
|
// Send Event Message
|
||||||
|
const eventMessage = await bot.helpers.sendMessage(interaction.channelId, {
|
||||||
|
embeds: [interaction.message.embeds[0]],
|
||||||
|
components: [{
|
||||||
|
type: MessageComponentTypes.ActionRow,
|
||||||
|
components: generateLFGButtons(interaction.data.customId.includes(idSeparator)),
|
||||||
|
}]
|
||||||
|
}).catch((e: Error) => utils.commonLoggers.messageSendError('step3-createEvent.ts', 'createEvent', e));
|
||||||
|
if (!eventMessage) {
|
||||||
|
somethingWentWrong(bot, interaction, 'creatingEventSendMessageFinalizeEventStep');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store in DB
|
||||||
|
let dbErrorOut = false;
|
||||||
|
await dbClient.execute(queries.insertEvent, [eventMessage.id, eventMessage.channelId, interaction.guildId, ownerId, eventTime]).catch((e) => {
|
||||||
|
utils.commonLoggers.dbError('step3-createEvent.ts', 'INSERT event to DB', e);
|
||||||
|
dbErrorOut = true;
|
||||||
|
});
|
||||||
|
if (dbErrorOut) {
|
||||||
|
bot.helpers.deleteMessage(eventMessage.channelId, eventMessage.id, 'Failed to log event to DB').catch((e: Error) => utils.commonLoggers.messageDeleteError('step3-createEvent.ts', 'deleteEventFailedDB', e));
|
||||||
|
somethingWentWrong(bot, interaction, 'creatingEventDBStoreFinalizeEventStep');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Let discord know we didn't ignore the user
|
||||||
|
bot.helpers.sendInteractionResponse(interaction.id, interaction.token, {
|
||||||
|
type: InteractionResponseTypes.DeferredUpdateMessage,
|
||||||
|
});
|
||||||
|
|
||||||
|
} else {
|
||||||
|
somethingWentWrong(bot, interaction, 'noDataFromFinalizeEventStep');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const createEventButton = {
|
||||||
|
customId,
|
||||||
|
execute,
|
||||||
|
};
|
|
@ -16,6 +16,7 @@ import utils from '../../utils.ts';
|
||||||
import { successColor } from '../../commandUtils.ts';
|
import { successColor } from '../../commandUtils.ts';
|
||||||
import { LFGMember } from '../../types/commandTypes.ts';
|
import { LFGMember } from '../../types/commandTypes.ts';
|
||||||
import { customId as gameSelCustomId } from './step1-gameSelection.ts';
|
import { customId as gameSelCustomId } from './step1-gameSelection.ts';
|
||||||
|
import { customId as createEventCustomId } from './step3-createEvent.ts';
|
||||||
|
|
||||||
// Discord Interaction Tokens last 15 minutes, we will self kill after 14.5 minutes
|
// Discord Interaction Tokens last 15 minutes, we will self kill after 14.5 minutes
|
||||||
const tokenTimeoutS = (15 * 60) - 30;
|
const tokenTimeoutS = (15 * 60) - 30;
|
||||||
|
@ -90,12 +91,12 @@ const finalizeButtons = (idxPath: string): [ButtonComponent, ButtonComponent, Bu
|
||||||
type: MessageComponentTypes.Button,
|
type: MessageComponentTypes.Button,
|
||||||
label: 'Create Event',
|
label: 'Create Event',
|
||||||
style: ButtonStyles.Success,
|
style: ButtonStyles.Success,
|
||||||
customId: 'createEvent', // TODO: replace with proper id
|
customId: createEventCustomId,
|
||||||
}, {
|
}, {
|
||||||
type: MessageComponentTypes.Button,
|
type: MessageComponentTypes.Button,
|
||||||
label: 'Create Whitelisted Event',
|
label: 'Create Whitelisted Event',
|
||||||
style: ButtonStyles.Primary,
|
style: ButtonStyles.Primary,
|
||||||
customId: `createEvent${idSeparator}`, // TODO: replace with proper id
|
customId: `${createEventCustomId}${idSeparator}`,
|
||||||
}, {
|
}, {
|
||||||
type: MessageComponentTypes.Button,
|
type: MessageComponentTypes.Button,
|
||||||
label: 'Edit Event Details',
|
label: 'Edit Event Details',
|
||||||
|
@ -136,6 +137,10 @@ export const generateLFGButtons = (whitelist: boolean): [ButtonComponent, Button
|
||||||
},
|
},
|
||||||
}];
|
}];
|
||||||
|
|
||||||
|
const generateMemberTitle = (memberList: Array<LFGMember>, maxMembers: number): string => `Members Joined: ${memberList.length}/${maxMembers}`;
|
||||||
|
const generateMemberList = (memberList: Array<LFGMember>): string => memberList.length ? memberList.map((member) => `${member.name} - <@${member.id}>`).join('\n') : 'None';
|
||||||
|
const generateAlternateList = (alternateList: Array<LFGMember>): string => alternateList.length ? alternateList.map((member) => `${member.name} - <@${member.id}>${member.joined ? ' *' : ''}`).join('\n') : 'None';
|
||||||
|
|
||||||
export enum LfgEmbedIndexes {
|
export enum LfgEmbedIndexes {
|
||||||
Activity,
|
Activity,
|
||||||
StartTime,
|
StartTime,
|
||||||
|
@ -143,7 +148,8 @@ export enum LfgEmbedIndexes {
|
||||||
Description,
|
Description,
|
||||||
JoinedMembers,
|
JoinedMembers,
|
||||||
AlternateMembers,
|
AlternateMembers,
|
||||||
}
|
};
|
||||||
|
export const lfgStartTimeName = 'Start Time:';
|
||||||
export const createLFGPost = (
|
export const createLFGPost = (
|
||||||
category: string,
|
category: string,
|
||||||
activity: Activity,
|
activity: Activity,
|
||||||
|
@ -162,8 +168,8 @@ export const createLFGPost = (
|
||||||
return {
|
return {
|
||||||
type: InteractionResponseTypes.ChannelMessageWithSource,
|
type: InteractionResponseTypes.ChannelMessageWithSource,
|
||||||
data: {
|
data: {
|
||||||
flags: ApplicationCommandFlags.Ephemeral,
|
flags: editing ? ApplicationCommandFlags.Ephemeral : undefined,
|
||||||
content: editing ? 'Please verify the information below, then click on the $name button below' : 'test',
|
content: editing ? `Please verify the information below, then click on the $name button below.\n\n${selfDestructMessage(new Date().getTime())}` : '',
|
||||||
embeds: [{
|
embeds: [{
|
||||||
color: successColor,
|
color: successColor,
|
||||||
fields: [{
|
fields: [{
|
||||||
|
@ -171,7 +177,7 @@ export const createLFGPost = (
|
||||||
value: activity.name,
|
value: activity.name,
|
||||||
inline: true,
|
inline: true,
|
||||||
}, {
|
}, {
|
||||||
name: 'Start Time:',
|
name: lfgStartTimeName,
|
||||||
value: `${eventDateTimeStr}\n<t:${Math.floor(eventDateTime.getTime() / 1000)}:R>`,
|
value: `${eventDateTimeStr}\n<t:${Math.floor(eventDateTime.getTime() / 1000)}:R>`,
|
||||||
inline: true,
|
inline: true,
|
||||||
}, {
|
}, {
|
||||||
|
@ -182,12 +188,12 @@ export const createLFGPost = (
|
||||||
name: 'Description:',
|
name: 'Description:',
|
||||||
value: eventDescription,
|
value: eventDescription,
|
||||||
}, {
|
}, {
|
||||||
name: `Members Joined: ${memberList.length}/${activity.maxMembers}`,
|
name: generateMemberTitle(memberList, activity.maxMembers || 0),
|
||||||
value: memberList.length ? memberList.map((member) => `${member.name} - <@${member.id}>`).join('\n') : 'None',
|
value: generateMemberList(memberList),
|
||||||
inline: true,
|
inline: true,
|
||||||
}, {
|
}, {
|
||||||
name: 'Alternates:',
|
name: 'Alternates:',
|
||||||
value: alternateList.length ? alternateList.map((member) => `${member.name} - <@${member.id}>${member.joined ? ' *' : ''}`).join('\n') : 'None',
|
value: generateAlternateList(alternateList),
|
||||||
inline: true,
|
inline: true,
|
||||||
}],
|
}],
|
||||||
footer: {
|
footer: {
|
||||||
|
|
|
@ -6,9 +6,9 @@ import info from './info.ts';
|
||||||
import report from './report.ts';
|
import report from './report.ts';
|
||||||
import setup from './setup.ts';
|
import setup from './setup.ts';
|
||||||
import deleteCmd from './delete.ts';
|
import deleteCmd from './delete.ts';
|
||||||
import { createEventCommand } from '../buttons/event-creation/step1-gameSelection.ts';
|
import { gameSelectionCommand } from '../buttons/event-creation/step1-gameSelection.ts';
|
||||||
|
|
||||||
export const commands: Array<Command> = [deleteCmd, info, report, setup, createEventCommand];
|
export const commands: Array<Command> = [deleteCmd, info, report, setup, gameSelectionCommand];
|
||||||
|
|
||||||
export const createSlashCommands = async (bot: Bot) => {
|
export const createSlashCommands = async (bot: Bot) => {
|
||||||
const globalCommands: MakeRequired<CreateApplicationCommand, 'name'>[] = [];
|
const globalCommands: MakeRequired<CreateApplicationCommand, 'name'>[] = [];
|
||||||
|
|
|
@ -13,6 +13,7 @@ export const dbClient = await new Client().connect({
|
||||||
|
|
||||||
export const queries = {
|
export const queries = {
|
||||||
callIncCnt: (cmdName: string) => `CALL INC_CNT("${cmdName}");`,
|
callIncCnt: (cmdName: string) => `CALL INC_CNT("${cmdName}");`,
|
||||||
|
insertEvent: 'INSERT INTO active_event(messageId,channelId,guildId,ownerId,eventTime) values(?,?,?,?,?)',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const lfgChannelSettings: Map<string, LfgChannelSetting> = new Map();
|
export const lfgChannelSettings: Map<string, LfgChannelSetting> = new Map();
|
||||||
|
|
Loading…
Reference in New Issue