Compare commits
3 Commits
0d757fef79
...
56ec6a1ad8
Author | SHA1 | Date | |
---|---|---|---|
56ec6a1ad8 | |||
c1f0ae670d | |||
034d1c076c |
@ -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
|
@ -133,6 +133,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 +143,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 +160,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 +169,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" });
|
||||||
|
0
src/actions/pomodoro/pomodoro.components.ts
Normal file
0
src/actions/pomodoro/pomodoro.components.ts
Normal file
41
src/actions/pomodoro/pomodoro.controller.ts
Normal file
41
src/actions/pomodoro/pomodoro.controller.ts
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
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 !== config.discord.vchannelIdPomodoro25;
|
||||||
|
|
||||||
|
if (joinedPomodoroVC && !this.activePomodoros.has(userId)) {
|
||||||
|
const member = newState.member;
|
||||||
|
const vchannel = newState.channel;
|
||||||
|
if (!member || !vchannel) return;
|
||||||
|
|
||||||
|
this.activePomodoros.add(userId);
|
||||||
|
this.pomodoroService.startPomodoroLoop(member, vchannel);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (leftPomodoroVC && this.activePomodoros.has(userId)) {
|
||||||
|
this.pomodoroService.stopPomodoro(userId);
|
||||||
|
this.activePomodoros.delete(userId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
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,8 +1,6 @@
|
|||||||
export default {
|
export default {
|
||||||
discord: {
|
discord: {
|
||||||
// test
|
version: 250508.2150,
|
||||||
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,24 @@ 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 { 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 channelListeners = new Map();
|
||||||
dynamicChannelService: DynamicChannelService;
|
private dynamicVChannelService: DynamicVChannelService;
|
||||||
reactRolesService: ReactRolesService;
|
private reactRolesService: ReactRolesService;
|
||||||
version = 250222.2319;
|
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
@ -53,7 +53,7 @@ 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.reactRolesService = new ReactRolesService();
|
this.reactRolesService = new ReactRolesService();
|
||||||
|
|
||||||
client.on("messageReactionAdd", async (reaction, user) => {
|
client.on("messageReactionAdd", async (reaction, user) => {
|
||||||
@ -106,38 +106,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 +128,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 +137,7 @@ export default class DiscordController extends EventEmitter {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
console.log(`----------------\nversion ${this.version}\n----------------`);
|
console.log(`----------------\nversion ${config.discord.version}\n----------------`);
|
||||||
}
|
}
|
||||||
|
|
||||||
async setActivity() {
|
async setActivity() {
|
@ -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();
|
Loading…
x
Reference in New Issue
Block a user