Add command to close the poll and update the event
This commit is contained in:
		
							
								
								
									
										115
									
								
								server/commands/closepoll.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										115
									
								
								server/commands/closepoll.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,115 @@ | ||||
| import { Command } from '../structures/command' | ||||
| import { RunOptions } from '../types/commandTypes' | ||||
| import { APIEmbed, Guild, GuildScheduledEvent, GuildScheduledEventEditOptions, GuildScheduledEventSetStatusArg, GuildScheduledEventStatus, Message, MessageEditOptions, TextChannel } from 'discord.js' | ||||
| import { v4 as uuid } from 'uuid' | ||||
| import { logger } from '../logger' | ||||
| import { config } from '../configuration' | ||||
| import { Emotes } from '../events/guildScheduledEventCreate' | ||||
| import { EndOfLineState } from 'typescript' | ||||
|  | ||||
| export default new Command({ | ||||
|     name: 'closepoll', | ||||
|     description: 'Aktuelle Umfrage für nächste Watchparty beenden und Gewinner in Event eintragen.', | ||||
|     options: [], | ||||
|     run: async (interaction: RunOptions) => { | ||||
|         const command = interaction.interaction | ||||
|         const requestId = uuid() | ||||
|         const guildId = command.guildId! | ||||
|         logger.info("Got command for closing poll!", { guildId: guildId, requestId }) | ||||
|  | ||||
|         const announcementChannel: TextChannel = <TextChannel>(await command.guild?.channels.fetch()) | ||||
|             ?.filter(channel => channel!.id === config.bot.announcement_channel_id) | ||||
|             .map((value, _) => value)[0] //todo: needs to be done less sketchy | ||||
|  | ||||
|         interaction.interaction.followUp("Alles klar, beende die Umfrage :)") | ||||
|  | ||||
|  | ||||
|         const messages: Message<true>[] = (await announcementChannel.messages.fetch()) //todo: fetch only pinned messages | ||||
|             .map((value, _) => value) | ||||
|             .filter(message => !message.cleanContent.includes("[Abstimmung beendet]") && message.cleanContent.includes("[Abstimmung]")) | ||||
|             .sort((a, b) => b.createdTimestamp - a.createdTimestamp)  | ||||
|              | ||||
|  | ||||
|         const lastMessage: Message<true> = messages[0] | ||||
|  | ||||
|         logger.debug(`Found messages: ${JSON.stringify(messages, null, 2)}`, { guildId: guildId, requestId }) | ||||
|  | ||||
|         logger.debug(`Last message: ${JSON.stringify(lastMessage, null, 2)}`, { guildId: guildId, requestId }) | ||||
|  | ||||
|         const votes = await (await getVotesByEmote(lastMessage, guildId, requestId)) | ||||
|             .sort((a, b) => b.count - a.count) | ||||
|  | ||||
|         logger.debug(`votes: ${JSON.stringify(votes, null, 2)}`, { guildId: guildId, requestId }) | ||||
|  | ||||
|         updateEvent(votes, command.guild!, guildId, requestId) | ||||
|         updateMessage(votes[0].movie, lastMessage, guildId, requestId) | ||||
|  | ||||
|         //lastMessage.unpin() //todo: uncomment when bot has permission to pin/unpin | ||||
|     } | ||||
| }) | ||||
|  | ||||
| async function updateMessage(movie: string, message: Message, guildId: string, requestId: string) { | ||||
|     const body = `[Abstimmung beendet] Gewonnen hat: ${movie}` | ||||
|         .concat(message.cleanContent.substring("[Abstimmung]".length)) | ||||
|  | ||||
|     const options: MessageEditOptions = { | ||||
|         content: body, | ||||
|     } | ||||
|     message.edit(options) | ||||
|  | ||||
| } | ||||
|  | ||||
| async function updateEvent(votes: Vote[], guild: Guild, guildId: string, requestId: string) { | ||||
|     logger.info(`Updating event with movie ${votes[0].movie}.`, { guildId: guildId, requestId }) | ||||
|     const voteEvents = (await guild.scheduledEvents.fetch()) | ||||
|         .map((value, _) => value) | ||||
|         .filter(event => event.name.toLowerCase().includes("voting offen")) | ||||
|     logger.debug(`Found events: ${JSON.stringify(voteEvents, null, 2)}`, { guildId: guildId, requestId }) | ||||
|      | ||||
|     if(!voteEvents || voteEvents.length <= 0) { | ||||
|         logger.error("Could not find vote event. Cancelling update!", { guildId: guildId, requestId }) | ||||
|     } | ||||
|  | ||||
|     const voteEvent: GuildScheduledEvent<GuildScheduledEventStatus> = voteEvents[0] | ||||
|     const options: GuildScheduledEventEditOptions<GuildScheduledEventStatus.Scheduled, GuildScheduledEventSetStatusArg<GuildScheduledEventStatus.Scheduled>> = { | ||||
|         name: votes[0].movie, | ||||
|         description: `!wp\nNummer 2: ${votes[1].movie} mit ${votes[1].count -1} Stimmen\nNummer 3: ${votes[2].movie} mit ${votes[2].count -1} Stimmen` | ||||
|     } | ||||
|     logger.debug(`Updating event: ${JSON.stringify(voteEvent, null, 2)}`, { guildId: guildId, requestId }) | ||||
|     voteEvent.edit(options) | ||||
| } | ||||
|  | ||||
| type Vote = { | ||||
|     emote: string, //todo habs nicht hinbekommen hier Emotes zu nutzen | ||||
|     count: number, | ||||
|     movie: string | ||||
| } | ||||
|  | ||||
| async function getVotesByEmote(message: Message, guildId: string, requestId: string): Promise<Vote[]> { | ||||
|     const votes: Vote[] = [] | ||||
|     logger.debug(`Number of items in emotes: ${Object.values(Emotes).length}`) | ||||
|     for (let i = 0; i < Object.keys(Emotes).length / 2; i++) { | ||||
|         const emote = Emotes[i] | ||||
|         // for (const emote of Object.keys(Emotes)) { | ||||
|         logger.debug(`Getting reaction for emote ${emote}`, { guildId: guildId, requestId }) | ||||
|         const reaction = await message.reactions.resolve(emote) | ||||
|         logger.debug(`Reaction for emote ${emote}: ${JSON.stringify(reaction, null, 2)}`, { guildId: guildId, requestId }) | ||||
|         if (reaction) { | ||||
|             const vote: Vote = { emote: emote, count: reaction.count, movie: extractMovieFromMessageByEmote(message, emote, guildId, requestId) } | ||||
|             votes.push(vote) | ||||
|         } | ||||
|     } | ||||
|     return votes | ||||
| } | ||||
|  | ||||
| function extractMovieFromMessageByEmote(message: Message, emote: string, guildId: string, requestId: string): string { | ||||
|     const lines = message.cleanContent.split("\n") | ||||
|     const emoteLines = lines.filter(line => line.includes(emote)) | ||||
|  | ||||
|     if (!emoteLines) { | ||||
|         return "" | ||||
|     } | ||||
|     const movie = emoteLines[0].substring(emoteLines[0].indexOf(emote) + emote.length + 2) // plus colon and space | ||||
|  | ||||
|     return movie | ||||
| } | ||||
| @ -8,7 +8,7 @@ import { config } from "../configuration"; | ||||
|  | ||||
| export const name = 'guildScheduledEventCreate' | ||||
|  | ||||
| const emotes = ["1️⃣", "2️⃣", "3️⃣", "4️⃣", "5️⃣", "6️⃣", "7️⃣", "8️⃣", "9️⃣", "🔟"] | ||||
| export enum Emotes {"1️⃣", "2️⃣", "3️⃣", "4️⃣", "5️⃣", "6️⃣", "7️⃣", "8️⃣", "9️⃣", "🔟"} | ||||
|  | ||||
| export async function execute(event: GuildScheduledEvent) { | ||||
|     const requestId = uuid() | ||||
| @ -28,17 +28,18 @@ export async function execute(event: GuildScheduledEvent) { | ||||
|         const channel: TextChannel = <TextChannel>(await event.guild?.channels.fetch())?.filter(channel => channel!.id === config.bot.announcement_channel_id).map((value, _) => value)[0] //todo: needs to be done less sketchy | ||||
|         logger.debug(`Found channel ${JSON.stringify(channel, null, 2)}`) | ||||
|  | ||||
|         let message = "Es gibt eine neue Abstimmung für die nächste Watchparty! Stimme hierunter für den nächsten Film ab!\n" | ||||
|         let message = "[Abstimmung]\nEs gibt eine neue Abstimmung für die nächste Watchparty! Stimme hierunter für den nächsten Film ab!\n" | ||||
|  | ||||
|         for (let i = 0; i < movies.length; i++) { | ||||
|             message = message.concat(emotes[i]).concat(": ").concat(movies[i].name!).concat("\n") | ||||
|             message = message.concat(Emotes[i]).concat(": ").concat(movies[i].name!).concat("\n") | ||||
|         } | ||||
|  | ||||
|         const sentMessage: Message<true> = await (await channel.fetch()).send(message) | ||||
|  | ||||
|         for (let i = 0; i < movies.length; i++) { | ||||
|             sentMessage.react(emotes[i]) | ||||
|             sentMessage.react(Emotes[i]) | ||||
|         } | ||||
|  | ||||
|         // sentMessage.pin() //todo: uncomment when bot has permission to pin messages. Also update closepoll.ts to only fetch pinned messages | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user