2023-06-13 21:12:32 +02:00
|
|
|
import { ApplicationCommandOptionType, Guild, GuildMember, Message, MessageCreateOptions, MessageReaction, Role, TextChannel, User } from 'discord.js'
|
2023-06-12 22:21:10 +02:00
|
|
|
import { v4 as uuid } from 'uuid'
|
2023-06-13 18:18:26 +02:00
|
|
|
import { client } from '../..'
|
2023-06-12 22:21:10 +02:00
|
|
|
import { config } from '../configuration'
|
|
|
|
import { logger } from '../logger'
|
|
|
|
import { Command } from '../structures/command'
|
|
|
|
import { RunOptions } from '../types/commandTypes'
|
2023-06-13 18:18:26 +02:00
|
|
|
import { off } from 'process'
|
|
|
|
import { ScheduledTask, schedule } from 'node-cron'
|
|
|
|
|
|
|
|
let task: ScheduledTask
|
2023-06-12 22:21:10 +02:00
|
|
|
|
|
|
|
export default new Command({
|
|
|
|
name: 'announce',
|
|
|
|
description: 'Neues announcement im announcement Channel an alle senden.',
|
2023-06-13 21:12:32 +02:00
|
|
|
options: [{
|
|
|
|
name: "typ",
|
|
|
|
type: ApplicationCommandOptionType.String,
|
|
|
|
description:"Was für ein announcement?",
|
|
|
|
choices: [{name: "initial", value:"initial"},{name: "votepls", value:"votepls"},{name: "cancel", value:"cancel"}],
|
|
|
|
required: true
|
|
|
|
}],
|
2023-06-12 22:21:10 +02:00
|
|
|
run: async (interaction: RunOptions) => {
|
|
|
|
const command = interaction.interaction
|
|
|
|
const requestId = uuid()
|
2023-06-14 22:24:39 +02:00
|
|
|
if(!command.guildId) {
|
|
|
|
logger.error("COMMAND DOES NOT HAVE A GUILD ID; CANCELLING!!!", {requestId})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
const guildId = command.guildId
|
2023-06-13 21:12:32 +02:00
|
|
|
const announcementType = command.options.data.find(option => option.name.includes("typ"))
|
|
|
|
logger.info(`Got command for announcing ${announcementType?.value}!`, { guildId, requestId })
|
|
|
|
|
|
|
|
if(!announcementType) {
|
|
|
|
logger.error("Did not get an announcement type!", { guildId, requestId })
|
|
|
|
return
|
|
|
|
}
|
2023-06-12 22:21:10 +02:00
|
|
|
|
2023-06-12 22:34:39 +02:00
|
|
|
if (!isAdmin(command.member)) {
|
|
|
|
logger.info(`Announcement was requested by ${command.member.displayName} but they are not an admin! Not sending announcement.`, { guildId, requestId })
|
|
|
|
return
|
|
|
|
} else {
|
|
|
|
logger.info(`User ${command.member.displayName} seems to be admin`)
|
|
|
|
}
|
2023-06-13 21:12:32 +02:00
|
|
|
|
|
|
|
if((<string>announcementType.value).includes("initial")) {
|
|
|
|
sendInitialAnnouncement(guildId, requestId)
|
|
|
|
command.followUp("Ist rausgeschickt!")
|
|
|
|
} else {
|
|
|
|
command.followUp(`${announcementType.value} ist aktuell noch nicht implementiert`)
|
|
|
|
}
|
2023-06-12 22:34:39 +02:00
|
|
|
}
|
|
|
|
})
|
2023-06-12 22:21:10 +02:00
|
|
|
|
2023-06-12 22:34:39 +02:00
|
|
|
function isAdmin(member: GuildMember): boolean {
|
2023-06-13 18:18:26 +02:00
|
|
|
return member.roles.cache.find((role, _) => role.id === config.bot.jf_admin_role) !== undefined
|
2023-06-12 22:34:39 +02:00
|
|
|
}
|
2023-06-12 22:21:10 +02:00
|
|
|
|
2023-06-13 21:12:32 +02:00
|
|
|
async function sendInitialAnnouncement(guildId: string, requestId: string): Promise<void> {
|
|
|
|
logger.info("Sending initial announcement")
|
2023-06-12 22:34:39 +02:00
|
|
|
const announcementChannel: TextChannel = client.getAnnouncementChannelForGuild(guildId)
|
2023-06-12 22:21:10 +02:00
|
|
|
|
2023-06-13 21:12:32 +02:00
|
|
|
const currentPinnedAnnouncementMessages = (await announcementChannel.messages.fetchPinned()).filter(message => message.cleanContent.includes("[initial]"))
|
2023-06-13 18:58:41 +02:00
|
|
|
currentPinnedAnnouncementMessages.forEach(async (message) => await message.unpin())
|
|
|
|
currentPinnedAnnouncementMessages.forEach(message => message.delete())
|
|
|
|
|
2023-06-13 21:12:32 +02:00
|
|
|
const body = `[initial] Hey! @everyone! Hier ist der Watchparty Bot vom Hartzarett.
|
2023-06-12 22:34:39 +02:00
|
|
|
|
|
|
|
Wir machen in Zukunft regelmäßig Watchparties! Falls du mitmachen möchtest, reagiere einfach auf diesen Post mit 🎫, dann bekommst du automatisch eine Rolle zugewiesen und wirst benachrichtigt sobald es in der Zukunft weitere Watchparties und Filme zum abstimmen gibt.
|
2023-06-12 22:21:10 +02:00
|
|
|
|
2023-06-12 22:34:39 +02:00
|
|
|
Für eine Erklärung wie das alles funktioniert mach einfach /mitgucken für eine lange Erklärung am Stück oder /guides wenn du auswählen möchtest wozu du Infos bekommst.`
|
2023-06-12 22:21:10 +02:00
|
|
|
|
2023-06-12 22:34:39 +02:00
|
|
|
const options: MessageCreateOptions = {
|
|
|
|
allowedMentions: { parse: ['everyone'] },
|
|
|
|
content: body
|
2023-06-12 22:21:10 +02:00
|
|
|
}
|
2023-06-12 22:34:39 +02:00
|
|
|
const message: Message<true> = await announcementChannel.send(options)
|
2023-06-13 18:18:26 +02:00
|
|
|
await message.react("🎫")
|
2023-06-13 18:58:41 +02:00
|
|
|
await message.pin()
|
2023-06-13 18:18:26 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2023-06-13 18:58:41 +02:00
|
|
|
export async function manageAnnouncementRoles(guild: Guild, reaction: MessageReaction, requestId: string) {
|
2023-06-13 18:18:26 +02:00
|
|
|
const guildId = guild.id
|
|
|
|
logger.info("Managing roles", { guildId, requestId })
|
|
|
|
|
|
|
|
const announcementRole: Role | undefined = (await guild.roles.fetch()).find(role => role.id === config.bot.announcement_role)
|
|
|
|
if (!announcementRole) {
|
|
|
|
logger.error(`Could not find announcement role! Aborting! Was looking for role with id: ${config.bot.announcement_role}`, { guildId, requestId })
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
const usersWhoWantRole: User[] = (await reaction.users.fetch()).filter(user => !user.bot).map(user => user)
|
|
|
|
|
|
|
|
const allUsers = (await guild.members.fetch())
|
|
|
|
|
|
|
|
const usersWhoHaveRole: GuildMember[] = allUsers
|
|
|
|
.filter(member=> member.roles.cache
|
|
|
|
.find(role => role.id === config.bot.announcement_role) !== undefined)
|
|
|
|
.map(member => member)
|
|
|
|
|
|
|
|
const usersWhoNeedRoleRevoked: GuildMember[] = usersWhoHaveRole
|
|
|
|
.filter(userWhoHas => !usersWhoWantRole.map(wanter => wanter.id).includes(userWhoHas.id))
|
|
|
|
|
|
|
|
const usersWhoDontHaveRole: GuildMember[] = allUsers
|
|
|
|
.filter(member => member.roles.cache
|
|
|
|
.find(role=> role.id === config.bot.announcement_role) === undefined)
|
|
|
|
.map(member => member)
|
|
|
|
|
|
|
|
const usersWhoNeedRole: GuildMember[] = usersWhoDontHaveRole
|
|
|
|
.filter(userWhoNeeds => usersWhoWantRole.map(wanter => wanter.id).includes(userWhoNeeds.id))
|
|
|
|
|
|
|
|
|
|
|
|
logger.debug(`Theses users will get the role removed: ${JSON.stringify(usersWhoNeedRoleRevoked)}`, {guildId, requestId})
|
|
|
|
logger.debug(`Theses users will get the role added: ${JSON.stringify(usersWhoNeedRole)}`, {guildId, requestId})
|
|
|
|
|
|
|
|
usersWhoNeedRoleRevoked.forEach(user => user.roles.remove(announcementRole))
|
|
|
|
usersWhoNeedRole.forEach(user => user.roles.add(announcementRole))
|
|
|
|
}
|
|
|
|
|