Compare commits
10 Commits
0d757fef79
...
pomodoro-b
| Author | SHA1 | Date | |
|---|---|---|---|
| 7a1f02ebd0 | |||
| f6bceb215c | |||
| 9914cd2bfb | |||
| fd2d5f5bff | |||
| 762bb989a2 | |||
| 4031291c38 | |||
| fca6927b08 | |||
| 56ec6a1ad8 | |||
| c1f0ae670d | |||
| 034d1c076c |
@@ -1,17 +1,16 @@
|
|||||||
name: release-tag
|
name: release-tag
|
||||||
|
|
||||||
on:
|
on: push
|
||||||
push
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
release-image:
|
release-image:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container:
|
container:
|
||||||
image: catthehacker/ubuntu:act-latest
|
image: catthehacker/ubuntu:act-latest
|
||||||
# env:
|
# env:
|
||||||
# DOCKER_ORG: teacup
|
# DOCKER_ORG: teacup
|
||||||
# DOCKER_LATEST: nightly
|
# DOCKER_LATEST: nightly
|
||||||
# RUNNER_TOOL_CACHE: /toolcache
|
# RUNNER_TOOL_CACHE: /toolcache
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
@@ -28,12 +27,12 @@ jobs:
|
|||||||
registry: git.unom.io # replace it with your local IP
|
registry: git.unom.io # replace it with your local IP
|
||||||
username: ${{ vars.DOCKER_USERNAME }}
|
username: ${{ vars.DOCKER_USERNAME }}
|
||||||
password: ${{ secrets.DOCKER_TOKEN }}
|
password: ${{ secrets.DOCKER_TOKEN }}
|
||||||
|
|
||||||
- name: Get Meta
|
- name: Get Meta
|
||||||
id: meta
|
id: meta
|
||||||
run: |
|
run: |
|
||||||
echo REPO_NAME=$(echo ${GITHUB_REPOSITORY} | awk -F"/" '{print $2}') >> $GITHUB_OUTPUT
|
echo REPO_NAME=$(echo ${GITHUB_REPOSITORY} | awk -F"/" '{print $2}') >> $GITHUB_OUTPUT
|
||||||
echo REPO_VERSION=$(git describe --tags --always | sed 's/^v//') >> $GITHUB_OUTPUT
|
echo REPO_VERSION=$(git describe --tags --always | sed 's/^v//') >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
- name: Build and push
|
- name: Build and push
|
||||||
uses: docker/build-push-action@v4
|
uses: docker/build-push-action@v4
|
||||||
@@ -42,8 +41,8 @@ jobs:
|
|||||||
file: ./Dockerfile
|
file: ./Dockerfile
|
||||||
platforms: |
|
platforms: |
|
||||||
linux/amd64
|
linux/amd64
|
||||||
linux/arm64
|
linux/arm64
|
||||||
push: true
|
push: true
|
||||||
tags: | # replace it with your local IP and tags
|
tags: | # replace it with your local IP and tags
|
||||||
git.unom.io/moriese/${{ steps.meta.outputs.REPO_NAME }}:${{ steps.meta.outputs.REPO_VERSION }}
|
git.unom.io/mo/${{ steps.meta.outputs.REPO_NAME }}:${{ steps.meta.outputs.REPO_VERSION }}
|
||||||
git.unom.io/moriese/${{ steps.meta.outputs.REPO_NAME }}:latest
|
git.unom.io/mo/${{ steps.meta.outputs.REPO_NAME }}:latest
|
||||||
|
|||||||
2
LICENSE
2
LICENSE
@@ -1,6 +1,6 @@
|
|||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2024 moriese
|
Copyright (c) 2024 mo (mo@unom.io)
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
services:
|
services:
|
||||||
avocadi-bot:
|
avocadi-bot:
|
||||||
container_name: avocadi-bot
|
container_name: avocadi-bot
|
||||||
image: git.unom.io/moriese/avocadi-bot:latest
|
image: git.unom.io/mo/avocadi-bot:latest
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
volumes:
|
volumes:
|
||||||
- ./.env:/usr/src/app/.env
|
- ./.env:/usr/src/app/.env
|
||||||
|
|||||||
48
src/actions/debug/debug.service.ts
Normal file
48
src/actions/debug/debug.service.ts
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
import { type CommandsType, Commands } from "commands";
|
||||||
|
import config from "config";
|
||||||
|
import type { CacheType, ChatInputCommandInteraction, Interaction } from "discord.js";
|
||||||
|
import { checkPermission } from "permissions";
|
||||||
|
|
||||||
|
export class DebugService {
|
||||||
|
|
||||||
|
async handleInteraction(
|
||||||
|
interaction: Interaction<CacheType>
|
||||||
|
) {
|
||||||
|
if (interaction.isChatInputCommand()) {
|
||||||
|
await this.handleChatInputCommand(interaction);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
async handleChatInputCommand(interaction: ChatInputCommandInteraction<CacheType>) {
|
||||||
|
const commandName = interaction.commandName as CommandsType;
|
||||||
|
switch (commandName) {
|
||||||
|
case Commands.Enum.version:
|
||||||
|
await this.version(interaction);
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async version(interaction: ChatInputCommandInteraction<CacheType>) {
|
||||||
|
try {
|
||||||
|
console.log("version command");
|
||||||
|
if (await checkPermission(interaction.member) !== true) {
|
||||||
|
await interaction.reply({
|
||||||
|
content: "du hast keine rechte fuer diesen befehl",
|
||||||
|
ephemeral: true,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await interaction.reply({
|
||||||
|
content: "version: " + config.discord.version,
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
console.error("error while sending version msg:", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import config from "config";
|
import config from "config";
|
||||||
import client from "lib/client";
|
import client from "lib/client";
|
||||||
import { getRandomInt } from "lib/utils";
|
import { getRandomInt } from "lib/utils";
|
||||||
import { } from "./dynamicChannel.components.ts";
|
import { } from "./dynamicVChannel.components.ts";
|
||||||
import {
|
import {
|
||||||
Client,
|
Client,
|
||||||
EmbedBuilder,
|
EmbedBuilder,
|
||||||
@@ -17,35 +17,33 @@ import {
|
|||||||
type VoiceBasedChannel,
|
type VoiceBasedChannel,
|
||||||
} from "discord.js";
|
} from "discord.js";
|
||||||
|
|
||||||
export class DynamicChannelService {
|
export class DynamicVChannelService {
|
||||||
async handleInteraction(interaction: Interaction<CacheType>) {
|
async handleInteraction(interaction: Interaction<CacheType>) {
|
||||||
// todo
|
// todo
|
||||||
}
|
}
|
||||||
|
|
||||||
async createChannel(
|
async createVChannel(
|
||||||
oldState: VoiceState,
|
|
||||||
newState: VoiceState,
|
newState: VoiceState,
|
||||||
channel: VoiceBasedChannel,
|
channel: VoiceBasedChannel
|
||||||
): Promise<StageChannel | VoiceChannel> {
|
): Promise<StageChannel | VoiceChannel> {
|
||||||
//console.log("createChannel()");
|
//console.log("createChannel()");
|
||||||
const newChannel = await channel.clone({
|
const newVChannel = await channel.clone({
|
||||||
name: `${channel.name.substring(2)}; ${newState.member?.displayName}`,
|
name: `${channel.name.substring(2)}; ${newState.member?.displayName}`,
|
||||||
position: 100,
|
position: 100,
|
||||||
});
|
});
|
||||||
|
|
||||||
return newChannel;
|
return newVChannel;
|
||||||
}
|
}
|
||||||
|
|
||||||
async deleteChannel(
|
async deleteVChannel(
|
||||||
oldState: VoiceState,
|
oldState: VoiceState,
|
||||||
newState: VoiceState,
|
newState: VoiceState,
|
||||||
newChannel: StageChannel | VoiceChannel,
|
newChannel: StageChannel | VoiceChannel,
|
||||||
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
||||||
channelListeners: Map<any, any>,
|
channelListeners: Map<any, any>,
|
||||||
channelListener: (oldState: VoiceState, newState: VoiceState) => void,
|
channelListener: (oldState: VoiceState, newState: VoiceState) => void
|
||||||
) {
|
) {
|
||||||
//console.log("deleteChannel()");
|
//console.log("deleteChannel()");
|
||||||
|
|
||||||
if (
|
if (
|
||||||
oldState.channelId === newChannel.id ||
|
oldState.channelId === newChannel.id ||
|
||||||
newState.channelId === newChannel.id
|
newState.channelId === newChannel.id
|
||||||
@@ -18,6 +18,7 @@ import {
|
|||||||
} from "discord.js";
|
} from "discord.js";
|
||||||
import { DmService } from "actions/dm/dm.service.ts";
|
import { DmService } from "actions/dm/dm.service.ts";
|
||||||
import { Commands, type CommandsType } from "commands/index.ts";
|
import { Commands, type CommandsType } from "commands/index.ts";
|
||||||
|
import { checkPermission } from "permissions/index.ts";
|
||||||
|
|
||||||
export class GreetingService {
|
export class GreetingService {
|
||||||
dmService: DmService;
|
dmService: DmService;
|
||||||
@@ -82,7 +83,7 @@ export class GreetingService {
|
|||||||
//console.log(input);
|
//console.log(input);
|
||||||
|
|
||||||
// permission check
|
// permission check
|
||||||
if (await this.checkPermission(interaction.member) !== true) {
|
if (await checkPermission(interaction.member) !== true) {
|
||||||
await interaction.reply({
|
await interaction.reply({
|
||||||
content: "du hast keine rechte fuer diesen befehl",
|
content: "du hast keine rechte fuer diesen befehl",
|
||||||
ephemeral: true,
|
ephemeral: true,
|
||||||
@@ -133,6 +134,7 @@ export class GreetingService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// unused
|
||||||
async greet() {
|
async greet() {
|
||||||
client.user?.setActivity("guten morgen! :3", { type: 4 });
|
client.user?.setActivity("guten morgen! :3", { type: 4 });
|
||||||
console.log("set activity: awake");
|
console.log("set activity: awake");
|
||||||
@@ -142,13 +144,14 @@ export class GreetingService {
|
|||||||
|
|
||||||
const channels = client.channels;
|
const channels = client.channels;
|
||||||
|
|
||||||
const channel = channels.cache.get(config.discord.testChannel);
|
const channel = channels.cache.get(config.discord.channelIdOffTopic);
|
||||||
|
|
||||||
if (channel?.isTextBased && channel?.isSendable()) {
|
if (channel?.isTextBased && channel?.isSendable()) {
|
||||||
await channel.send({ content: this.getContent(false) });
|
await channel.send({ content: this.getContent(false) });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// unused
|
||||||
async sleep() {
|
async sleep() {
|
||||||
client.user?.setActivity("zzzzZZ..", { type: 4 });
|
client.user?.setActivity("zzzzZZ..", { type: 4 });
|
||||||
console.log("set activity: asleep");
|
console.log("set activity: asleep");
|
||||||
@@ -158,7 +161,7 @@ export class GreetingService {
|
|||||||
|
|
||||||
const channels = client.channels;
|
const channels = client.channels;
|
||||||
|
|
||||||
const channel = channels.cache.get(config.discord.testChannel);
|
const channel = channels.cache.get(config.discord.channelIdOffTopic);
|
||||||
|
|
||||||
if (channel?.isTextBased && channel?.isSendable()) {
|
if (channel?.isTextBased && channel?.isSendable()) {
|
||||||
await channel.send({ content: this.getContent(true) });
|
await channel.send({ content: this.getContent(true) });
|
||||||
@@ -167,14 +170,15 @@ export class GreetingService {
|
|||||||
|
|
||||||
async newYear() {
|
async newYear() {
|
||||||
client.user?.setActivity("frohes neues! :)", { type: 4 });
|
client.user?.setActivity("frohes neues! :)", { type: 4 });
|
||||||
console.log("set activity: happy new Year");
|
console.log("set activity: happy new year");
|
||||||
client.user?.setPresence({
|
client.user?.setPresence({
|
||||||
status: "online",
|
status: "online",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// unused
|
||||||
/*const channels = client.channels;
|
/*const channels = client.channels;
|
||||||
|
|
||||||
const channel = channels.cache.get(config.discord.channelId);
|
const channel = channels.cache.get(config.discord.channelIdOffTopic);
|
||||||
|
|
||||||
if (channel?.isTextBased && channel?.isSendable()) {
|
if (channel?.isTextBased && channel?.isSendable()) {
|
||||||
await channel.send({ content: "frohes neues! @everyone" });
|
await channel.send({ content: "frohes neues! @everyone" });
|
||||||
@@ -199,7 +203,7 @@ export class GreetingService {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
// permission check
|
// permission check
|
||||||
if (await this.checkPermission(interaction.member) !== true) {
|
if (await checkPermission(interaction.member) !== true) {
|
||||||
await interaction.reply({
|
await interaction.reply({
|
||||||
content: "du hast keine rechte fuer diesen befehl",
|
content: "du hast keine rechte fuer diesen befehl",
|
||||||
ephemeral: true,
|
ephemeral: true,
|
||||||
@@ -271,7 +275,7 @@ export class GreetingService {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (await this.checkPermission(interaction.member) !== true) {
|
if (await checkPermission(interaction.member) !== true) {
|
||||||
await interaction.reply({
|
await interaction.reply({
|
||||||
content: "du hast keine rechte fuer diesen befehl",
|
content: "du hast keine rechte fuer diesen befehl",
|
||||||
ephemeral: true,
|
ephemeral: true,
|
||||||
@@ -322,17 +326,6 @@ export class GreetingService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async checkPermission(member: GuildMember | APIInteractionGuildMember | null) {
|
|
||||||
let permission = false;
|
|
||||||
if (member?.roles instanceof GuildMemberRoleManager) {
|
|
||||||
if (member.roles.cache.has(config.discord.roleAdmin) || member.roles.cache.has(config.discord.roleMod)) {
|
|
||||||
console.log("user has permission");
|
|
||||||
permission = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return permission;
|
|
||||||
}
|
|
||||||
|
|
||||||
async checkRole(member: GuildMember) {
|
async checkRole(member: GuildMember) {
|
||||||
let hasRole = false;
|
let hasRole = false;
|
||||||
if (member?.roles instanceof GuildMemberRoleManager) {
|
if (member?.roles instanceof GuildMemberRoleManager) {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ export default function createEmbed() { // ({ embeds: [exampleEmbed] })
|
|||||||
.setColor(0x004400)
|
.setColor(0x004400)
|
||||||
//.setTitle("/hilfe")
|
//.setTitle("/hilfe")
|
||||||
//.setURL("")
|
//.setURL("")
|
||||||
.setAuthor({ name: "avocadi - befehle", iconURL: "https://media.discordapp.net/attachments/1321933410188656693/1323447010380222474/mo_Avocadi_Avatar_Closeup_2.png?ex=67748b93&is=67733a13&hm=f48efb3523bca5f50e79144c7b41a127c94670e693e3da3dc2e6ffe62ad8a769&=&format=webp&quality=lossless&width=1524&height=1524", url: 'https://git.unom.io/moriese/avocadi-bot' })
|
.setAuthor({ name: "avocadi - befehle", iconURL: "https://media.discordapp.net/attachments/1321933410188656693/1323447010380222474/mo_Avocadi_Avatar_Closeup_2.png?ex=67748b93&is=67733a13&hm=f48efb3523bca5f50e79144c7b41a127c94670e693e3da3dc2e6ffe62ad8a769&=&format=webp&quality=lossless&width=1524&height=1524", url: 'https://git.unom.io/mo/avocadi-bot' })
|
||||||
.setDescription(" ")
|
.setDescription(" ")
|
||||||
.addFields(
|
.addFields(
|
||||||
{ name: `/${Commands.Enum.giessen}`, value: CommandsMeta.giessen.description },
|
{ name: `/${Commands.Enum.giessen}`, value: CommandsMeta.giessen.description },
|
||||||
|
|||||||
@@ -115,6 +115,7 @@ export class MedicationService {
|
|||||||
await interaction.reply({
|
await interaction.reply({
|
||||||
content:
|
content:
|
||||||
"es gab einen fehler beim verarbeiten deiner anfrage :( versuch es bitte spaeter nochmal, oki? c:",
|
"es gab einen fehler beim verarbeiten deiner anfrage :( versuch es bitte spaeter nochmal, oki? c:",
|
||||||
|
ephemeral: true,
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
0
src/actions/pomodoro/pomodoro.components.ts
Normal file
0
src/actions/pomodoro/pomodoro.components.ts
Normal file
42
src/actions/pomodoro/pomodoro.controller.ts
Normal file
42
src/actions/pomodoro/pomodoro.controller.ts
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
import config from "config";
|
||||||
|
import { Events, NewsChannel, type VoiceState } from "discord.js";
|
||||||
|
import client from "lib/client";
|
||||||
|
import EventEmitter from "node:events";
|
||||||
|
import { PomodoroService } from "actions/pomodoro/pomodoro.service";
|
||||||
|
|
||||||
|
export default class PomodoroController extends EventEmitter {
|
||||||
|
private pomodoroService: PomodoroService;
|
||||||
|
private activePomodoros = new Set<string>();
|
||||||
|
private pomodoroChannels = [config.discord.vchannelIdPomodoro25, config.discord.vchannelIdPomodoro50];
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.pomodoroService = new PomodoroService();
|
||||||
|
|
||||||
|
client.on(Events.VoiceStateUpdate, async (oldState, newState) => {
|
||||||
|
const userId = newState.id;
|
||||||
|
|
||||||
|
const joinedPomodoroVC = newState.channelId != null && this.pomodoroChannels.includes(newState.channelId) &&
|
||||||
|
oldState.channelId !== newState.channelId;
|
||||||
|
|
||||||
|
const leftPomodoroVC = oldState.channelId != null && this.pomodoroChannels.includes(oldState.channelId) &&
|
||||||
|
newState.channelId !== oldState.channelId;
|
||||||
|
|
||||||
|
if (leftPomodoroVC && this.activePomodoros.has(userId)) {
|
||||||
|
console.log("pomodoro left");
|
||||||
|
this.pomodoroService.stopPomodoro(userId);
|
||||||
|
this.activePomodoros.delete(userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (joinedPomodoroVC && !this.activePomodoros.has(userId)) {
|
||||||
|
console.log("pomodoro join");
|
||||||
|
const member = newState.member;
|
||||||
|
const vchannel = newState.channel;
|
||||||
|
if (!member || !vchannel) return;
|
||||||
|
|
||||||
|
this.activePomodoros.add(userId);
|
||||||
|
this.pomodoroService.startPomodoroLoop(member, vchannel);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
67
src/actions/pomodoro/pomodoro.service.ts
Normal file
67
src/actions/pomodoro/pomodoro.service.ts
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
import type { GuildMember, VoiceBasedChannel } from "discord.js";
|
||||||
|
import client from "lib/client";
|
||||||
|
import config from "config";
|
||||||
|
import { CustomMessageService } from "actions/customMessage/customMessage.service";
|
||||||
|
|
||||||
|
export class PomodoroService {
|
||||||
|
customMessageService: CustomMessageService;
|
||||||
|
private activeControllers = new Map<string, AbortController>();
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.customMessageService = new CustomMessageService();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async startPomodoroLoop(member: GuildMember, vchannel: VoiceBasedChannel) {
|
||||||
|
const userId = member.id;
|
||||||
|
const controller = new AbortController();
|
||||||
|
this.activeControllers.set(userId, controller);
|
||||||
|
|
||||||
|
const minutesWork = vchannel.id === config.discord.vchannelIdPomodoro25 ? 25 : 50;
|
||||||
|
const minutesBreak = minutesWork / 5;//vchannel.id === config.discord.vchannelIdPomodoro25 ? 5 : 10;
|
||||||
|
|
||||||
|
const signal = controller.signal;
|
||||||
|
|
||||||
|
try {
|
||||||
|
while (!signal.aborted) {
|
||||||
|
await this.sendMessage(`<@${userId}> 🍅 **pomodoro gestartet!** ${minutesWork} minuten produktivitaet`);
|
||||||
|
const finishedWork = await this.sleep(minutesWork * 60 * 1000, signal);
|
||||||
|
if (!finishedWork) break;
|
||||||
|
|
||||||
|
await this.sendMessage(`<@${userId}> ☕ **pause!** ${minutesBreak} minuten chillen`);
|
||||||
|
const finishedBreak = await this.sleep(minutesBreak * 60 * 1000, signal);
|
||||||
|
if (!finishedBreak) break;
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
if ((err as Error).name !== "AbortError") {
|
||||||
|
console.error("pomodoro fehler:", err);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
this.activeControllers.delete(userId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public stopPomodoro(userId: string) {
|
||||||
|
const controller = this.activeControllers.get(userId);
|
||||||
|
if (controller) {
|
||||||
|
controller.abort();
|
||||||
|
this.activeControllers.delete(userId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async sendMessage(text: string) {
|
||||||
|
const channel = client.channels.cache.get(config.discord.channelIdPomodoro);
|
||||||
|
if (channel?.isTextBased() && channel?.isSendable()) {
|
||||||
|
await channel.send(text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private sleep(ms: number, signal: AbortSignal): Promise<boolean> {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const timeout = setTimeout(() => resolve(true), ms);
|
||||||
|
signal.addEventListener("abort", () => {
|
||||||
|
clearTimeout(timeout);
|
||||||
|
resolve(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import { SlashCommandBuilder, userMention } from "discord.js";
|
import { SlashCommandBuilder, userMention } from "discord.js";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
export const Commands = z.enum(["giessen", "medikamente", "hilfe", "support", "kofi", "disboard", "discadia", "accept", "welcome", "embed", "message", "reminder"]);
|
export const Commands = z.enum(["giessen", "medikamente", "hilfe", "support", "kofi", "disboard", "discadia", "accept", "welcome", "embed", "message", "reminder", "version"]);
|
||||||
|
|
||||||
export const CommandsMeta: Record<z.output<typeof Commands>, { description: string }> = {
|
export const CommandsMeta: Record<z.output<typeof Commands>, { description: string }> = {
|
||||||
giessen: {
|
giessen: {
|
||||||
@@ -39,6 +39,9 @@ export const CommandsMeta: Record<z.output<typeof Commands>, { description: stri
|
|||||||
},
|
},
|
||||||
reminder: {
|
reminder: {
|
||||||
description: "admin use only"
|
description: "admin use only"
|
||||||
|
},
|
||||||
|
version: {
|
||||||
|
description: "admin use only"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,6 +113,9 @@ export default function getCommands() {
|
|||||||
option.setName('input')
|
option.setName('input')
|
||||||
.setDescription('input for bot')
|
.setDescription('input for bot')
|
||||||
.setRequired(true)),
|
.setRequired(true)),
|
||||||
|
new SlashCommandBuilder()
|
||||||
|
.setName(Commands.Enum.version)
|
||||||
|
.setDescription(CommandsMeta.version.description),
|
||||||
|
|
||||||
].map((command) => command.toJSON());
|
].map((command) => command.toJSON());
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
export default {
|
export default {
|
||||||
discord: {
|
discord: {
|
||||||
// test
|
version: 250602.10,
|
||||||
testChannel: process.env.DISCORD_TEST_CHANNEL_ID || "",
|
|
||||||
|
|
||||||
// avocadi
|
// avocadi
|
||||||
serverID: process.env.DISCORD_SERVER_ID || "",
|
serverID: process.env.DISCORD_SERVER_ID || "",
|
||||||
// texxt channel
|
// texxt channel
|
||||||
@@ -15,11 +13,14 @@ export default {
|
|||||||
channelIdIntroduction: process.env.DISCORD_CHANNEL_ID_INTRODUCTION || "",
|
channelIdIntroduction: process.env.DISCORD_CHANNEL_ID_INTRODUCTION || "",
|
||||||
channelIdOffTopic: process.env.DISCORD_CHANNEL_ID_OFF_TOPIC || "",
|
channelIdOffTopic: process.env.DISCORD_CHANNEL_ID_OFF_TOPIC || "",
|
||||||
channelIdHelp: process.env.DISCORD_CHANNEL_ID_HELP || "",
|
channelIdHelp: process.env.DISCORD_CHANNEL_ID_HELP || "",
|
||||||
// voice channel#
|
channelIdPomodoro: process.env.DISCORD_CHANNEL_ID_POMODORO || "",
|
||||||
|
// voice channel
|
||||||
vchannelIdForTwo: process.env.DISCORD_VCHANNEL_ID_FOR_TWO || "",
|
vchannelIdForTwo: process.env.DISCORD_VCHANNEL_ID_FOR_TWO || "",
|
||||||
vchannelIdForThree: process.env.DISCORD_VCHANNEL_ID_FOR_THREE || "",
|
vchannelIdForThree: process.env.DISCORD_VCHANNEL_ID_FOR_THREE || "",
|
||||||
vchannelIdForFour: process.env.DISCORD_VCHANNEL_ID_FOR_FOUR || "",
|
vchannelIdForFour: process.env.DISCORD_VCHANNEL_ID_FOR_FOUR || "",
|
||||||
vchannelIdForGroup: process.env.DISCORD_VCHANNEL_ID_FOR_GROUP || "",
|
vchannelIdForGroup: process.env.DISCORD_VCHANNEL_ID_FOR_GROUP || "",
|
||||||
|
vchannelIdPomodoro25: process.env.DISCORD_VCHANNEL_ID_POMODORO_25_5 || "",
|
||||||
|
vchannelIdPomodoro50: process.env.DISCORD_VCHANNEL_ID_POMODORO_50_10 || "",
|
||||||
// roles
|
// roles
|
||||||
roleStudy: process.env.PEOPLE || "",
|
roleStudy: process.env.PEOPLE || "",
|
||||||
roleMod: process.env.MOD || "",
|
roleMod: process.env.MOD || "",
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import {
|
|||||||
} from "discord.js";
|
} from "discord.js";
|
||||||
import client from "lib/client";
|
import client from "lib/client";
|
||||||
import EventEmitter from "node:events";
|
import EventEmitter from "node:events";
|
||||||
import DiscordService from "services/discord.service";
|
import DiscordService from "discord.service";
|
||||||
import { WaterMeService } from "actions/waterMe/waterMe.service";
|
import { WaterMeService } from "actions/waterMe/waterMe.service";
|
||||||
import { MedicationService } from "actions/medication/medication.service";
|
import { MedicationService } from "actions/medication/medication.service";
|
||||||
import { HelpService } from "actions/help/help.service";
|
import { HelpService } from "actions/help/help.service";
|
||||||
@@ -22,24 +22,27 @@ import { GreetingService } from "actions/greeting/greeting.service";
|
|||||||
import { ActivityService } from "actions/activity/activity.service";
|
import { ActivityService } from "actions/activity/activity.service";
|
||||||
import { DmService } from "actions/dm/dm.service";
|
import { DmService } from "actions/dm/dm.service";
|
||||||
import { CustomMessageService } from "actions/customMessage/customMessage.service";
|
import { CustomMessageService } from "actions/customMessage/customMessage.service";
|
||||||
import { DynamicChannelService } from "actions/dynamicChannel/dynamicChannel.service";
|
import { DynamicVChannelService } from "actions/dynamicVChannel/dynamicVChannel.service";
|
||||||
|
import { DebugService } from "actions/debug/debug.service";
|
||||||
import { ReactRolesService } from "actions/reactRole/reactRoles.service";
|
import { ReactRolesService } from "actions/reactRole/reactRoles.service";
|
||||||
import config from "config";
|
import config from "config";
|
||||||
|
|
||||||
export default class DiscordController extends EventEmitter {
|
export default class DiscordController extends EventEmitter {
|
||||||
private discordService!: DiscordService;
|
private discordService: DiscordService;
|
||||||
waterMeService: WaterMeService;
|
private waterMeService: WaterMeService;
|
||||||
greetingService: GreetingService;
|
private greetingService: GreetingService;
|
||||||
medicationService: MedicationService;
|
private medicationService: MedicationService;
|
||||||
helpService: HelpService;
|
private helpService: HelpService;
|
||||||
supportService: SupportService;
|
private supportService: SupportService;
|
||||||
activityService: ActivityService;
|
private activityService: ActivityService;
|
||||||
dmService: DmService;
|
private dmService: DmService;
|
||||||
customMessageService: CustomMessageService;
|
private customMessageService: CustomMessageService;
|
||||||
channelListeners = new Map();
|
private dynamicVChannelService: DynamicVChannelService;
|
||||||
dynamicChannelService: DynamicChannelService;
|
private debugService: DebugService;
|
||||||
reactRolesService: ReactRolesService;
|
|
||||||
version = 250222.2319;
|
private channelListeners = new Map();
|
||||||
|
private reactRolesService: ReactRolesService;
|
||||||
|
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
@@ -53,7 +56,8 @@ export default class DiscordController extends EventEmitter {
|
|||||||
this.activityService = new ActivityService();
|
this.activityService = new ActivityService();
|
||||||
this.dmService = new DmService();
|
this.dmService = new DmService();
|
||||||
this.customMessageService = new CustomMessageService();
|
this.customMessageService = new CustomMessageService();
|
||||||
this.dynamicChannelService = new DynamicChannelService();
|
this.dynamicVChannelService = new DynamicVChannelService();
|
||||||
|
this.debugService = new DebugService();
|
||||||
this.reactRolesService = new ReactRolesService();
|
this.reactRolesService = new ReactRolesService();
|
||||||
|
|
||||||
client.on("messageReactionAdd", async (reaction, user) => {
|
client.on("messageReactionAdd", async (reaction, user) => {
|
||||||
@@ -106,38 +110,19 @@ export default class DiscordController extends EventEmitter {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
// create new channel with same settings
|
const newChannel = await this.dynamicVChannelService.createVChannel(
|
||||||
/*const newChannel = await channel.clone({
|
|
||||||
name: channel.name + "; " + newState.member?.displayName,
|
|
||||||
position: channel.position
|
|
||||||
});*/
|
|
||||||
|
|
||||||
const newChannel = await this.dynamicChannelService.createChannel(
|
|
||||||
oldState,
|
|
||||||
newState,
|
newState,
|
||||||
channel,
|
channel,
|
||||||
);
|
);
|
||||||
|
|
||||||
// move user in new channel
|
// move user in new channel
|
||||||
await newState.setChannel(newChannel);
|
await newState.setChannel(newChannel);
|
||||||
|
|
||||||
// create specific listener for channel
|
// create specific listener for channel
|
||||||
const channelListener = async (
|
const channelListener = async (
|
||||||
oldState: VoiceState,
|
oldState: VoiceState,
|
||||||
newState: VoiceState,
|
newState: VoiceState,
|
||||||
) => {
|
) => {
|
||||||
/*if (oldState.channelId === newChannel.id || newState.channelId === newChannel.id) {
|
|
||||||
// check if channel empty
|
|
||||||
if (newChannel.members.size === 0) {
|
|
||||||
newChannel.delete()
|
|
||||||
.catch(console.error);
|
|
||||||
// delete listener for this channel
|
|
||||||
client.removeListener(Events.VoiceStateUpdate, channelListener);
|
|
||||||
channelListeners.delete(newChannel.id);
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
channelListeners =
|
channelListeners =
|
||||||
await this.dynamicChannelService.deleteChannel(
|
await this.dynamicVChannelService.deleteVChannel(
|
||||||
oldState,
|
oldState,
|
||||||
newState,
|
newState,
|
||||||
newChannel,
|
newChannel,
|
||||||
@@ -147,7 +132,6 @@ export default class DiscordController extends EventEmitter {
|
|||||||
};
|
};
|
||||||
// save listener in map
|
// save listener in map
|
||||||
channelListeners.set(newChannel.id, channelListener);
|
channelListeners.set(newChannel.id, channelListener);
|
||||||
|
|
||||||
// add listener
|
// add listener
|
||||||
client.on(Events.VoiceStateUpdate, channelListener);
|
client.on(Events.VoiceStateUpdate, channelListener);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -157,7 +141,7 @@ export default class DiscordController extends EventEmitter {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
console.log(`----------------\nversion ${this.version}\n----------------`);
|
console.log(`----------------\nversion ${config.discord.version}\n----------------`);
|
||||||
}
|
}
|
||||||
|
|
||||||
async setActivity() {
|
async setActivity() {
|
||||||
@@ -235,6 +219,9 @@ export default class DiscordController extends EventEmitter {
|
|||||||
case Commands.Enum.reminder:
|
case Commands.Enum.reminder:
|
||||||
await this.greetingService.handleChatInputCommand(interaction);
|
await this.greetingService.handleChatInputCommand(interaction);
|
||||||
return;
|
return;
|
||||||
|
case Commands.Enum.version:
|
||||||
|
await this.debugService.handleChatInputCommand(interaction);
|
||||||
|
return;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2,10 +2,13 @@ import "actions/waterMe/waterMe.task";
|
|||||||
import "actions/greeting/greeting.task";
|
import "actions/greeting/greeting.task";
|
||||||
import "actions/medication/medication.task";
|
import "actions/medication/medication.task";
|
||||||
import "actions/drink/drink.task";
|
import "actions/drink/drink.task";
|
||||||
import DiscordController from "controllers/discord.controller";
|
import DiscordController from "discord.controller";
|
||||||
|
import PomodoroController from "actions/pomodoro/pomodoro.controller";
|
||||||
|
|
||||||
import "dotenv/config";
|
import "dotenv/config";
|
||||||
|
|
||||||
// bootstrap application
|
// bootstrap application
|
||||||
const discordController = new DiscordController();
|
const discordController = new DiscordController();
|
||||||
discordController.init();
|
const pomodoroController = new PomodoroController();
|
||||||
|
|
||||||
|
discordController.init();
|
||||||
13
src/permissions/index.ts
Normal file
13
src/permissions/index.ts
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import config from "config";
|
||||||
|
import { GuildMember, GuildMemberRoleManager, type APIInteractionGuildMember } from "discord.js";
|
||||||
|
|
||||||
|
export async function checkPermission(member: GuildMember | APIInteractionGuildMember | null) {
|
||||||
|
let permission = false;
|
||||||
|
if (member?.roles instanceof GuildMemberRoleManager) {
|
||||||
|
if (member.roles.cache.has(config.discord.roleAdmin) || member.roles.cache.has(config.discord.roleMod)) {
|
||||||
|
permission = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log("user permission == " + permission);
|
||||||
|
return permission;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user