Compare commits
21 Commits
Author | SHA1 | Date | |
---|---|---|---|
a4d7c57d10 | |||
2802afa7d5 | |||
3a5ea5d4ff | |||
45d87275bf | |||
31e440434e | |||
3d70b56eb7 | |||
3298c7a244 | |||
5b98c9bf2f | |||
ee363e065c | |||
9af847f234 | |||
a18406e7e4 | |||
b9f65125dc | |||
d61457cb5f | |||
9da8f47784 | |||
e8c58d5ff8 | |||
8569a3e1e6 | |||
8d0dda0fa9 | |||
777ae330ad | |||
111ccaa880 | |||
c00453d3d3 | |||
8a7973a2e3 |
@ -1,5 +1,5 @@
|
||||
name: Compile the repository
|
||||
on: [push]
|
||||
on: [pull_request]
|
||||
env:
|
||||
REGISTRY: gitea.brudi.xyz
|
||||
IMAGE_NAME: ${{ gitea.repository }}
|
||||
@ -14,4 +14,4 @@ jobs:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
- name: Build Container
|
||||
run: docker build -t "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest" .
|
||||
run: docker build .
|
||||
|
@ -11,7 +11,7 @@ env:
|
||||
jobs:
|
||||
build-docker-image:
|
||||
runs-on: ubuntu-latest
|
||||
if: gitea.ref == 'refs/heads/master'
|
||||
#if: gitea.ref == 'refs/heads/master'
|
||||
container: catthehacker/ubuntu:act-latest
|
||||
permissions:
|
||||
contents: read
|
||||
@ -19,11 +19,9 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
- name: Get Package Version
|
||||
run: VERSION = node -p "require('./package.json').version"
|
||||
- name: Log in to the Container registry
|
||||
run: docker login -u ${{ env.USER }} -p ${{ secrets.TOKEN }} ${{ env.REGISTRY }}
|
||||
- name: Build Container
|
||||
run: docker build -t "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest" -t "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ env.VERSION }}".
|
||||
run: docker build -t "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest" -t "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ node -p "require('./package.json').version" }}".
|
||||
- name: Push Container
|
||||
run: docker push "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest"
|
||||
run: docker push --all-tags "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}"
|
||||
|
4
package-lock.json
generated
4
package-lock.json
generated
@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "node-jellyfin-discord-bot",
|
||||
"version": "1.0.1",
|
||||
"version": "1.1.0",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "node-jellyfin-discord-bot",
|
||||
"version": "1.0.1",
|
||||
"version": "1.1.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@discordjs/rest": "^1.7.0",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "node-jellyfin-discord-bot",
|
||||
"version": "1.0.1",
|
||||
"version": "1.1.0",
|
||||
"description": "A discord bot to sync jellyfin accounts with discord roles",
|
||||
"main": "index.js",
|
||||
"license": "MIT",
|
||||
|
@ -3,7 +3,7 @@ import { Guild, GuildScheduledEvent, GuildScheduledEventEditOptions, GuildSchedu
|
||||
import { v4 as uuid } from 'uuid'
|
||||
import { client } from '../..'
|
||||
import { config } from '../configuration'
|
||||
import { Emotes } from '../events/guildScheduledEventCreate'
|
||||
import { Emotes } from '../events/autoCreateVoteByWPEvent'
|
||||
import { Maybe } from '../interfaces'
|
||||
import { logger } from '../logger'
|
||||
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) {
|
||||
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 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 = {
|
||||
content: body,
|
||||
allowedMentions: { parse: ["roles"] }
|
||||
|
48
server/events/announceManualWatchparty.ts
Normal file
48
server/events/announceManualWatchparty.ts
Normal 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 })
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,9 +1,9 @@
|
||||
import { format } from "date-fns";
|
||||
import { GuildScheduledEvent, Message, MessageCreateOptions, TextChannel } from "discord.js";
|
||||
import { ScheduledTask } from "node-cron";
|
||||
import { v4 as uuid } from "uuid";
|
||||
import { client, yavinJellyfinHandler } from "../..";
|
||||
import { config } from "../configuration";
|
||||
import { createDateStringFromEvent } from "../helper/dateHelper";
|
||||
import { Maybe } from "../interfaces";
|
||||
import { logger } from "../logger";
|
||||
|
||||
@ -11,12 +11,12 @@ import { logger } from "../logger";
|
||||
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()
|
||||
logger.debug(`New event created: ${JSON.stringify(event, null, 2)}`, { guildId: event.guildId, requestId })
|
||||
|
||||
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 })
|
||||
@ -38,17 +38,16 @@ export async function execute(event: GuildScheduledEvent) {
|
||||
logger.info("EVENT DOES NOT HAVE STARTDATE; CANCELLING", {guildId: event.guildId, requestId})
|
||||
return
|
||||
}
|
||||
const date = format(event.scheduledStartAt, "dd.MM")
|
||||
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`
|
||||
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`
|
||||
|
||||
for (let i = 0; i < movies.length; i++) {
|
||||
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 = {
|
||||
allowedMentions: { parse: ["roles"]},
|
||||
content: message
|
||||
content: message,
|
||||
}
|
||||
|
||||
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++) {
|
||||
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
|
||||
}
|
52
server/events/deleteAnnouncementsWhenWPEnds.ts
Normal file
52
server/events/deleteAnnouncementsWhenWPEnds.ts
Normal 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
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
import { GuildMember, GuildScheduledEvent, GuildScheduledEventStatus } from "discord.js";
|
||||
import { v4 as uuid } from "uuid";
|
||||
import { client, jellyfinHandler } from "../..";
|
||||
import { jellyfinHandler } from "../..";
|
||||
import { getGuildSpecificTriggerRoleId } from "../helper/roleFilter";
|
||||
import { logger } from "../logger";
|
||||
|
||||
@ -10,7 +10,7 @@ export const name = 'guildScheduledEventUpdate'
|
||||
export async function execute(oldEvent: GuildScheduledEvent, newEvent: GuildScheduledEvent) {
|
||||
try {
|
||||
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) {
|
||||
logger.error("Event has no guild, aborting.", { guildId: newEvent.guildId, requestId })
|
||||
return
|
||||
@ -32,13 +32,7 @@ export async function execute(oldEvent: GuildScheduledEvent, newEvent: GuildSche
|
||||
if (newEvent.status === GuildScheduledEventStatus.Active)
|
||||
createJFUsers(members, newEvent.name, requestId)
|
||||
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 => {
|
||||
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.`))
|
||||
})
|
16
server/helper/dateHelper.ts
Normal file
16
server/helper/dateHelper.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import { format } from "date-fns";
|
||||
import { GuildScheduledEvent } from "discord.js";
|
||||
import { logger } from "../logger";
|
||||
|
||||
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 date = format(event.scheduledStartAt, "dd.MM")
|
||||
const time = format(event.scheduledStartAt, "HH:mm")
|
||||
|
||||
|
||||
return `am ${date} um ${time}`
|
||||
}
|
Reference in New Issue
Block a user