Compare commits
	
		
			41 Commits
		
	
	
		
			b1c581ca6e
			...
			feat/cicd
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 36d1306180 | |||
| 69bde313b5 | |||
| 7af3d87048 | |||
| 73741230b1 | |||
| 4f6d4f646a | |||
| 6169649261 | |||
| 0560c4620c | |||
| be3ee5e493 | |||
| 251e6ae3d6 | |||
| 2edd0312dc | |||
| f2b5ee502f | |||
| 749e1c89ab | |||
| 0d5799796a | |||
| b7986d276b | |||
| 8540381834 | |||
| 7e67d1fed9 | |||
| 0cb19ba8f1 | |||
| 5dcf766593 | |||
| 808bdd033e | |||
| 33f031d333 | |||
| 40d9523e21 | |||
| 26e74a62c1 | |||
| c0f91aad79 | |||
| 79ffde5f34 | |||
| 911b9e4884 | |||
| 31a9e0eb28 | |||
| bcf788293e | |||
| 934b6dfead | |||
| cd0c8c0017 | |||
| 83f803d0e7 | |||
| 2cb652aee6 | |||
| 034d14eb15 | |||
| c8bfc47ddf | |||
| b67982ed38 | |||
| e3144fc402 | |||
| 1970f4b0cb | |||
| 8ac4f568a0 | |||
| 09f4efc96c | |||
| 6e0c3b8ef6 | |||
| 8ee36f7510 | |||
| 1593e126eb | 
@@ -1,7 +0,0 @@
 | 
				
			|||||||
root = true
 | 
					 | 
				
			||||||
[*]
 | 
					 | 
				
			||||||
indent_style = tab
 | 
					 | 
				
			||||||
tab_width = 4
 | 
					 | 
				
			||||||
[*.ts]
 | 
					 | 
				
			||||||
indent_style = tab
 | 
					 | 
				
			||||||
tab_width = 4
 | 
					 | 
				
			||||||
@@ -14,4 +14,4 @@ jobs:
 | 
				
			|||||||
      - name: Checkout repository
 | 
					      - name: Checkout repository
 | 
				
			||||||
        uses: actions/checkout@v3
 | 
					        uses: actions/checkout@v3
 | 
				
			||||||
      - name: Build Container
 | 
					      - name: Build Container
 | 
				
			||||||
        run: docker build --target compile .
 | 
					        run: docker build .
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,6 +11,7 @@ env:
 | 
				
			|||||||
jobs:
 | 
					jobs:
 | 
				
			||||||
  build-docker-image:
 | 
					  build-docker-image:
 | 
				
			||||||
    runs-on: ubuntu-latest
 | 
					    runs-on: ubuntu-latest
 | 
				
			||||||
 | 
					      #if: gitea.ref == 'refs/heads/master'
 | 
				
			||||||
    container: catthehacker/ubuntu:act-latest
 | 
					    container: catthehacker/ubuntu:act-latest
 | 
				
			||||||
    permissions:
 | 
					    permissions:
 | 
				
			||||||
      contents: read
 | 
					      contents: read
 | 
				
			||||||
@@ -21,8 +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 --target compile -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" .
 | 
				
			||||||
        env:
 | 
					 | 
				
			||||||
          version: $(cat package.json | awk 'match($0, /version/) {print $2}' | sed 's/[\",]//g') # extracts the version number from the package.json with bash magic
 | 
					 | 
				
			||||||
      - name: Push Container
 | 
					      - name: Push Container
 | 
				
			||||||
        run: docker push --all-tags "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}"
 | 
					        run: docker push --all-tags "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,18 +0,0 @@
 | 
				
			|||||||
name: Run unit tests
 | 
					 | 
				
			||||||
on: [pull_request]
 | 
					 | 
				
			||||||
env:
 | 
					 | 
				
			||||||
  REGISTRY: gitea.brudi.xyz
 | 
					 | 
				
			||||||
  IMAGE_NAME: ${{ gitea.repository }}
 | 
					 | 
				
			||||||
  USER: ${{ gitea.actor }}
 | 
					 | 
				
			||||||
jobs:
 | 
					 | 
				
			||||||
  test:
 | 
					 | 
				
			||||||
    runs-on: ubuntu-latest
 | 
					 | 
				
			||||||
    container: catthehacker/ubuntu:act-latest
 | 
					 | 
				
			||||||
    permissions:
 | 
					 | 
				
			||||||
      contents: read
 | 
					 | 
				
			||||||
    steps:
 | 
					 | 
				
			||||||
      - name: Checkout repository
 | 
					 | 
				
			||||||
        uses: actions/checkout@v3
 | 
					 | 
				
			||||||
      - name: Run Tests
 | 
					 | 
				
			||||||
        run: docker build --target test .
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
							
								
								
									
										23
									
								
								Dockerfile
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								Dockerfile
									
									
									
									
									
								
							@@ -1,22 +1,11 @@
 | 
				
			|||||||
FROM node:alpine as files 
 | 
					FROM node:alpine as Build
 | 
				
			||||||
ENV TZ="Europe/Berlin"
 | 
					 | 
				
			||||||
WORKDIR /app
 | 
					 | 
				
			||||||
COPY [ "package-lock.json", "package.json", "index.ts", "tsconfig.json", "./" ]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
FROM files as proddependencies
 | 
					 | 
				
			||||||
ENV NODE_ENV=production
 | 
					ENV NODE_ENV=production
 | 
				
			||||||
 | 
					WORKDIR /app
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					COPY [ "package-lock.json", "package.json", "index.ts", "tsconfig.json", "./" ]
 | 
				
			||||||
 | 
					COPY server ./server
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RUN npm ci --omit=dev
 | 
					RUN npm ci --omit=dev
 | 
				
			||||||
 | 
					
 | 
				
			||||||
FROM proddependencies as compile 
 | 
					 | 
				
			||||||
COPY server ./server
 | 
					 | 
				
			||||||
RUN npm run build
 | 
					RUN npm run build
 | 
				
			||||||
CMD ["npm","run","start"]
 | 
					CMD ["npm","run","start"]
 | 
				
			||||||
 | 
					 | 
				
			||||||
FROM files as dependencies
 | 
					 | 
				
			||||||
RUN npm ci
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
FROM dependencies as test
 | 
					 | 
				
			||||||
COPY server ./server
 | 
					 | 
				
			||||||
COPY jest.config.js .
 | 
					 | 
				
			||||||
COPY tests ./tests
 | 
					 | 
				
			||||||
RUN npm run test
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										4
									
								
								index.ts
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								index.ts
									
									
									
									
									
								
							@@ -5,8 +5,8 @@ import { JellyfinHandler } from "./server/jellyfin/handler"
 | 
				
			|||||||
import { attachedImages } from "./server/assets/attachments"
 | 
					import { attachedImages } from "./server/assets/attachments"
 | 
				
			||||||
const requestId = 'startup'
 | 
					const requestId = 'startup'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const jellyfinHandler = new JellyfinHandler({ jellyfinToken: config.bot.workaround_token, jellyfinUrl: config.bot.jellyfin_url, movieCollectionId: config.bot.jf_collection_id, collectionUser: config.bot.jf_user })
 | 
					export const jellyfinHandler = new JellyfinHandler({jellyfinToken: config.bot.workaround_token, jellyfinUrl: config.bot.jellyfin_url, movieCollectionId: config.bot.jf_collection_id, collectionUser: config.bot.jf_user})
 | 
				
			||||||
export const yavinJellyfinHandler = new JellyfinHandler({ jellyfinToken: config.bot.yavin_jellyfin_token, jellyfinUrl: config.bot.yavin_jellyfin_url, movieCollectionId: config.bot.yavin_collection_id, collectionUser: config.bot.yavin_jellyfin_collection_user })
 | 
					export const yavinJellyfinHandler = new JellyfinHandler({jellyfinToken: config.bot.yavin_jellyfin_token, jellyfinUrl: config.bot.yavin_jellyfin_url, movieCollectionId: config.bot.yavin_collection_id, collectionUser: config.bot.yavin_jellyfin_collection_user})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const client = new ExtendedClient(jellyfinHandler)
 | 
					export const client = new ExtendedClient(jellyfinHandler)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,19 +0,0 @@
 | 
				
			|||||||
module.exports = {
 | 
					 | 
				
			||||||
	'roots': [
 | 
					 | 
				
			||||||
		'<rootDir>/tests',
 | 
					 | 
				
			||||||
		'<rootDir>/server'
 | 
					 | 
				
			||||||
	],
 | 
					 | 
				
			||||||
	'transform': {
 | 
					 | 
				
			||||||
		'^.+\\.tsx?$': 'ts-jest'
 | 
					 | 
				
			||||||
	},
 | 
					 | 
				
			||||||
	'testRegex': '(/__tests__/.*|(\\.|/)(test|spec))\\.tsx?$',
 | 
					 | 
				
			||||||
	'setupFiles': ["<rootDir>/tests/testenv.js"],
 | 
					 | 
				
			||||||
	'moduleFileExtensions': [
 | 
					 | 
				
			||||||
		'ts',
 | 
					 | 
				
			||||||
		'tsx',
 | 
					 | 
				
			||||||
		'js',
 | 
					 | 
				
			||||||
		'jsx',
 | 
					 | 
				
			||||||
		'json',
 | 
					 | 
				
			||||||
		'node'
 | 
					 | 
				
			||||||
	],
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
							
								
								
									
										27
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										27
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							@@ -30,13 +30,12 @@
 | 
				
			|||||||
        "winston": "^3.8.2"
 | 
					        "winston": "^3.8.2"
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      "devDependencies": {
 | 
					      "devDependencies": {
 | 
				
			||||||
        "@types/jest": "^29.5.2",
 | 
					        "@types/jest": "^29.5.0",
 | 
				
			||||||
        "@typescript-eslint/eslint-plugin": "^5.58.0",
 | 
					        "@typescript-eslint/eslint-plugin": "^5.58.0",
 | 
				
			||||||
        "@typescript-eslint/parser": "^5.58.0",
 | 
					        "@typescript-eslint/parser": "^5.58.0",
 | 
				
			||||||
        "eslint": "^8.38.0",
 | 
					        "eslint": "^8.38.0",
 | 
				
			||||||
        "jest": "^29.5.0",
 | 
					        "jest": "^29.5.0",
 | 
				
			||||||
        "jest-cli": "^29.5.0",
 | 
					        "jest-cli": "^29.5.0",
 | 
				
			||||||
        "mockdate": "^3.0.5",
 | 
					 | 
				
			||||||
        "nodemon": "^2.0.22",
 | 
					        "nodemon": "^2.0.22",
 | 
				
			||||||
        "rimraf": "^5.0.0",
 | 
					        "rimraf": "^5.0.0",
 | 
				
			||||||
        "ts-jest": "^29.1.0"
 | 
					        "ts-jest": "^29.1.0"
 | 
				
			||||||
@@ -1569,9 +1568,9 @@
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "node_modules/@types/jest": {
 | 
					    "node_modules/@types/jest": {
 | 
				
			||||||
      "version": "29.5.2",
 | 
					      "version": "29.5.0",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.2.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.0.tgz",
 | 
				
			||||||
      "integrity": "sha512-mSoZVJF5YzGVCk+FsDxzDuH7s+SCkzrgKZzf0Z0T2WudhBUPoF6ktoTPC4R0ZoCPCV5xUvuU6ias5NvxcBcMMg==",
 | 
					      "integrity": "sha512-3Emr5VOl/aoBwnWcH/EFQvlSAmjV+XtV9GGu5mwdYew5vhQh0IUZx/60x0TzHDu09Bi7HMx10t/namdJw5QIcg==",
 | 
				
			||||||
      "dev": true,
 | 
					      "dev": true,
 | 
				
			||||||
      "dependencies": {
 | 
					      "dependencies": {
 | 
				
			||||||
        "expect": "^29.0.0",
 | 
					        "expect": "^29.0.0",
 | 
				
			||||||
@@ -4990,12 +4989,6 @@
 | 
				
			|||||||
        "node": ">=10"
 | 
					        "node": ">=10"
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "node_modules/mockdate": {
 | 
					 | 
				
			||||||
      "version": "3.0.5",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/mockdate/-/mockdate-3.0.5.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-iniQP4rj1FhBdBYS/+eQv7j1tadJ9lJtdzgOpvsOHng/GbcDh2Fhdeq+ZRldrPYdXvCyfFUmFeEwEGXZB5I/AQ==",
 | 
					 | 
				
			||||||
      "dev": true
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/ms": {
 | 
					    "node_modules/ms": {
 | 
				
			||||||
      "version": "2.1.2",
 | 
					      "version": "2.1.2",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
 | 
				
			||||||
@@ -8146,9 +8139,9 @@
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "@types/jest": {
 | 
					    "@types/jest": {
 | 
				
			||||||
      "version": "29.5.2",
 | 
					      "version": "29.5.0",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.2.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.0.tgz",
 | 
				
			||||||
      "integrity": "sha512-mSoZVJF5YzGVCk+FsDxzDuH7s+SCkzrgKZzf0Z0T2WudhBUPoF6ktoTPC4R0ZoCPCV5xUvuU6ias5NvxcBcMMg==",
 | 
					      "integrity": "sha512-3Emr5VOl/aoBwnWcH/EFQvlSAmjV+XtV9GGu5mwdYew5vhQh0IUZx/60x0TzHDu09Bi7HMx10t/namdJw5QIcg==",
 | 
				
			||||||
      "dev": true,
 | 
					      "dev": true,
 | 
				
			||||||
      "requires": {
 | 
					      "requires": {
 | 
				
			||||||
        "expect": "^29.0.0",
 | 
					        "expect": "^29.0.0",
 | 
				
			||||||
@@ -10727,12 +10720,6 @@
 | 
				
			|||||||
      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
 | 
				
			||||||
      "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="
 | 
					      "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "mockdate": {
 | 
					 | 
				
			||||||
      "version": "3.0.5",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/mockdate/-/mockdate-3.0.5.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-iniQP4rj1FhBdBYS/+eQv7j1tadJ9lJtdzgOpvsOHng/GbcDh2Fhdeq+ZRldrPYdXvCyfFUmFeEwEGXZB5I/AQ==",
 | 
					 | 
				
			||||||
      "dev": true
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "ms": {
 | 
					    "ms": {
 | 
				
			||||||
      "version": "2.1.2",
 | 
					      "version": "2.1.2",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -33,18 +33,15 @@
 | 
				
			|||||||
    "debuggable": "node build/index.js --inspect-brk",
 | 
					    "debuggable": "node build/index.js --inspect-brk",
 | 
				
			||||||
    "monitor": "nodemon build/index.js",
 | 
					    "monitor": "nodemon build/index.js",
 | 
				
			||||||
    "lint": "eslint . --ext .ts",
 | 
					    "lint": "eslint . --ext .ts",
 | 
				
			||||||
		"lint-fix": "eslint . --ext .ts --fix",
 | 
					    "lint-fix": "eslint . --ext .ts --fix"
 | 
				
			||||||
		"test": "jest --runInBand",
 | 
					 | 
				
			||||||
		"test-watch": "jest --watch"
 | 
					 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "devDependencies": {
 | 
					  "devDependencies": {
 | 
				
			||||||
		"@types/jest": "^29.5.2",
 | 
					    "@types/jest": "^29.5.0",
 | 
				
			||||||
    "@typescript-eslint/eslint-plugin": "^5.58.0",
 | 
					    "@typescript-eslint/eslint-plugin": "^5.58.0",
 | 
				
			||||||
    "@typescript-eslint/parser": "^5.58.0",
 | 
					    "@typescript-eslint/parser": "^5.58.0",
 | 
				
			||||||
    "eslint": "^8.38.0",
 | 
					    "eslint": "^8.38.0",
 | 
				
			||||||
    "jest": "^29.5.0",
 | 
					    "jest": "^29.5.0",
 | 
				
			||||||
    "jest-cli": "^29.5.0",
 | 
					    "jest-cli": "^29.5.0",
 | 
				
			||||||
		"mockdate": "^3.0.5",
 | 
					 | 
				
			||||||
    "nodemon": "^2.0.22",
 | 
					    "nodemon": "^2.0.22",
 | 
				
			||||||
    "rimraf": "^5.0.0",
 | 
					    "rimraf": "^5.0.0",
 | 
				
			||||||
    "ts-jest": "^29.1.0"
 | 
					    "ts-jest": "^29.1.0"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,22 +13,22 @@ export default new Command({
 | 
				
			|||||||
    options: [{
 | 
					    options: [{
 | 
				
			||||||
        name: "typ",
 | 
					        name: "typ",
 | 
				
			||||||
        type: ApplicationCommandOptionType.String,
 | 
					        type: ApplicationCommandOptionType.String,
 | 
				
			||||||
		description: "Was für ein announcement?",
 | 
					        description:"Was für ein announcement?",
 | 
				
			||||||
		choices: [{ name: "initial", value: "initial" }, { name: "votepls", value: "votepls" }, { name: "cancel", value: "cancel" }],
 | 
					        choices: [{name: "initial", value:"initial"},{name: "votepls", value:"votepls"},{name: "cancel", value:"cancel"}],
 | 
				
			||||||
        required: true
 | 
					        required: true
 | 
				
			||||||
    }],
 | 
					    }],
 | 
				
			||||||
    run: async (interaction: RunOptions) => {
 | 
					    run: async (interaction: RunOptions) => {
 | 
				
			||||||
        const command = interaction.interaction
 | 
					        const command = interaction.interaction
 | 
				
			||||||
        const requestId = uuid()
 | 
					        const requestId = uuid()
 | 
				
			||||||
		if (!command.guildId) {
 | 
					        if(!command.guildId) {
 | 
				
			||||||
			logger.error("COMMAND DOES NOT HAVE A GUILD ID; CANCELLING!!!", { requestId })
 | 
					            logger.error("COMMAND DOES NOT HAVE A GUILD ID; CANCELLING!!!", {requestId})
 | 
				
			||||||
            return
 | 
					            return
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        const guildId = command.guildId
 | 
					        const guildId = command.guildId
 | 
				
			||||||
        const announcementType = command.options.data.find(option => option.name.includes("typ"))
 | 
					        const announcementType = command.options.data.find(option => option.name.includes("typ"))
 | 
				
			||||||
        logger.info(`Got command for announcing ${announcementType?.value}!`, { guildId, requestId })
 | 
					        logger.info(`Got command for announcing ${announcementType?.value}!`, { guildId, requestId })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (!announcementType) {
 | 
					        if(!announcementType) {
 | 
				
			||||||
            logger.error("Did not get an announcement type!", { guildId, requestId })
 | 
					            logger.error("Did not get an announcement type!", { guildId, requestId })
 | 
				
			||||||
            return
 | 
					            return
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -40,7 +40,7 @@ export default new Command({
 | 
				
			|||||||
            logger.info(`User ${command.member.displayName} seems to be admin`)
 | 
					            logger.info(`User ${command.member.displayName} seems to be admin`)
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if ((<string>announcementType.value).includes("initial")) {
 | 
					        if((<string>announcementType.value).includes("initial")) {
 | 
				
			||||||
            sendInitialAnnouncement(guildId, requestId)
 | 
					            sendInitialAnnouncement(guildId, requestId)
 | 
				
			||||||
            command.followUp("Ist rausgeschickt!")
 | 
					            command.followUp("Ist rausgeschickt!")
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
@@ -56,7 +56,7 @@ function isAdmin(member: GuildMember): boolean {
 | 
				
			|||||||
async function sendInitialAnnouncement(guildId: string, requestId: string): Promise<void> {
 | 
					async function sendInitialAnnouncement(guildId: string, requestId: string): Promise<void> {
 | 
				
			||||||
    logger.info("Sending initial announcement")
 | 
					    logger.info("Sending initial announcement")
 | 
				
			||||||
    const announcementChannel: Maybe<TextChannel> = client.getAnnouncementChannelForGuild(guildId)
 | 
					    const announcementChannel: Maybe<TextChannel> = client.getAnnouncementChannelForGuild(guildId)
 | 
				
			||||||
	if (!announcementChannel) {
 | 
					    if(!announcementChannel) {
 | 
				
			||||||
        logger.error("Could not find announcement channel. Aborting", { guildId, requestId })
 | 
					        logger.error("Could not find announcement channel. Aborting", { guildId, requestId })
 | 
				
			||||||
        return
 | 
					        return
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -96,7 +96,7 @@ export async function manageAnnouncementRoles(guild: Guild, reaction: MessageRea
 | 
				
			|||||||
    const allUsers = (await guild.members.fetch())
 | 
					    const allUsers = (await guild.members.fetch())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const usersWhoHaveRole: GuildMember[] = allUsers
 | 
					    const usersWhoHaveRole: GuildMember[] = allUsers
 | 
				
			||||||
		.filter(member => member.roles.cache
 | 
					        .filter(member=> member.roles.cache
 | 
				
			||||||
            .find(role => role.id === config.bot.announcement_role) !== undefined)
 | 
					            .find(role => role.id === config.bot.announcement_role) !== undefined)
 | 
				
			||||||
        .map(member => member)
 | 
					        .map(member => member)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -105,15 +105,15 @@ export async function manageAnnouncementRoles(guild: Guild, reaction: MessageRea
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    const usersWhoDontHaveRole: GuildMember[] = allUsers
 | 
					    const usersWhoDontHaveRole: GuildMember[] = allUsers
 | 
				
			||||||
        .filter(member => member.roles.cache
 | 
					        .filter(member => member.roles.cache
 | 
				
			||||||
			.find(role => role.id === config.bot.announcement_role) === undefined)
 | 
					            .find(role=> role.id === config.bot.announcement_role) === undefined)
 | 
				
			||||||
        .map(member => member)
 | 
					        .map(member => member)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const usersWhoNeedRole: GuildMember[] = usersWhoDontHaveRole
 | 
					    const usersWhoNeedRole: GuildMember[] = usersWhoDontHaveRole
 | 
				
			||||||
        .filter(userWhoNeeds => usersWhoWantRole.map(wanter => wanter.id).includes(userWhoNeeds.id))
 | 
					        .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 removed: ${JSON.stringify(usersWhoNeedRoleRevoked)}`, {guildId, requestId})
 | 
				
			||||||
	logger.debug(`Theses users will get the role added: ${JSON.stringify(usersWhoNeedRole)}`, { guildId, requestId })
 | 
					    logger.debug(`Theses users will get the role added: ${JSON.stringify(usersWhoNeedRole)}`, {guildId, requestId})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    usersWhoNeedRoleRevoked.forEach(user => user.roles.remove(announcementRole))
 | 
					    usersWhoNeedRoleRevoked.forEach(user => user.roles.remove(announcementRole))
 | 
				
			||||||
    usersWhoNeedRole.forEach(user => user.roles.add(announcementRole))
 | 
					    usersWhoNeedRole.forEach(user => user.roles.add(announcementRole))
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,7 +20,7 @@ export async function execute(event: GuildScheduledEvent) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        if (event.description.includes("!wp")) {
 | 
					        if (event.description.includes("!wp")) {
 | 
				
			||||||
            logger.info("Got manual create event of watchparty event!", { guildId, requestId })
 | 
					            logger.info("Got manual create event of watchparty event!", { guildId, requestId })
 | 
				
			||||||
			if (event.description.includes("!private")) {
 | 
					            if(event.description.includes("!private")) {
 | 
				
			||||||
                logger.info("Event description contains \"!private\". Won't announce.", { guildId, requestId })
 | 
					                logger.info("Event description contains \"!private\". Won't announce.", { guildId, requestId })
 | 
				
			||||||
                return
 | 
					                return
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -28,14 +28,14 @@ export async function execute(event: GuildScheduledEvent) {
 | 
				
			|||||||
        logger.debug(`Movies: ${JSON.stringify(movies)}`, { guildId: event.guildId, requestId })
 | 
					        logger.debug(`Movies: ${JSON.stringify(movies)}`, { guildId: event.guildId, requestId })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const announcementChannel: Maybe<TextChannel> = client.getAnnouncementChannelForGuild(event.guildId)
 | 
					        const announcementChannel: Maybe<TextChannel> = client.getAnnouncementChannelForGuild(event.guildId)
 | 
				
			||||||
		if (!announcementChannel) {
 | 
					        if(!announcementChannel) {
 | 
				
			||||||
            logger.error("Could not find announcement channel. Aborting", { guildId: event.guildId, requestId })
 | 
					            logger.error("Could not find announcement channel. Aborting", { guildId: event.guildId, requestId })
 | 
				
			||||||
            return
 | 
					            return
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        logger.debug(`Found channel ${JSON.stringify(announcementChannel, null, 2)}`, { guildId: event.guildId, requestId })
 | 
					        logger.debug(`Found channel ${JSON.stringify(announcementChannel, null, 2)}`, { guildId: event.guildId, requestId })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (!event.scheduledStartAt) {
 | 
					        if(!event.scheduledStartAt) {
 | 
				
			||||||
			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
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        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`
 | 
					        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`
 | 
				
			||||||
@@ -46,7 +46,7 @@ export async function execute(event: GuildScheduledEvent) {
 | 
				
			|||||||
        message = message.concat(NONE_OF_THAT).concat(": Wenn dir nichts davon gefällt.")
 | 
					        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,
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -27,7 +27,7 @@ export async function execute(oldEvent: GuildScheduledEvent, newEvent: GuildSche
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            const wpAnnouncements = (await announcementChannel.messages.fetch()).filter(message => !message.cleanContent.includes("[initial]"))
 | 
					            const wpAnnouncements = (await announcementChannel.messages.fetch()).filter(message => !message.cleanContent.includes("[initial]"))
 | 
				
			||||||
            const announcementsWithoutEvent = filterAnnouncementsByPendingWPs(wpAnnouncements, events)
 | 
					            const announcementsWithoutEvent = filterAnnouncementsByPendingWPs(wpAnnouncements, events)
 | 
				
			||||||
			logger.info(`Deleting ${announcementsWithoutEvent.length} announcements.`, { guildId, requestId })
 | 
					            logger.info(`Deleting ${announcementsWithoutEvent.length} announcements.`, {guildId, requestId})
 | 
				
			||||||
            announcementsWithoutEvent.forEach(message => message.delete())
 | 
					            announcementsWithoutEvent.forEach(message => message.delete())
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    } catch (error) {
 | 
					    } catch (error) {
 | 
				
			||||||
@@ -44,7 +44,7 @@ function filterAnnouncementsByPendingWPs(messages: Collection<string, Message<tr
 | 
				
			|||||||
                foundEventForMessage = true
 | 
					                foundEventForMessage = true
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
		if (!foundEventForMessage) {
 | 
					        if(!foundEventForMessage){
 | 
				
			||||||
            filteredMessages.push(message)
 | 
					            filteredMessages.push(message)
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,7 +12,7 @@ export async function execute(oldState: VoiceState, newState: VoiceState) {
 | 
				
			|||||||
    try {
 | 
					    try {
 | 
				
			||||||
        logger.info(JSON.stringify(newState, null, 2))
 | 
					        logger.info(JSON.stringify(newState, null, 2))
 | 
				
			||||||
        //ignore events like mute/unmute
 | 
					        //ignore events like mute/unmute
 | 
				
			||||||
		if (newState.channel?.id === oldState.channel?.id) {
 | 
					        if(newState.channel?.id === oldState.channel?.id) {
 | 
				
			||||||
            logger.info("Not handling VoiceState event because channelid of old and new was the same (i.e. mute/unmute event)")
 | 
					            logger.info("Not handling VoiceState event because channelid of old and new was the same (i.e. mute/unmute event)")
 | 
				
			||||||
            return
 | 
					            return
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -21,25 +21,25 @@ export async function execute(oldState: VoiceState, newState: VoiceState) {
 | 
				
			|||||||
            .filter((key) => key.description?.toLowerCase().includes("!wp") && key.isActive())
 | 
					            .filter((key) => key.description?.toLowerCase().includes("!wp") && key.isActive())
 | 
				
			||||||
            .map((key) => key)
 | 
					            .map((key) => key)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		const scheduledEventUsers = (await Promise.all(scheduledEvents.map(event => event.fetchSubscribers({ withMember: true }))))
 | 
					        const scheduledEventUsers = (await Promise.all(scheduledEvents.map(event => event.fetchSubscribers({withMember: true}))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //Dont handle users, that are already subscribed to the event. We only want to handle unsubscribed users here
 | 
					        //Dont handle users, that are already subscribed to the event. We only want to handle unsubscribed users here
 | 
				
			||||||
        let userFound = false;
 | 
					        let userFound = false;
 | 
				
			||||||
        scheduledEventUsers.forEach(collection => {
 | 
					        scheduledEventUsers.forEach(collection => {
 | 
				
			||||||
            collection.each(key => {
 | 
					            collection.each(key => {
 | 
				
			||||||
                logger.info(JSON.stringify(key, null, 2))
 | 
					                logger.info(JSON.stringify(key, null, 2))
 | 
				
			||||||
				if (key.member.user.id === newState.member?.user.id)
 | 
					                if(key.member.user.id === newState.member?.user.id)
 | 
				
			||||||
                    userFound = true;
 | 
					                    userFound = true;
 | 
				
			||||||
            })
 | 
					            })
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
		if (userFound) {
 | 
					        if(userFound) {
 | 
				
			||||||
            logger.info(`Not handling VoiceState event because user was already subscribed and got an account from there. User: ${JSON.stringify(newState.member, null, 2)}`)
 | 
					            logger.info(`Not handling VoiceState event because user was already subscribed and got an account from there. User: ${JSON.stringify(newState.member, null, 2)}`)
 | 
				
			||||||
            return
 | 
					            return
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (scheduledEvents.find(event => event.channelId === newState.channelId)) {
 | 
					        if (scheduledEvents.find(event => event.channelId === newState.channelId)) {
 | 
				
			||||||
			if (newState.member) {
 | 
					            if(newState.member){
 | 
				
			||||||
                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!")
 | 
				
			||||||
                const result = await jellyfinHandler.upsertUser(newState.member, "TEMPORARY", uuid())
 | 
					                const result = await jellyfinHandler.upsertUser(newState.member, "TEMPORARY", uuid())
 | 
				
			||||||
                if (result === UserUpsertResult.created) {
 | 
					                if (result === UserUpsertResult.created) {
 | 
				
			||||||
@@ -53,7 +53,7 @@ export async function execute(oldState: VoiceState, newState: VoiceState) {
 | 
				
			|||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            logger.info("VoiceState channelId was not the id of any channel with events")
 | 
					            logger.info("VoiceState channelId was not the id of any channel with events")
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
	} catch (error) {
 | 
					    }catch(error){
 | 
				
			||||||
        logger.error(error)
 | 
					        logger.error(error)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -1,23 +1,23 @@
 | 
				
			|||||||
import { format, isToday, toDate } from "date-fns";
 | 
					import { format, isToday, toDate } from "date-fns";
 | 
				
			||||||
import { utcToZonedTime } from "date-fns-tz"
 | 
					import {utcToZonedTime} from "date-fns-tz"
 | 
				
			||||||
import { GuildScheduledEvent } from "discord.js";
 | 
					import { GuildScheduledEvent } from "discord.js";
 | 
				
			||||||
import { logger } from "../logger";
 | 
					import { logger } from "../logger";
 | 
				
			||||||
import de from "date-fns/locale/de";
 | 
					import de from "date-fns/locale/de";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function createDateStringFromEvent(event: GuildScheduledEvent, requestId: string, guildId?: string): string {
 | 
					export function createDateStringFromEvent(event: GuildScheduledEvent, requestId: string, guildId?: string): string {
 | 
				
			||||||
	if (!event.scheduledStartAt) {
 | 
					    if(!event.scheduledStartAt) {
 | 
				
			||||||
		logger.error("Event has no start. Cannot create dateString.", { guildId, requestId })
 | 
					        logger.error("Event has no start. Cannot create dateString.", {guildId, requestId})
 | 
				
			||||||
        return `"habe keinen Startzeitpunkt ermitteln können"`
 | 
					        return `"habe keinen Startzeitpunkt ermitteln können"`
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const timeZone = 'Europe/Berlin'
 | 
					    const timeZone = 'Europe/Berlin'
 | 
				
			||||||
    const zonedDateTime = utcToZonedTime(event.scheduledStartAt, timeZone)
 | 
					    const zonedDateTime = utcToZonedTime(event.scheduledStartAt, timeZone)
 | 
				
			||||||
	const time = format(zonedDateTime, "HH:mm", { locale: de })
 | 
					    const time = format(zonedDateTime, "HH:mm", {locale: de})
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
	if (isToday(zonedDateTime)) {
 | 
					    if(isToday(zonedDateTime)) {
 | 
				
			||||||
        return `heute um ${time}`
 | 
					        return `heute um ${time}`
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const date = format(zonedDateTime, "eeee dd.MM", { locale: de })
 | 
					    const date = format(zonedDateTime, "eeee dd.MM", {locale: de})
 | 
				
			||||||
    return `am ${date} um ${time}`
 | 
					    return `am ${date} um ${time}`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -64,7 +64,7 @@ export class JellyfinHandler {
 | 
				
			|||||||
    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) {
 | 
					      if(createResult.policy) {
 | 
				
			||||||
        this.setUserPermissions(createResult, requestId, guildId)
 | 
					        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}"!`)
 | 
				
			||||||
@@ -74,8 +74,8 @@ export class JellyfinHandler {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public async setUserPermissions(user: UserDto, requestId: string, guildId?: string) {
 | 
					  public async setUserPermissions(user: UserDto, requestId: string, guildId?: string) {
 | 
				
			||||||
		if (!user.policy || !user.id) {
 | 
					    if(!user.policy || !user.id) {
 | 
				
			||||||
			logger.error(`Cannot update user policy. User ${user.name} has no policy to modify`, { guildId, requestId })
 | 
					      logger.error(`Cannot update user policy. User ${user.name} has no policy to modify`, {guildId, requestId}) 
 | 
				
			||||||
      return
 | 
					      return
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    user.policy.enableVideoPlaybackTranscoding = false
 | 
					    user.policy.enableVideoPlaybackTranscoding = false
 | 
				
			||||||
@@ -273,7 +273,7 @@ export class JellyfinHandler {
 | 
				
			|||||||
    let movieCount = 0
 | 
					    let movieCount = 0
 | 
				
			||||||
    let movieNames: string[]
 | 
					    let movieNames: string[]
 | 
				
			||||||
    do {
 | 
					    do {
 | 
				
			||||||
			movieNames = (await this.getRandomMovies(count, guildId, requestId)).filter(movie => movie.name && movie.name.length > 0).map(movie => <string>movie.name)
 | 
					      movieNames = (await this.getRandomMovies(count, guildId, requestId)).filter(movie => movie.name && movie.name.length > 0).map(movie => <string> movie.name)
 | 
				
			||||||
      movieCount = movieNames.length
 | 
					      movieCount = movieNames.length
 | 
				
			||||||
    } while (movieCount < count)
 | 
					    } while (movieCount < count)
 | 
				
			||||||
    return movieNames
 | 
					    return movieNames
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,7 +29,7 @@ export interface ConfigurationParameters {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export class Configuration {
 | 
					export class Configuration {
 | 
				
			||||||
	constructor(private configuration: ConfigurationParameters = {}) { }
 | 
					    constructor(private configuration: ConfigurationParameters = {}) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    set config(configuration: Configuration) {
 | 
					    set config(configuration: Configuration) {
 | 
				
			||||||
        this.configuration = configuration;
 | 
					        this.configuration = configuration;
 | 
				
			||||||
@@ -393,7 +393,7 @@ export interface ResponseTransformer<T> {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export class JSONApiResponse<T> {
 | 
					export class JSONApiResponse<T> {
 | 
				
			||||||
	constructor(public raw: Response, private transformer: ResponseTransformer<T> = (jsonValue: any) => jsonValue) { }
 | 
					    constructor(public raw: Response, private transformer: ResponseTransformer<T> = (jsonValue: any) => jsonValue) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async value(): Promise<T> {
 | 
					    async value(): Promise<T> {
 | 
				
			||||||
        return this.transformer(await this.raw.json());
 | 
					        return this.transformer(await this.raw.json());
 | 
				
			||||||
@@ -401,7 +401,7 @@ export class JSONApiResponse<T> {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export class VoidApiResponse {
 | 
					export class VoidApiResponse {
 | 
				
			||||||
	constructor(public raw: Response) { }
 | 
					    constructor(public raw: Response) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async value(): Promise<void> {
 | 
					    async value(): Promise<void> {
 | 
				
			||||||
        return undefined;
 | 
					        return undefined;
 | 
				
			||||||
@@ -409,7 +409,7 @@ export class VoidApiResponse {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export class BlobApiResponse {
 | 
					export class BlobApiResponse {
 | 
				
			||||||
	constructor(public raw: Response) { }
 | 
					    constructor(public raw: Response) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async value(): Promise<Blob> {
 | 
					    async value(): Promise<Blob> {
 | 
				
			||||||
        return await this.raw.blob();
 | 
					        return await this.raw.blob();
 | 
				
			||||||
@@ -417,7 +417,7 @@ export class BlobApiResponse {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export class TextApiResponse {
 | 
					export class TextApiResponse {
 | 
				
			||||||
	constructor(public raw: Response) { }
 | 
					    constructor(public raw: Response) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async value(): Promise<string> {
 | 
					    async value(): Promise<string> {
 | 
				
			||||||
        return await this.raw.text();
 | 
					        return await this.raw.text();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -130,7 +130,7 @@ export class ExtendedClient extends Client {
 | 
				
			|||||||
    for (const guild of guilds.values()) {
 | 
					    for (const guild of guilds.values()) {
 | 
				
			||||||
      logger.info("Starting background task for announcement role", { guildId: guild.id })
 | 
					      logger.info("Starting background task for announcement role", { guildId: guild.id })
 | 
				
			||||||
      const textChannel: Maybe<TextChannel> = this.getAnnouncementChannelForGuild(guild.id)
 | 
					      const textChannel: Maybe<TextChannel> = this.getAnnouncementChannelForGuild(guild.id)
 | 
				
			||||||
			if (!textChannel) {
 | 
					      if(!textChannel) {
 | 
				
			||||||
        logger.error("Could not find announcement channel. Aborting", { guildId: guild.id })
 | 
					        logger.error("Could not find announcement channel. Aborting", { guildId: guild.id })
 | 
				
			||||||
        return
 | 
					        return
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -174,7 +174,7 @@ export class ExtendedClient extends Client {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private async startPollCloseBackgroundTasks() {
 | 
					  private async startPollCloseBackgroundTasks() {
 | 
				
			||||||
		for (const guild of this.guilds.cache) {
 | 
					    for(const guild of this.guilds.cache) {
 | 
				
			||||||
      this.pollCloseBackgroundTasks.set(guild[1].id, schedule("0 * * * * *", () => checkForPollsToClose(guild[1])))
 | 
					      this.pollCloseBackgroundTasks.set(guild[1].id, schedule("0 * * * * *", () => checkForPollsToClose(guild[1])))
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,16 +0,0 @@
 | 
				
			|||||||
import { GuildScheduledEvent } from "discord.js"
 | 
					 | 
				
			||||||
import { createDateStringFromEvent } from "../../server/helper/dateHelper"
 | 
					 | 
				
			||||||
import MockDate from 'mockdate'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
beforeAll(() => {
 | 
					 | 
				
			||||||
  MockDate.set('01-01-2023')
 | 
					 | 
				
			||||||
})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function getTestDate(date: string): GuildScheduledEvent {
 | 
					 | 
				
			||||||
  return <GuildScheduledEvent>{ scheduledStartAt: new Date(date) }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
test('createDateStringFromEvent - correct formatting', () => {
 | 
					 | 
				
			||||||
  expect(createDateStringFromEvent(getTestDate('01-01-2023 12:30'), "")).toEqual('heute um 12:30')
 | 
					 | 
				
			||||||
  expect(createDateStringFromEvent(getTestDate('01-02-2023 12:30'), "")).toEqual('am Montag 02.01 um 12:30')
 | 
					 | 
				
			||||||
  expect(createDateStringFromEvent(getTestDate('01-03-2023 12:30'), "")).toEqual('am Dienstag 03.01 um 12:30')
 | 
					 | 
				
			||||||
})
 | 
					 | 
				
			||||||
@@ -1,28 +0,0 @@
 | 
				
			|||||||
import { Collection, GuildMember, Role } from "discord.js"
 | 
					 | 
				
			||||||
import { filterRolesFromMemberUpdate } from "../../server/helper/roleFilter"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function buildFakeRole(id: string, name: string): Role {
 | 
					 | 
				
			||||||
  return <Role>{ id, name }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
test('filterRolesFromMemberUpdate', () => {
 | 
					 | 
				
			||||||
  const oldMemberRoles: Collection<string, Role> = new Collection<string, Role>()
 | 
					 | 
				
			||||||
  oldMemberRoles.set('1', buildFakeRole('01', 'Role01'))
 | 
					 | 
				
			||||||
  oldMemberRoles.set('2', buildFakeRole('02', 'Role02'))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const newMemberRoles: Collection<string, Role> = new Collection<string, Role>()
 | 
					 | 
				
			||||||
  newMemberRoles.set('1', buildFakeRole('01', 'Role01'))
 | 
					 | 
				
			||||||
  newMemberRoles.set('2', buildFakeRole('02', 'Role02'))
 | 
					 | 
				
			||||||
  newMemberRoles.set('3', buildFakeRole('03', 'Role03'))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const oldMember: GuildMember = <GuildMember>{ roles: { cache: oldMemberRoles }, guild: { id: "guildid" } }
 | 
					 | 
				
			||||||
  const newMember: GuildMember = <GuildMember>{ roles: { cache: newMemberRoles }, guild: { id: "guildid" } }
 | 
					 | 
				
			||||||
  const output = filterRolesFromMemberUpdate(oldMember, newMember)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const expectedAddedRoles: Collection<string, Role> = new Collection<string, Role>()
 | 
					 | 
				
			||||||
  expectedAddedRoles.set('3', buildFakeRole('03', 'Role03'))
 | 
					 | 
				
			||||||
  const expectedRemovedRoles: Collection<string, Role> = new Collection<string, Role>()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  expect(output.addedRoles).toEqual(expectedAddedRoles)
 | 
					 | 
				
			||||||
  expect(output.removedRoles).toEqual(expectedRemovedRoles)
 | 
					 | 
				
			||||||
})
 | 
					 | 
				
			||||||
@@ -1,15 +0,0 @@
 | 
				
			|||||||
process.env.CLIENT_ID = "CLIENT_ID"
 | 
					 | 
				
			||||||
process.env.SECRET = "SECRET"
 | 
					 | 
				
			||||||
process.env.BOT_TOKEN = "BOT_TOKEN"
 | 
					 | 
				
			||||||
process.env.WATCHER_ROLE = "WATCHER_ROLE"
 | 
					 | 
				
			||||||
process.env.ADMIN_ROLE = "ADMIN_ROLE"
 | 
					 | 
				
			||||||
process.env.CHANNEL_ID = "CHANNEL_ID"
 | 
					 | 
				
			||||||
process.env.WATCHPARTY_ANNOUNCEMENT_ROLE = "WATCHPARTY_ANNOUNCEMENT_ROLE"
 | 
					 | 
				
			||||||
process.env.YAVIN_JELLYFIN_URL = "YAVIN_JELLYFIN_URL"
 | 
					 | 
				
			||||||
process.env.YAVIN_COLLECTION_ID = "YAVIN_COLLECTION_ID"
 | 
					 | 
				
			||||||
process.env.YAVIN_COLLECTION_USER = "YAVIN_COLLECTION_USER"
 | 
					 | 
				
			||||||
process.env.YAVIN_TOKEN = "YAVIN_TOKEN"
 | 
					 | 
				
			||||||
process.env.TOKEN = "TOKEN"
 | 
					 | 
				
			||||||
process.env.JELLYFIN_USER = "JELLYFIN_USER"
 | 
					 | 
				
			||||||
process.env.JELLYFIN_COLLECTION_ID = "JELLYFIN_COLLECTION_ID"
 | 
					 | 
				
			||||||
process.env.JELLYFIN_URL = "JELLYFIN_URL"
 | 
					 | 
				
			||||||
		Reference in New Issue
	
	Block a user