Compare commits
6 Commits
b8a32aab40
...
d9d1d74ef9
Author | SHA1 | Date | |
---|---|---|---|
d9d1d74ef9 | |||
331ff89060 | |||
f6476c609b | |||
6220268b14 | |||
b6034d4fb7 | |||
ca0a9e3cb8 |
@ -6,6 +6,7 @@ import { Maybe } from '../interfaces'
|
||||
import { logger } from '../logger'
|
||||
import { Command } from '../structures/command'
|
||||
import { RunOptions } from '../types/commandTypes'
|
||||
import { messageIsInitialAnnouncement } from '../helper/messageIdentifiers'
|
||||
|
||||
export default new Command({
|
||||
name: 'announce',
|
||||
@ -61,7 +62,7 @@ async function sendInitialAnnouncement(guildId: string, requestId: string): Prom
|
||||
return
|
||||
}
|
||||
|
||||
const currentPinnedAnnouncementMessages = (await announcementChannel.messages.fetchPinned()).filter(message => message.cleanContent.includes("[initial]"))
|
||||
const currentPinnedAnnouncementMessages = (await announcementChannel.messages.fetchPinned()).filter(message => messageIsInitialAnnouncement(message))
|
||||
currentPinnedAnnouncementMessages.forEach(async (message) => await message.unpin())
|
||||
currentPinnedAnnouncementMessages.forEach(message => message.delete())
|
||||
|
||||
|
@ -3,11 +3,12 @@ import { Guild, GuildScheduledEvent, GuildScheduledEventEditOptions, GuildSchedu
|
||||
import { v4 as uuid } from 'uuid'
|
||||
import { client } from '../..'
|
||||
import { config } from '../configuration'
|
||||
import { Emotes } from '../events/autoCreateVoteByWPEvent'
|
||||
import { Maybe } from '../interfaces'
|
||||
import { logger } from '../logger'
|
||||
import { Command } from '../structures/command'
|
||||
import { RunOptions } from '../types/commandTypes'
|
||||
import { messageIsVoteEndedMessage, messageIsVoteMessage } from '../helper/messageIdentifiers'
|
||||
import { Emotes } from '../constants'
|
||||
|
||||
export default new Command({
|
||||
name: 'closepoll',
|
||||
@ -41,7 +42,7 @@ export async function closePoll(guild: Guild, requestId: string) {
|
||||
|
||||
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]"))
|
||||
.filter(message => !messageIsVoteEndedMessage(message) && messageIsVoteMessage(message))
|
||||
.sort((a, b) => b.createdTimestamp - a.createdTimestamp)
|
||||
|
||||
if (!messages || messages.length <= 0) {
|
||||
|
3
server/constants.ts
Normal file
3
server/constants.ts
Normal file
@ -0,0 +1,3 @@
|
||||
|
||||
export enum Emotes { "1️⃣", "2️⃣", "3️⃣", "4️⃣", "5️⃣", "6️⃣", "7️⃣", "8️⃣", "9️⃣", "🔟" }
|
||||
export const NONE_OF_THAT = "❌"
|
@ -6,14 +6,12 @@ import { config } from "../configuration";
|
||||
import { createDateStringFromEvent } from "../helper/dateHelper";
|
||||
import { Maybe } from "../interfaces";
|
||||
import { logger } from "../logger";
|
||||
import { Emotes, NONE_OF_THAT } from "../constants";
|
||||
|
||||
|
||||
export const name = 'guildScheduledEventCreate'
|
||||
|
||||
export enum Emotes { "1️⃣", "2️⃣", "3️⃣", "4️⃣", "5️⃣", "6️⃣", "7️⃣", "8️⃣", "9️⃣", "🔟" }
|
||||
export const NONE_OF_THAT = "❌"
|
||||
|
||||
export let task: ScheduledTask | undefined
|
||||
|
||||
export async function execute(event: GuildScheduledEvent) {
|
||||
const requestId = uuid()
|
||||
|
@ -2,6 +2,7 @@ import { Collection, GuildScheduledEvent, GuildScheduledEventStatus, Message } f
|
||||
import { v4 as uuid } from "uuid";
|
||||
import { client } from "../..";
|
||||
import { logger } from "../logger";
|
||||
import { messageIsInitialAnnouncement } from "../helper/messageIdentifiers";
|
||||
|
||||
|
||||
export const name = 'guildScheduledEventUpdate'
|
||||
@ -25,7 +26,7 @@ export async function execute(oldEvent: GuildScheduledEvent, newEvent: GuildSche
|
||||
|
||||
const events = await newEvent.guild.scheduledEvents.fetch()
|
||||
|
||||
const wpAnnouncements = (await announcementChannel.messages.fetch()).filter(message => !message.cleanContent.includes("[initial]"))
|
||||
const wpAnnouncements = (await announcementChannel.messages.fetch()).filter(message => !messageIsInitialAnnouncement(message))
|
||||
const announcementsWithoutEvent = filterAnnouncementsByPendingWPs(wpAnnouncements, events)
|
||||
logger.info(`Deleting ${announcementsWithoutEvent.length} announcements.`, { guildId, requestId })
|
||||
announcementsWithoutEvent.forEach(message => message.delete())
|
||||
|
@ -2,18 +2,43 @@
|
||||
import { Message, MessageReaction, User } from "discord.js";
|
||||
import { messageIsVoteMessage } from "../helper/messageIdentifiers";
|
||||
import { logger, newRequestId, noGuildId } from "../logger";
|
||||
import { NONE_OF_THAT } from "../constants";
|
||||
import { client } from "../..";
|
||||
import { getMembersWithRoleFromGuild } from "../helper/roleFilter";
|
||||
import { config } from "../configuration";
|
||||
|
||||
|
||||
export const name = 'messageReactionAdd'
|
||||
|
||||
export async function execute(messageReaction: MessageReaction, user: User) {
|
||||
if (user.id == client.user?.id)
|
||||
logger.info('Skipping bot reaction')
|
||||
|
||||
const requestId = newRequestId
|
||||
const guildId = messageReaction.message.inGuild() ? messageReaction.message.guildId : noGuildId
|
||||
|
||||
const reactedUponMessage: Message = messageReaction.message.partial ? await messageReaction.message.fetch() : messageReaction.message
|
||||
if (!messageReaction.message.guild) return 'No guild'
|
||||
|
||||
logger.info(`Got reaction on message`, { requestId, guildId })
|
||||
logger.debug(`reactedUponMessage payload: ${JSON.stringify(reactedUponMessage)}`)
|
||||
|
||||
if (messageIsVoteMessage(reactedUponMessage)) {
|
||||
logger.info(`Got reaction on message`, { requestId, guildId })
|
||||
logger.debug(`${reactedUponMessage.id} is vote message`, { requestId, guildId })
|
||||
if (messageReaction.message.reactions.cache.find(reaction => reaction.emoji.toString() == NONE_OF_THAT)) {
|
||||
const watcherRoleMember = await getMembersWithRoleFromGuild(config.bot.announcement_role, messageReaction.message.guild)
|
||||
logger.info("ROLE MEMBERS " + JSON.stringify(watcherRoleMember), { requestId, guildId })
|
||||
const watcherRoleMemberCount = watcherRoleMember.size
|
||||
logger.info(`MEMBER COUNT: ${watcherRoleMemberCount}`, { requestId, guildId })
|
||||
let noneOfThatReactions = messageReaction.message.reactions.cache.get(NONE_OF_THAT)?.users.cache.filter(x => x.id !== client.user?.id).size ?? 0
|
||||
|
||||
const memberThreshold = (watcherRoleMemberCount / 2)
|
||||
logger.info(`Reroll ${noneOfThatReactions} > ${memberThreshold} ?`, { requestId, guildId })
|
||||
if (noneOfThatReactions > memberThreshold) {
|
||||
logger.info('Starting poll reroll', { requestId, guildId })
|
||||
messageReaction.message.edit((messageReaction.message.content ?? "").concat('\nDiese Abstimmung muss wiederholt werden.'))
|
||||
}
|
||||
logger.info(`No reroll`, { requestId, guildId })
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
|
@ -1,6 +1,11 @@
|
||||
import { Message } from "discord.js";
|
||||
|
||||
export function messageIsVoteMessage(msg: Message): boolean {
|
||||
return msg.content.includes('[Abstimmung]')
|
||||
|
||||
return msg.cleanContent.includes('[Abstimmung]')
|
||||
}
|
||||
export function messageIsInitialAnnouncement(msg: Message): boolean {
|
||||
return msg.cleanContent.includes("[initial]")
|
||||
}
|
||||
export function messageIsVoteEndedMessage(msg: Message): boolean {
|
||||
return msg.cleanContent.includes("[Abstimmung beendet]")
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Collection, GuildMember } from "discord.js"
|
||||
import { ChangedRoles, PermissionLevel } from "../interfaces"
|
||||
import { Collection, Guild, GuildMember, Role, User } from "discord.js"
|
||||
import { ChangedRoles, Maybe, PermissionLevel } from "../interfaces"
|
||||
import { logger } from "../logger"
|
||||
import { config } from "../configuration"
|
||||
|
||||
@ -16,6 +16,13 @@ export function filterRolesFromMemberUpdate(oldMember: GuildMember, newMember: G
|
||||
return { addedRoles, removedRoles }
|
||||
}
|
||||
|
||||
export async function getMembersWithRoleFromGuild(roleId: string, guild: Guild): Promise<Collection<string, GuildMember>> {
|
||||
const emptyResponse = new Collection<string, GuildMember>
|
||||
const guildRole: Maybe<Role> = guild.roles.resolve(roleId)
|
||||
if (!guildRole) return emptyResponse
|
||||
return guildRole.members
|
||||
}
|
||||
|
||||
export function getGuildSpecificTriggerRoleId(): Collection<string, PermissionLevel> {
|
||||
const outVal = new Collection<string, PermissionLevel>()
|
||||
outVal.set(config.bot.watcher_role, "VIEWER")
|
||||
|
@ -9,6 +9,7 @@ import { JellyfinHandler } from "../jellyfin/handler";
|
||||
import { logger } from "../logger";
|
||||
import { CommandType } from "../types/commandTypes";
|
||||
import { checkForPollsToClose } from "../commands/closepoll";
|
||||
import { messageIsInitialAnnouncement } from "../helper/messageIdentifiers";
|
||||
|
||||
|
||||
|
||||
@ -22,7 +23,7 @@ export class ExtendedClient extends Client {
|
||||
private pollCloseBackgroundTasks: Collection<string, ScheduledTask> = new Collection()
|
||||
public constructor(jf: JellyfinHandler) {
|
||||
const intents: IntentsBitField = new IntentsBitField()
|
||||
intents.add(IntentsBitField.Flags.GuildMembers, IntentsBitField.Flags.MessageContent, IntentsBitField.Flags.Guilds, IntentsBitField.Flags.DirectMessages, IntentsBitField.Flags.GuildScheduledEvents, IntentsBitField.Flags.GuildVoiceStates)
|
||||
intents.add(IntentsBitField.Flags.GuildMembers, IntentsBitField.Flags.MessageContent, IntentsBitField.Flags.Guilds, IntentsBitField.Flags.DirectMessages, IntentsBitField.Flags.GuildScheduledEvents, IntentsBitField.Flags.GuildMessageReactions, IntentsBitField.Flags.GuildVoiceStates)
|
||||
const options: ClientOptions = { intents }
|
||||
super(options)
|
||||
this.jellyfin = jf
|
||||
@ -74,6 +75,7 @@ export class ExtendedClient extends Client {
|
||||
this.registerCommands(slashCommands, guilds)
|
||||
this.cacheUsers(guilds)
|
||||
await this.cacheAnnouncementServer(guilds)
|
||||
this.fetchAnnouncementChannelMessage(this.announcementChannels)
|
||||
this.startAnnouncementRoleBackgroundTask(guilds)
|
||||
this.startPollCloseBackgroundTasks()
|
||||
})
|
||||
@ -81,6 +83,11 @@ export class ExtendedClient extends Client {
|
||||
logger.info(`Error refreshing slash commands: ${error}`)
|
||||
}
|
||||
}
|
||||
private async fetchAnnouncementChannelMessage(channels: Collection<string, TextChannel>): Promise<void> {
|
||||
channels.each(async ch => {
|
||||
ch.messages.fetch()
|
||||
})
|
||||
}
|
||||
private async cacheAnnouncementServer(guilds: Collection<Snowflake, Guild>) {
|
||||
for (const guild of guilds.values()) {
|
||||
const channels: TextChannel[] = <TextChannel[]>(await guild.channels.fetch())
|
||||
@ -136,7 +143,7 @@ export class ExtendedClient extends Client {
|
||||
}
|
||||
this.announcementRoleHandlerTask.set(guild.id, schedule("*/10 * * * * *", async () => {
|
||||
const requestId = uuid()
|
||||
const messages = (await textChannel.messages.fetchPinned()).filter(message => message.cleanContent.includes("[initial]"))
|
||||
const messages = (await textChannel.messages.fetchPinned()).filter(message => messageIsInitialAnnouncement(message))
|
||||
|
||||
if (messages.size > 1) {
|
||||
logger.error("More than one pinned announcement Messages found. Unable to know which one people react to. Please fix!", { guildId: guild.id, requestId })
|
||||
|
Loading…
Reference in New Issue
Block a user