further handling of automatic user adding/deleting

This commit is contained in:
Sammy 2023-06-04 16:35:43 +02:00
parent 892562cd0b
commit 64c5874249
6 changed files with 72 additions and 48 deletions

View File

@ -1,5 +1,5 @@
import { Collection, GuildMember } from "discord.js" import { Collection, GuildMember } from "discord.js"
import { filterRolesFromMemberUpdate } from "../helper/roleFilter" import { filterRolesFromMemberUpdate, getGuildSpecificTriggerRoleId } from "../helper/roleFilter"
import { ChangedRoles, PermissionLevel } from "../interfaces" import { ChangedRoles, PermissionLevel } from "../interfaces"
import { jellyfinHandler } from "../.." import { jellyfinHandler } from "../.."
import { v4 as uuid } from "uuid" import { v4 as uuid } from "uuid"
@ -18,7 +18,7 @@ export async function execute(oldMember: GuildMember, newMember: GuildMember) {
} }
const removedRoleMatches = changedRoles.removedRoles.find(rRole => rRole.id === key) const removedRoleMatches = changedRoles.removedRoles.find(rRole => rRole.id === key)
if (removedRoleMatches) { if (removedRoleMatches) {
jellyfinHandler.removeUser(newMember, requestId) jellyfinHandler.removeUser(newMember, level, requestId)
} }
}) })
} catch (error) { } catch (error) {
@ -26,10 +26,5 @@ export async function execute(oldMember: GuildMember, newMember: GuildMember) {
} }
} }
function getGuildSpecificTriggerRoleId(id: string): Collection<string, PermissionLevel> {
const outVal = new Collection<string, PermissionLevel>()
outVal.set('1096819983889215659', "VIEWER")
outVal.set('1097990848613986526', "ADMIN")
return outVal
}

View File

@ -1,7 +1,8 @@
import { GuildScheduledEvent, GuildScheduledEventStatus, Collection, Snowflake, GuildScheduledEventUser} from "discord.js"; import { GuildScheduledEvent, GuildScheduledEventStatus, Collection, Snowflake, GuildScheduledEventUser } from "discord.js";
import { logger } from "../logger"; import { logger } from "../logger";
import { jellyfinHandler } from "../.." import { jellyfinHandler } from "../.."
import { v4 as uuid } from "uuid"; import { v4 as uuid } from "uuid";
import { getGuildSpecificTriggerRoleId } from "../helper/roleFilter";
export const name = 'guildScheduledEventUpdate' export const name = 'guildScheduledEventUpdate'
@ -9,32 +10,33 @@ export const name = 'guildScheduledEventUpdate'
export async function execute(oldEvent: GuildScheduledEvent, newEvent: GuildScheduledEvent) { export async function execute(oldEvent: GuildScheduledEvent, newEvent: GuildScheduledEvent) {
try { try {
logger.info(JSON.stringify(newEvent, null, 2)) logger.info(JSON.stringify(newEvent, null, 2))
const requestId = uuid()
if (newEvent.description?.includes("!WP") && [GuildScheduledEventStatus.Active, GuildScheduledEventStatus.Completed].includes(newEvent.status)) { if (newEvent.description?.includes("!WP") && [GuildScheduledEventStatus.Active, GuildScheduledEventStatus.Completed].includes(newEvent.status)) {
const members = await newEvent.fetchSubscribers({withMember: true}) const roles = getGuildSpecificTriggerRoleId(newEvent.guildId).map((key, value)=> value)
newEvent.guild?.members.fetch const members = (await newEvent.fetchSubscribers({ withMember: true })).filter(member => !member.member.roles.cache.hasAny(...roles))
if(newEvent.status === GuildScheduledEventStatus.Active) if (newEvent.status === GuildScheduledEventStatus.Active)
createJFUsers(members, newEvent.name) createJFUsers(members, newEvent.name, requestId)
else else {
deleteJFUsers(members) members.forEach(member => {
member.member.createDM().then(channel => channel.send(`Die Watchparty ist vorbei, dein Account wurde wieder gelöscht. Wenn du einen permanenten Account haben möchtest, melde dich bei Samantha oder Marukus.`))
})
deleteJFUsers(newEvent.guildId, requestId)
}
} }
} catch(error) { } catch (error) {
logger.error(error) logger.error(error)
} }
} }
async function createJFUsers(members: Collection<Snowflake, GuildScheduledEventUser<true>>, movieName: string, requestId?: string) {
async function createJFUsers(members: Collection<Snowflake, GuildScheduledEventUser<true>>, movieName: string) {
logger.info(`Creating users for: \n ${JSON.stringify(members, null, 2)}`) logger.info(`Creating users for: \n ${JSON.stringify(members, null, 2)}`)
members.forEach(member => { members.forEach(member => {
member.member.createDM().then(channel => channel.send(`Hey! Du hast dich für die Watchparty von ${movieName} angemeldet! Es geht gleich los!`)) member.member.createDM().then(channel => channel.send(`Hey! Du hast dich für die Watchparty von ${movieName} angemeldet! Es geht gleich los!`))
jellyfinHandler.upsertUser(member.member, "wird eh nicht genutzt", uuid()) jellyfinHandler.upsertUser(member.member, "TEMPORARY", requestId)
}) })
} }
async function deleteJFUsers(members: Collection<Snowflake, GuildScheduledEventUser<true>>) { async function deleteJFUsers(guildId: string, requestId?: string) {
logger.info(`Deleting users for: \n ${JSON.stringify(members, null, 2)}`) logger.info(`Watchparty ended, deleting tmp users`)
members.forEach(member => { jellyfinHandler.purge(guildId, requestId)
member.member.createDM().then(channel => channel.send(`Hey! Da die Watchparty vorbei ist, hab ich deinen Account wieder entfernt. Falls du einen permanenten Account haben möchtest frag bitte Samantha oder Marukus :)`))
jellyfinHandler.removeUser(member.member, uuid())
})
} }

View File

@ -38,7 +38,7 @@ export async function execute(oldState: VoiceState, newState: VoiceState) {
logger.info("YO! Da ist jemand dem Channel mit dem Event beigetreten, ich kümmer mich mal um nen Account!") logger.info("YO! Da ist jemand dem Channel mit dem Event beigetreten, ich kümmer mich mal um nen Account!")
newState.member.createDM().then(channel => channel.send(`Hey! Du bist unserer Watchparty beigetreten, ich leg dir mal nen Account an, damit du mitschauen kannst!`)) newState.member.createDM().then(channel => channel.send(`Hey! Du bist unserer Watchparty beigetreten, ich leg dir mal nen Account an, damit du mitschauen kannst!`))
jellyfinHandler.upsertUser(newState.member, "wird eh nicht genutzt", uuid()) jellyfinHandler.upsertUser(newState.member, "TEMPORARY", uuid())
} else { } else {
logger.error("WTF? Expected Member?? When doing things") logger.error("WTF? Expected Member?? When doing things")
} }

View File

@ -1,5 +1,5 @@
import { GuildMember } from "discord.js" import { Collection, GuildMember } from "discord.js"
import { ChangedRoles } from "../interfaces" import { ChangedRoles, PermissionLevel } from "../interfaces"
import { logger } from "../logger" import { logger } from "../logger"
export function filterRolesFromMemberUpdate(oldMember: GuildMember, newMember: GuildMember): ChangedRoles { export function filterRolesFromMemberUpdate(oldMember: GuildMember, newMember: GuildMember): ChangedRoles {
@ -14,3 +14,10 @@ export function filterRolesFromMemberUpdate(oldMember: GuildMember, newMember: G
return { addedRoles, removedRoles } return { addedRoles, removedRoles }
} }
export function getGuildSpecificTriggerRoleId(guildId: string): Collection<string, PermissionLevel> {
const outVal = new Collection<string, PermissionLevel>()
outVal.set('1096819983889215659', "VIEWER")
outVal.set('1097990848613986526', "ADMIN")
return outVal
}

View File

@ -32,4 +32,4 @@ export interface ChangedRoles {
addedRoles: Collection<string, Role> addedRoles: Collection<string, Role>
removedRoles: Collection<string, Role> removedRoles: Collection<string, Role>
} }
export type PermissionLevel = "VIEWER" | "ADMIN" export type PermissionLevel = "VIEWER" | "ADMIN" | "TEMPORARY"

View File

@ -1,11 +1,11 @@
import { GuildMember } from "discord.js"; import { GuildMember } from "discord.js";
import { CreateUserByNameOperationRequest, SystemApi, UpdateUserPasswordOperationRequest, UpdateUserPolicyOperationRequest, UserApi } from "./apis"; import { CreateUserByNameOperationRequest, DeleteUserRequest, SystemApi, UpdateUserPasswordOperationRequest, UpdateUserPolicyOperationRequest, UserApi } from "./apis";
import { UserDto } from "./models/UserDto"; import { UserDto } from "./models/UserDto";
import { Configuration, ConfigurationParameters } from "./runtime"; import { Configuration, ConfigurationParameters } from "./runtime";
import { CreateUserByNameRequest, UpdateUserEasyPasswordRequest, UpdateUserPasswordRequest, UpdateUserPolicyRequest } from "./models"; import { CreateUserByNameRequest, UpdateUserEasyPasswordRequest, UpdateUserPasswordRequest, UpdateUserPolicyRequest } from "./models";
import { Config } from "../configuration"; import { Config } from "../configuration";
import { logger } from "../logger"; import { logger } from "../logger";
import { Maybe } from "../interfaces"; import { Maybe, PermissionLevel } from "../interfaces";
import { v4 as uuid } from "uuid"; import { v4 as uuid } from "uuid";
@ -46,8 +46,8 @@ export class JellyfinHandler {
logger.info(`Initialized Jellyfin handler`, { requestId: 'Init' }) logger.info(`Initialized Jellyfin handler`, { requestId: 'Init' })
} }
private generateJFUserName(discordUser: GuildMember): string { private generateJFUserName(discordUser: GuildMember, level: PermissionLevel): string {
return discordUser.displayName return `${discordUser.displayName}${level == "TEMPORARY" ? "_tmp" : ""}`
} }
public async addPermissionsToUserAccount(jfUserAccount: UserDto, guildId: string, requestId: string): Promise<UserDto> { public async addPermissionsToUserAccount(jfUserAccount: UserDto, guildId: string, requestId: string): Promise<UserDto> {
@ -58,8 +58,8 @@ export class JellyfinHandler {
return (Math.random() * 10000 + 10000).toFixed(0) return (Math.random() * 10000 + 10000).toFixed(0)
} }
public async createUserAccountForDiscordUser(discordUser: GuildMember, guildId?: string, requestId?: string): Promise<UserDto> { public async createUserAccountForDiscordUser(discordUser: GuildMember, level: PermissionLevel, guildId?: string, requestId?: string): Promise<UserDto> {
const newUserName = this.generateJFUserName(discordUser) const newUserName = this.generateJFUserName(discordUser, level)
logger.info(`New Username for ${discordUser.displayName}: ${newUserName}`, { guildId, requestId }) logger.info(`New Username for ${discordUser.displayName}: ${newUserName}`, { guildId, requestId })
const req: CreateUserByNameOperationRequest = { const req: CreateUserByNameOperationRequest = {
createUserByNameRequest: { createUserByNameRequest: {
@ -94,23 +94,43 @@ export class JellyfinHandler {
} }
public async getUser(discordUser: GuildMember, requestId?: string): Promise<Maybe<UserDto>> { public async getUser(discordUser: GuildMember, requestId?: string): Promise<Maybe<UserDto>> {
logger.info(`Getting user for discord member ${discordUser.displayName}`, {requestId}) logger.info(`Getting user for discord member ${discordUser.displayName}`, { requestId })
const jfUsernameFromDiscordUsername = this.generateJFUserName(discordUser)
const jfUsers = await this.getCurrentUsers(discordUser.guild.id, requestId) const jfUsers = await this.getCurrentUsers(discordUser.guild.id, requestId)
const foundUser = jfUsers.find(x => x.name === jfUsernameFromDiscordUsername) const foundUser = jfUsers.find(x => x.name?.includes(discordUser.displayName))
return foundUser return foundUser
} }
public async removeUser(newMember: GuildMember, requestId?: string) { public async removeUser(newMember: GuildMember, level: PermissionLevel, requestId?: string) {
logger.error(`Trying to remove user ${newMember.displayName}, but method is not implemented`, {requestId}) logger.info(`${level == "TEMPORARY" ? "Deleting" : "Disabling" } user ${newMember.displayName}, but method is not implemented`, { requestId })
const jfuser = await this.getUser(newMember, requestId) const jfuser = await this.getUser(newMember, requestId)
if (jfuser) { if (jfuser && jfuser.id) {
await this.disableUser(jfuser, newMember.guild.id, requestId) if (level === "TEMPORARY") {
const r: DeleteUserRequest = {
userId: jfuser.id
}
this.userApi.deleteUser(r)
}
else
await this.disableUser(jfuser, newMember.guild.id, requestId)
} }
} }
public async purge(guildId: string, requestId?: string) {
logger.info("Deleting tmp users")
const users = (await this.userApi.getUsers()).filter(user => user.name?.endsWith("_tmp"))
users.forEach(user => {
if(user.id) {
const r: DeleteUserRequest = {
userId: user.id
}
this.userApi.deleteUser(r)
}
})
}
public async resetUserPasswort(member: GuildMember, requestId?: string) { public async resetUserPasswort(member: GuildMember, requestId?: string) {
logger.info(`Resetting password for user ${member.displayName}`, {requestId}) logger.info(`Resetting password for user ${member.displayName}`, { requestId })
const jfUser = await this.getUser(member, requestId) const jfUser = await this.getUser(member, requestId)
if (jfUser && jfUser.id) { if (jfUser && jfUser.id) {
@ -140,7 +160,7 @@ export class JellyfinHandler {
userId: jfUser.id userId: jfUser.id
} }
logger.info("Setting new password", {requestId}) logger.info("Setting new password", { requestId })
await this.userApi.updateUserPassword(passwordOperationRequest); await this.userApi.updateUserPassword(passwordOperationRequest);
@ -190,14 +210,14 @@ export class JellyfinHandler {
} }
} }
public async upsertUser(newMember: GuildMember, level: string, requestId?: string) { public async upsertUser(newMember: GuildMember, level: PermissionLevel, requestId?: string) {
logger.error(`Trying to upsert user ${newMember.displayName}, with permissionLevel ${level}`) logger.error(`Trying to upsert user ${newMember.displayName}, with permissionLevel ${level}`)
const jfuser = await this.getUser(newMember, requestId) const jfuser = await this.getUser(newMember, requestId)
if (jfuser) { if (jfuser) {
logger.info(`User with name ${newMember.displayName} is already present`) logger.info(`User with name ${newMember.displayName} is already present`)
await this.enableUser(jfuser, newMember.guild.id, requestId) await this.enableUser(jfuser, newMember.guild.id, requestId)
} else { } else {
this.createUserAccountForDiscordUser(newMember, newMember.guild.id, requestId) this.createUserAccountForDiscordUser(newMember, level, newMember.guild.id, requestId)
} }
} }
} }