21 Commits

Author SHA1 Message Date
e52e845851 1.1.3
All checks were successful
Build a docker image for node-jellyfin-role-bot / build-docker-image (push) Successful in 1m59s
2023-06-23 23:46:52 +02:00
61544feaba Fix stupid timezone issues 2023-06-23 23:46:11 +02:00
1966640239 Merge branch 'master' of ssh://gitea.brudi.xyz:222/kenobi/jellyfin-discord-bot 2023-06-23 21:24:32 +02:00
fa9998e92c Unallow transcoding per default for new users 2023-06-23 21:23:54 +02:00
c1a449bafe 1.1.2
All checks were successful
Build a docker image for node-jellyfin-role-bot / build-docker-image (push) Successful in 1m50s
2023-06-23 19:46:20 +02:00
d5d82043f0 temporarily remove second tag on docker build 2023-06-23 19:46:06 +02:00
51ebf2e939 1.1.1
All checks were successful
Build a docker image for node-jellyfin-role-bot / build-docker-image (push) Successful in 12s
2023-06-23 19:44:58 +02:00
f314b2f355 maybe fix a docker build typo 2023-06-23 19:44:44 +02:00
a4d7c57d10 1.1.0
All checks were successful
Build a docker image for node-jellyfin-role-bot / build-docker-image (push) Successful in 14s
2023-06-23 19:33:31 +02:00
2802afa7d5 Merge pull request 'feat/#42_announce_manual_watchparty' (#50) from feat/#42_announce_manual_watchparty into master
Reviewed-on: #50
2023-06-23 19:31:57 +02:00
3a5ea5d4ff improve message clarity when no start date in event found
All checks were successful
Compile the repository / compile (pull_request) Successful in 4m8s
2023-06-23 19:30:17 +02:00
45d87275bf prevent announcement when description contains !private
All checks were successful
Compile the repository / compile (pull_request) Successful in 1m43s
2023-06-23 15:56:36 +02:00
31e440434e properly clean up wp announcements without event only 2023-06-23 15:51:48 +02:00
3d70b56eb7 Merge pull request 'feat/#43_append_event_invite' (#49) from feat/#43_append_event_invite into master
Reviewed-on: #49
2023-06-23 15:49:59 +02:00
3298c7a244 Merge pull request 'Create option "none of that" in voting' (#48) from feat/#39_none_of_that into master
Reviewed-on: #48
2023-06-23 15:49:43 +02:00
5b98c9bf2f Rename event files to specific case
We can add multiple eventhandlers per eventname. To avoid confusion and large files and to improve concise file names the event files were renamed
2023-06-23 14:37:41 +02:00
ee363e065c 1.0.4
All checks were successful
Build a docker image for node-jellyfin-role-bot / build-docker-image (push) Successful in 47s
2023-06-22 23:23:56 +02:00
9af847f234 Fix docker-build for good 2023-06-22 23:23:38 +02:00
9da8f47784 add event box to vote closed message
All checks were successful
Compile the repository / compile (pull_request) Successful in 1m18s
2023-06-22 19:38:59 +02:00
e8c58d5ff8 add event box to create message 2023-06-22 19:35:47 +02:00
8569a3e1e6 Create option "none of that" in voting
All checks were successful
Compile the repository / compile (pull_request) Successful in 1m19s
2023-06-22 18:53:29 +02:00
12 changed files with 181 additions and 26 deletions

View File

@ -22,6 +22,6 @@ jobs:
- name: Log in to the Container registry - name: Log in to the Container registry
run: docker login -u ${{ env.USER }} -p ${{ secrets.TOKEN }} ${{ env.REGISTRY }} run: docker login -u ${{ env.USER }} -p ${{ secrets.TOKEN }} ${{ env.REGISTRY }}
- name: Build Container - name: Build Container
run: docker build -t "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest" -t "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ node -p "require('./package.json').version" }}". run: docker build -t "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest" .
- name: Push Container - name: Push Container
run: docker push --all-tags "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest" run: docker push --all-tags "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}"

19
package-lock.json generated
View File

@ -1,12 +1,12 @@
{ {
"name": "node-jellyfin-discord-bot", "name": "node-jellyfin-discord-bot",
"version": "1.0.3", "version": "1.1.3",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "node-jellyfin-discord-bot", "name": "node-jellyfin-discord-bot",
"version": "1.0.3", "version": "1.1.3",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@discordjs/rest": "^1.7.0", "@discordjs/rest": "^1.7.0",
@ -17,6 +17,7 @@
"@types/uuid": "^9.0.1", "@types/uuid": "^9.0.1",
"axios": "^1.3.5", "axios": "^1.3.5",
"date-fns": "^2.29.3", "date-fns": "^2.29.3",
"date-fns-tz": "^2.0.0",
"discord-api-types": "^0.37.38", "discord-api-types": "^0.37.38",
"discord.js": "^14.9.0", "discord.js": "^14.9.0",
"dotenv": "^16.0.3", "dotenv": "^16.0.3",
@ -2626,6 +2627,14 @@
"url": "https://opencollective.com/date-fns" "url": "https://opencollective.com/date-fns"
} }
}, },
"node_modules/date-fns-tz": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/date-fns-tz/-/date-fns-tz-2.0.0.tgz",
"integrity": "sha512-OAtcLdB9vxSXTWHdT8b398ARImVwQMyjfYGkKD2zaGpHseG2UPHbHjXELReErZFxWdSLph3c2zOaaTyHfOhERQ==",
"peerDependencies": {
"date-fns": ">=2.0.0"
}
},
"node_modules/debug": { "node_modules/debug": {
"version": "4.3.4", "version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@ -8905,6 +8914,12 @@
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.29.3.tgz", "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.29.3.tgz",
"integrity": "sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==" "integrity": "sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA=="
}, },
"date-fns-tz": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/date-fns-tz/-/date-fns-tz-2.0.0.tgz",
"integrity": "sha512-OAtcLdB9vxSXTWHdT8b398ARImVwQMyjfYGkKD2zaGpHseG2UPHbHjXELReErZFxWdSLph3c2zOaaTyHfOhERQ==",
"requires": {}
},
"debug": { "debug": {
"version": "4.3.4", "version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",

View File

@ -1,6 +1,6 @@
{ {
"name": "node-jellyfin-discord-bot", "name": "node-jellyfin-discord-bot",
"version": "1.0.3", "version": "1.1.3",
"description": "A discord bot to sync jellyfin accounts with discord roles", "description": "A discord bot to sync jellyfin accounts with discord roles",
"main": "index.js", "main": "index.js",
"license": "MIT", "license": "MIT",
@ -13,6 +13,7 @@
"@types/uuid": "^9.0.1", "@types/uuid": "^9.0.1",
"axios": "^1.3.5", "axios": "^1.3.5",
"date-fns": "^2.29.3", "date-fns": "^2.29.3",
"date-fns-tz": "^2.0.0",
"discord-api-types": "^0.37.38", "discord-api-types": "^0.37.38",
"discord.js": "^14.9.0", "discord.js": "^14.9.0",
"dotenv": "^16.0.3", "dotenv": "^16.0.3",

View File

@ -3,7 +3,7 @@ import { Guild, GuildScheduledEvent, GuildScheduledEventEditOptions, GuildSchedu
import { v4 as uuid } from 'uuid' import { v4 as uuid } from 'uuid'
import { client } from '../..' import { client } from '../..'
import { config } from '../configuration' import { config } from '../configuration'
import { Emotes } from '../events/guildScheduledEventCreate' import { Emotes } from '../events/autoCreateVoteByWPEvent'
import { Maybe } from '../interfaces' import { Maybe } from '../interfaces'
import { logger } from '../logger' import { logger } from '../logger'
import { Command } from '../structures/command' import { Command } from '../structures/command'
@ -75,7 +75,7 @@ export async function closePoll(guild: Guild, requestId: string) {
async function sendVoteClosedMessage(event: GuildScheduledEvent, movie: string, guildId: string, requestId: string) { async function sendVoteClosedMessage(event: GuildScheduledEvent, movie: string, guildId: string, requestId: string) {
const date = event.scheduledStartAt ? format(event.scheduledStartAt, "dd.MM") : "Fehler, event hatte kein Datum" const date = event.scheduledStartAt ? format(event.scheduledStartAt, "dd.MM") : "Fehler, event hatte kein Datum"
const time = event.scheduledStartAt ? format(event.scheduledStartAt, "HH:mm") : "Fehler, event hatte kein Datum" const time = event.scheduledStartAt ? format(event.scheduledStartAt, "HH:mm") : "Fehler, event hatte kein Datum"
const body = `[Abstimmung beendet] <@&${config.bot.announcement_role}> Wir gucken ${movie} am ${date} um ${time}` const body = `[Abstimmung beendet] für https://discord.com/events/${event.guildId}/${event.id}\n<@&${config.bot.announcement_role}> Wir gucken ${movie} am ${date} um ${time}`
const options: MessageCreateOptions = { const options: MessageCreateOptions = {
content: body, content: body,
allowedMentions: { parse: ["roles"] } allowedMentions: { parse: ["roles"] }

View File

@ -0,0 +1,48 @@
import { GuildScheduledEvent, TextChannel } from "discord.js";
import { v4 as uuid } from "uuid";
import { client } from "../..";
import { config } from "../configuration";
import { createDateStringFromEvent } from "../helper/dateHelper";
import { Maybe } from "../interfaces";
import { logger } from "../logger";
export const name = 'guildScheduledEventCreate'
export async function execute(event: GuildScheduledEvent) {
const guildId = event.guildId
const requestId = uuid()
try {
if (!event.description) {
logger.debug("Got GuildScheduledEventCreate event. But has no description. Aborting.")
return
}
if (event.description.includes("!wp")) {
logger.info("Got manual create event of watchparty event!", { guildId, requestId })
if(event.description.includes("!private")) {
logger.info("Event description contains \"!private\". Won't announce.", { guildId, requestId })
return
}
const channel: Maybe<TextChannel> = client.getAnnouncementChannelForGuild(guildId)
if (!channel) {
logger.error("Could not obtain announcement channel. Aborting announcement.", { guildId, requestId })
return
}
const message = `[Watchparty] https://discord.com/events/${event.guildId}/${event.id} \nHey <@&${config.bot.announcement_role}>, wir gucken ${event.name} ${createDateStringFromEvent(event, guildId, requestId)}`
channel.send(message)
} else {
logger.debug("Got GuildScheduledEventCreate event but no !wp in description. Not creating manual wp announcement.", { guildId, requestId })
}
} catch (error) {
// sendFailureDM(error)
logger.error(<string>error, { guildId, requestId })
}
}

View File

@ -1,9 +1,9 @@
import { format } from "date-fns";
import { GuildScheduledEvent, Message, MessageCreateOptions, TextChannel } from "discord.js"; import { GuildScheduledEvent, Message, MessageCreateOptions, TextChannel } from "discord.js";
import { ScheduledTask } from "node-cron"; import { ScheduledTask } from "node-cron";
import { v4 as uuid } from "uuid"; import { v4 as uuid } from "uuid";
import { client, yavinJellyfinHandler } from "../.."; import { client, yavinJellyfinHandler } from "../..";
import { config } from "../configuration"; import { config } from "../configuration";
import { createDateStringFromEvent } from "../helper/dateHelper";
import { Maybe } from "../interfaces"; import { Maybe } from "../interfaces";
import { logger } from "../logger"; import { logger } from "../logger";
@ -11,13 +11,13 @@ import { logger } from "../logger";
export const name = 'guildScheduledEventCreate' export const name = 'guildScheduledEventCreate'
export enum Emotes { "1⃣", "2⃣", "3⃣", "4⃣", "5⃣", "6⃣", "7⃣", "8⃣", "9⃣", "🔟" } export enum Emotes { "1⃣", "2⃣", "3⃣", "4⃣", "5⃣", "6⃣", "7⃣", "8⃣", "9⃣", "🔟" }
export const NONE_OF_THAT = "❌"
export let task: ScheduledTask | undefined export let task: ScheduledTask | undefined
export async function execute(event: GuildScheduledEvent) { export async function execute(event: GuildScheduledEvent) {
const requestId = uuid() const requestId = uuid()
logger.debug(`New event created: ${JSON.stringify(event, null, 2)}`, { guildId: event.guildId, requestId })
if (event.name.toLowerCase().includes("!nextwp")) { if (event.name.toLowerCase().includes("!nextwp")) {
logger.info("Event was a placeholder event to start a new watchparty and voting. Creating vote!", { guildId: event.guildId, requestId }) logger.info("Event was a placeholder event to start a new watchparty and voting. Creating vote!", { guildId: event.guildId, requestId })
logger.debug("Renaming event", { guildId: event.guildId, requestId }) logger.debug("Renaming event", { guildId: event.guildId, requestId })
@ -38,17 +38,16 @@ export async function execute(event: GuildScheduledEvent) {
logger.info("EVENT DOES NOT HAVE STARTDATE; CANCELLING", {guildId: event.guildId, requestId}) logger.info("EVENT DOES NOT HAVE STARTDATE; CANCELLING", {guildId: event.guildId, requestId})
return return
} }
const date = format(event.scheduledStartAt, "dd.MM") let message = `[Abstimmung] für https://discord.com/events/${event.guildId}/${event.id}\n<@&${config.bot.announcement_role}> Es gibt eine neue Abstimmung für die nächste Watchparty ${createDateStringFromEvent(event, event.guildId, requestId)}! Stimme hierunter für den nächsten Film ab!\n`
const time = format(event.scheduledStartAt, "HH:mm")
let message = `[Abstimmung]\n<@&${config.bot.announcement_role}> Es gibt eine neue Abstimmung für die nächste Watchparty am ${date} um ${time}}! Stimme hierunter für den nächsten Film ab!\n`
for (let i = 0; i < movies.length; i++) { for (let i = 0; i < movies.length; i++) {
message = message.concat(Emotes[i]).concat(": ").concat(movies[i]).concat("\n") message = message.concat(Emotes[i]).concat(": ").concat(movies[i]).concat("\n")
} }
message = message.concat(NONE_OF_THAT).concat(": Wenn dir nichts davon gefällt.")
const options: MessageCreateOptions = { const options: MessageCreateOptions = {
allowedMentions: { parse: ["roles"]}, allowedMentions: { parse: ["roles"]},
content: message content: message,
} }
const sentMessage: Message<true> = await (await announcementChannel.fetch()).send(options) const sentMessage: Message<true> = await (await announcementChannel.fetch()).send(options)
@ -56,6 +55,7 @@ export async function execute(event: GuildScheduledEvent) {
for (let i = 0; i < movies.length; i++) { for (let i = 0; i < movies.length; i++) {
sentMessage.react(Emotes[i]) sentMessage.react(Emotes[i])
} }
sentMessage.react(NONE_OF_THAT)
// sentMessage.pin() //todo: uncomment when bot has permission to pin messages. Also update closepoll.ts to only fetch pinned messages // sentMessage.pin() //todo: uncomment when bot has permission to pin messages. Also update closepoll.ts to only fetch pinned messages
} }

View File

@ -0,0 +1,52 @@
import { Collection, GuildScheduledEvent, GuildScheduledEventStatus, Message } from "discord.js";
import { v4 as uuid } from "uuid";
import { client } from "../..";
import { logger } from "../logger";
export const name = 'guildScheduledEventUpdate'
export async function execute(oldEvent: GuildScheduledEvent, newEvent: GuildScheduledEvent) {
const requestId = uuid()
try {
if (!newEvent.guild) {
logger.error("Event has no guild, aborting.", { guildId: newEvent.guildId, requestId })
return
}
const guildId = newEvent.guildId
if (newEvent.description?.toLowerCase().includes("!wp") && newEvent.status === GuildScheduledEventStatus.Completed) {
logger.info("A watchparty ended. Cleaning up announcements!", { guildId, requestId })
const announcementChannel = client.getAnnouncementChannelForGuild(newEvent.guild.id)
if (!announcementChannel) {
logger.error("Could not find announcement channel. Aborting", { guildId: newEvent.guild.id, requestId })
return
}
const events = await newEvent.guild.scheduledEvents.fetch()
const wpAnnouncements = (await announcementChannel.messages.fetch()).filter(message => !message.cleanContent.includes("[initial]"))
const announcementsWithoutEvent = filterAnnouncementsByPendingWPs(wpAnnouncements, events)
logger.info(`Deleting ${announcementsWithoutEvent.length} announcements.`, {guildId, requestId})
announcementsWithoutEvent.forEach(message => message.delete())
}
} catch (error) {
logger.error(<string>error, { guildId: newEvent.guildId, requestId })
}
}
function filterAnnouncementsByPendingWPs(messages: Collection<string, Message<true>>, events: Collection<string, GuildScheduledEvent<GuildScheduledEventStatus>>): Message<true>[] {
const filteredMessages: Message<true>[] = []
for (const message of messages.values()) {
let foundEventForMessage = false
for (const event of events.values()) {
if (message.cleanContent.includes(event.id)) { //announcement always has eventid because of eventbox
foundEventForMessage = true
}
}
if(!foundEventForMessage){
filteredMessages.push(message)
}
}
return filteredMessages
}

View File

@ -1,6 +1,6 @@
import { GuildMember, GuildScheduledEvent, GuildScheduledEventStatus } from "discord.js"; import { GuildMember, GuildScheduledEvent, GuildScheduledEventStatus } from "discord.js";
import { v4 as uuid } from "uuid"; import { v4 as uuid } from "uuid";
import { client, jellyfinHandler } from "../.."; import { jellyfinHandler } from "../..";
import { getGuildSpecificTriggerRoleId } from "../helper/roleFilter"; import { getGuildSpecificTriggerRoleId } from "../helper/roleFilter";
import { logger } from "../logger"; import { logger } from "../logger";
@ -10,7 +10,7 @@ export const name = 'guildScheduledEventUpdate'
export async function execute(oldEvent: GuildScheduledEvent, newEvent: GuildScheduledEvent) { export async function execute(oldEvent: GuildScheduledEvent, newEvent: GuildScheduledEvent) {
try { try {
const requestId = uuid() const requestId = uuid()
logger.debug(`Got scheduledEvent update. New Event: ${JSON.stringify(newEvent, null, 2)}`, { guildId: newEvent.guildId, requestId }) // logger.debug(`Got scheduledEvent update. New Event: ${JSON.stringify(newEvent, null, 2)}`, { guildId: newEvent.guildId, requestId })
if (!newEvent.guild) { if (!newEvent.guild) {
logger.error("Event has no guild, aborting.", { guildId: newEvent.guildId, requestId }) logger.error("Event has no guild, aborting.", { guildId: newEvent.guildId, requestId })
return return
@ -32,13 +32,7 @@ export async function execute(oldEvent: GuildScheduledEvent, newEvent: GuildSche
if (newEvent.status === GuildScheduledEventStatus.Active) if (newEvent.status === GuildScheduledEventStatus.Active)
createJFUsers(members, newEvent.name, requestId) createJFUsers(members, newEvent.name, requestId)
else { else {
const announcementChannel = await client.getAnnouncementChannelForGuild(newEvent.guild.id)
if(!announcementChannel) {
logger.error("Could not find announcement channel. Aborting", { guildId: newEvent.guild.id, requestId })
return
}
const announcements = (await announcementChannel.messages.fetch()).filter(message => !message.pinned)
announcements.forEach(message => message.delete())
members.forEach(member => { members.forEach(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.`)) 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.`))
}) })

View File

@ -0,0 +1,23 @@
import { format, isToday, toDate } from "date-fns";
import {utcToZonedTime} from "date-fns-tz"
import { GuildScheduledEvent } from "discord.js";
import { logger } from "../logger";
import de from "date-fns/locale/de";
export function createDateStringFromEvent(event: GuildScheduledEvent, requestId: string, guildId?: string): string {
if(!event.scheduledStartAt) {
logger.error("Event has no start. Cannot create dateString.", {guildId, requestId})
return `"habe keinen Startzeitpunkt ermitteln können"`
}
const timeZone = 'Europe/Berlin'
const zonedDateTime = utcToZonedTime(event.scheduledStartAt, timeZone)
const time = format(zonedDateTime, "HH:mm", {locale: de})
if(isToday(zonedDateTime)) {
return `heute um ${time}`
}
const date = format(zonedDateTime, "eeee dd.MM", {locale: de})
return `am ${date} um ${time}`
}

View File

@ -2,7 +2,7 @@ import { GuildMember } from "discord.js";
import { JellyfinConfig, Maybe, PermissionLevel } from "../interfaces"; import { JellyfinConfig, Maybe, PermissionLevel } from "../interfaces";
import { logger } from "../logger"; import { logger } from "../logger";
import { CreateUserByNameOperationRequest, DeleteUserRequest, GetItemsRequest, ItemsApi, SystemApi, UpdateUserPasswordOperationRequest, UpdateUserPolicyOperationRequest, UserApi } from "./apis"; import { CreateUserByNameOperationRequest, DeleteUserRequest, GetItemsRequest, ItemsApi, SystemApi, UpdateUserPasswordOperationRequest, UpdateUserPolicyOperationRequest, UserApi } from "./apis";
import { BaseItemDto, UpdateUserPasswordRequest } from "./models"; import { BaseItemDto, UpdateUserPasswordRequest, UpdateUserPolicyRequest } from "./models";
import { UserDto } from "./models/UserDto"; import { UserDto } from "./models/UserDto";
import { Configuration, ConfigurationParameters } from "./runtime"; import { Configuration, ConfigurationParameters } from "./runtime";
@ -52,24 +52,46 @@ export class JellyfinHandler {
return (Math.random() * 10000 + 10000).toFixed(0) return (Math.random() * 10000 + 10000).toFixed(0)
} }
public async createUserAccountForDiscordUser(discordUser: GuildMember, level: PermissionLevel, guildId?: string, requestId?: string): Promise<UserDto> { public async createUserAccountForDiscordUser(discordUser: GuildMember, level: PermissionLevel, requestId: string, guildId?: string): Promise<UserDto> {
const newUserName = this.generateJFUserName(discordUser, level) 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: {
name: newUserName, name: newUserName,
password: this.generatePasswordForUser(), password: this.generatePasswordForUser()
} }
} }
logger.debug(JSON.stringify(req), { requestId, guildId }) logger.debug(JSON.stringify(req), { requestId, guildId })
const createResult = await this.userApi.createUserByName(req) const createResult = await this.userApi.createUserByName(req)
if (createResult) { if (createResult) {
if(createResult.policy) {
this.setUserPermissions(createResult, requestId, guildId)
}
(await discordUser.createDM()).send(`Ich hab dir mal nen Account angelegt :)\nDein Username ist ${createResult.name}, dein Password ist "${req.createUserByNameRequest.password}"!`) (await discordUser.createDM()).send(`Ich hab dir mal nen Account angelegt :)\nDein Username ist ${createResult.name}, dein Password ist "${req.createUserByNameRequest.password}"!`)
return createResult return createResult
} }
else throw new Error('Could not create User in Jellyfin') else throw new Error('Could not create User in Jellyfin')
} }
public async setUserPermissions(user: UserDto, requestId: string, guildId?: string) {
if(!user.policy || !user.id) {
logger.error(`Cannot update user policy. User ${user.name} has no policy to modify`, {guildId, requestId})
return
}
user.policy.enableVideoPlaybackTranscoding = false
const operation: UpdateUserPolicyRequest = {
...user.policy,
enableVideoPlaybackTranscoding: false
}
const request: UpdateUserPolicyOperationRequest = {
userId: user.id,
updateUserPolicyRequest: operation
}
this.userApi.updateUserPolicy(request)
}
public async isUserAlreadyPresent(discordUser: GuildMember, requestId?: string): Promise<boolean> { public async isUserAlreadyPresent(discordUser: GuildMember, requestId?: string): Promise<boolean> {
const jfuser = await this.getUser(discordUser, requestId) const jfuser = await this.getUser(discordUser, requestId)
logger.debug(`Presence for DiscordUser ${discordUser.id}:${jfuser !== undefined}`, { guildId: discordUser.guild.id, requestId }) logger.debug(`Presence for DiscordUser ${discordUser.id}:${jfuser !== undefined}`, { guildId: discordUser.guild.id, requestId })