Skip to content

Commit

Permalink
feat(upcomingRaids #113): List upcoming raids for a server
Browse files Browse the repository at this point in the history
  • Loading branch information
DasithKuruppu committed Feb 12, 2023
1 parent 81abb77 commit 1b391a8
Show file tree
Hide file tree
Showing 11 changed files with 452 additions and 97 deletions.
90 changes: 90 additions & 0 deletions bot/embeds/templates/raidSummary/raidSummary.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import { convertToDiscordDate } from "../../../interactions/messageComponents/utils/date/dateToDiscordTimeStamp";

const createRaidSummary = ({
userId,
raidsList,
timestamp = new Date(),
requestedTime = Date.now(),
}) => {
const hasRaidList = createRaidSummary?.length;
return {
type: "rich",
title: `Raid summary for the upcoming week`,
description: `${raidsList?.length} available raids for the upcoming week\n
Last updated - ${convertToDiscordDate("now", {
relative: true,
})}
`,
color: 0xffa200,
timestamp,
// thumbnail: {
// url: `https://www.dasithsblog.com/images/Ranger-Hunter-Build.png`,
// height: 0,
// width: 0,
// },
// author: {
// name: `${userName}`,
// },
fields: raidsList.map(
({
raidName,
eventDiscordDateTime,
type,
createdBy,
raidUrl,
authorName,
}) => {
const relativeProcessedTime =
Number(
eventDiscordDateTime.substring(3, eventDiscordDateTime.length - 3)
) * 1000;
const relativeProcessedTimeDiscordConvertion = convertToDiscordDate(
new Date(relativeProcessedTime).toUTCString(),
{ relative: true }
);
console.log({
relativeProcessedTime,
relativeProcessedTimeDiscordConvertion,
requestedTime,
});
return {
name: `${raidName} [${type}]`,
value: `[Go to raid - ${raidName}](${raidUrl})\n⏱️ ${eventDiscordDateTime}\n⌛ ${relativeProcessedTimeDiscordConvertion} \n created by <@${createdBy}>`,
inline: false,
};
}
),
// footer: {
// text: `Footer text`,
// },
};
};

export const raidSummaryBuilder = ({ userId, raidsList }) => {
const serverProfileEmbed = createRaidSummary({
userId,
raidsList,
});
return {
components: [
{
type: 1,
components: [
{
style: 3,
label: `Refresh`,
emoji: {
id: `1074205923154858014`,
name: `refresh`,
animated: false,
},
custom_id: `button_raidsummary_refresh`,
disabled: false,
type: 2,
},
],
},
],
embeds: [serverProfileEmbed],
};
};
2 changes: 1 addition & 1 deletion bot/interactions/commands/ask/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ export const askCommand = async (
const currentUpdatedEmbedDescription = currentEmbed.description
.replace(/<t:.+:F>/gi, requestedDateTime)
.replace(/<t:.+:R>/gi, requestedTimeRelative);
const updatedRecordData = updateRaid(
const updatedRecordData = await updateRaid(
{
raidId: raidRecord.raidId,
createdAt: raidRecord.createdAt,
Expand Down
2 changes: 2 additions & 0 deletions bot/interactions/commands/request/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { inviteLinkCommand} from "./inviteLink"
import { buildCommand } from "./builds";
import { profileCommand } from "./profile";
import { serverProfileCommand } from "./serverProfile"
import { raidSummaryCommand } from "./raidSummary"
import { unrecognizedCommand } from "..";
interface factoryInitializations {
logger: Logger;
Expand All @@ -28,6 +29,7 @@ export const availableSubCommands = {
build: buildCommand,
profile: profileCommand,
server_profile: serverProfileCommand,
raid_summary: raidSummaryCommand
};
export const recognizedSubCommands = Object.keys(availableSubCommands);
export const requestCommand = async (
Expand Down
61 changes: 61 additions & 0 deletions bot/interactions/commands/request/raidSummary.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import {
APIChatInputApplicationCommandInteractionData,
ApplicationCommandOptionType,
REST,
Routes,
APIInteractionGuildMember,
APIApplicationCommandInteractionDataSubcommandOption,
RESTGetAPIChannelMessageResult,
} from "discord.js";

import { Logger } from "winston";
import {
getNewClassOptionsList,
getOptionsList,
} from "../../../embeds/templates/neverwinter/classesList";
import {
profileBuilder,
UserStatusValues,
} from "../../../embeds/templates/neverwinter/profile";
import { raidSummaryBuilder } from "../../../embeds/templates/raidSummary/raidSummary";
import { convertToDiscordDate } from "../../messageComponents/utils/date/dateToDiscordTimeStamp";
import { displayArtifactAsEmoji } from "../../messageComponents/utils/helper/artifactsRenderer";
import { fieldSorter } from "../../messageComponents/utils/helper/artifactsSorter";
import {
createFieldName,
defaultJoinStatus,
statusSymbols,
} from "../../messageComponents/utils/helper/embedFieldAttribute";
import { getUpcomingWeekRaids } from "../../messageComponents/utils/storeOps/fetchData";
import { IfactoryInitializations } from "../../typeDefinitions/event";
import { getAvailableUpcomingWeekRaids } from "../../utils/util";

export const raidSummaryCommand = async (
data: APIChatInputApplicationCommandInteractionData,
factoryInits: IfactoryInitializations
) => {
const { rest, logger, interactionConfig, documentClient } = factoryInits;
const [{ type: subCommandType, options: subCommandOptions = [] }] =
data.options as APIApplicationCommandInteractionDataSubcommandOption[];
const processedUpcomingRaids = await getAvailableUpcomingWeekRaids({
serverId: interactionConfig.guild_id,
documentClient,
rest,
logger,
});
logger.log("info", "processed raids", { processedUpcomingRaids });
const buildData = raidSummaryBuilder({
userId: interactionConfig.member.user.id,
raidsList: processedUpcomingRaids,
});

return {
body: {
...buildData,
content: ``,
allowed_mentions: {
parse: [],
},
},
};
};
2 changes: 2 additions & 0 deletions bot/interactions/messageComponents/buttons/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ import { confirmButtonInteract } from "./raidButton/confirm";
import { defaultRaidButtonInfo } from "../../../embeds/templates/neverwinter/raid";
import { waitlistButtonInteract } from "./raidButton/waitlist";
import { wontJoinButtonInteract } from "./raidButton/wontJoin";
import { refreshRaidSummary } from "./raidSummary/refresh";

export const buttonInteractions = {
[defaultRaidButtonInfo.buttons.joinConfirmButton.id]: confirmButtonInteract,
[defaultRaidButtonInfo.buttons.joinWaitlistButton.id]: waitlistButtonInteract,
[defaultRaidButtonInfo.buttons.wontJoinButton.id]: wontJoinButtonInteract,
button_raidsummary_refresh: refreshRaidSummary,
};

export const recognizedButtonInteractionComponentIds =
Expand Down
58 changes: 58 additions & 0 deletions bot/interactions/messageComponents/buttons/raidSummary/refresh.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { APIMessageSelectMenuInteractionData } from "discord-api-types/payloads/v10/interactions";
import { IfactoryInitializations } from "../../../typeDefinitions/event";
import {
Category,
determineActions,
getEmbedFieldsSeperatedSections,
getExistingMemberRecordDetails,
} from "../../utils/categorizeEmbedFields/categorizeEmbedFields";
import { defaultJoinStatus } from "../../utils/helper/embedFieldAttribute";
import {
createRaidContent,
determineRaidTemplateType,
getRaidTime,
getRaidTitle,
} from "../../utils/helper/raid";
import { raidSummaryBuilder } from "../../../../embeds/templates/raidSummary/raidSummary";
import { getAvailableUpcomingWeekRaids } from "../../../../interactions/utils/util";
export const refreshRaidSummary = async (
data: APIMessageSelectMenuInteractionData,
factoryInits: IfactoryInitializations
) => {
const {
logger,
rest,
documentClient,
interactionConfig: {
application_id,
token,
guild_id,
channel_id,
member,
message,
},
} = factoryInits;
const processedUpcomingRaids = await getAvailableUpcomingWeekRaids({
serverId: guild_id,
documentClient,
rest,
logger,
});

logger.log("info", "processed raids", { processedUpcomingRaids });

const buildData = raidSummaryBuilder({
userId: member.user.id,
raidsList: processedUpcomingRaids,
});

return {
body: {
...buildData,
content: ``,
allowed_mentions: {
parse: [],
},
},
};
};
28 changes: 28 additions & 0 deletions bot/interactions/messageComponents/utils/storeOps/fetchData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,31 @@ export const getRaid = async (
const [Item] = Items;
return Item;
};

export const getUpcomingWeekRaids = async (
{ serverId, today = Date.now() }: { serverId: string; today?: number },
{ documentClient }
) => {
const currentDay = new Date(today);
const weekAhead = currentDay.setDate(currentDay.getDate() + 7);
const dbResult = await documentClient
.query({
TableName: raidsTable.name.get(),
IndexName: "eventTimeIndex",
KeyConditionExpression: "#serverId = :pkey AND #eventDiscordDateTime BETWEEN :today AND :weekAhead",
ExpressionAttributeValues: {
":pkey": serverId,
":weekAhead": `<t:${weekAhead}:F>`,
":today": `<t:${today}:F>`,
},
ExpressionAttributeNames: {
"#serverId": "serverId",
"#eventDiscordDateTime": "eventDiscordDateTime",
},
ScanIndexForward: true,
Limit: 10,
})
.promise();
const { Items = [] } = dbResult;
return Items;
};
60 changes: 60 additions & 0 deletions bot/interactions/utils/util.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { RESTGetAPIChannelMessageResult, Routes } from "discord.js";
import { getUpcomingWeekRaids } from "../messageComponents/utils/storeOps/fetchData";
export const getAvailableUpcomingWeekRaids = async ({
serverId,
documentClient,
rest,
logger,
}) => {
const upcomingWeekRaids = await getUpcomingWeekRaids(
{ serverId },
{
documentClient,
}
);
logger.log("info", "Raid", { upcomingWeekRaids });

const processedUpcomingRaids = upcomingWeekRaids
.filter(({ title, messageId }) => title && messageId)
.map(
async ({
title,
creatorId,
autorName,
eventDiscordDateTime,
isFivePerson,
description,
template,
raidEmbed,
serverId,
messageId,
channelId,
type,
updatedAt,
}) => {
const raidMessage = (await rest.get(
(Routes as any).channelMessage(channelId, messageId)
)) as RESTGetAPIChannelMessageResult;
return {
authorName: autorName,
raidName: title,
eventDiscordDateTime,
type,
createdBy: creatorId,
raidMessage,
raidUrl: `https://discord.com/channels/${serverId}/${channelId}/${messageId}`,
};
}
);

const resolvedUpcomingRaids = await Promise.allSettled(
processedUpcomingRaids as any[]
);

const upcomingExisitingRecords = (
resolvedUpcomingRaids.filter(
({ status }) => status === "fulfilled"
) as PromiseFulfilledResult<any>[]
).map(({ value }) => value);
return upcomingExisitingRecords;
};
Loading

0 comments on commit 1b391a8

Please sign in to comment.