All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 3m43s
140 lines
6.8 KiB
TypeScript
140 lines
6.8 KiB
TypeScript
import { Events, ActivityType, ChannelType } from "discord.js"
|
|
import type { Client } from "discord.js"
|
|
import { useMainPlayer } from "discord-player"
|
|
import { SpotifyExtractor } from "@discord-player/extractor"
|
|
import { YoutubeiExtractor } from "discord-player-youtubei"
|
|
import { connect } from "mongoose"
|
|
import type { Document } from "mongoose"
|
|
import { playerDisco, playerReplay } from "@/utils/player"
|
|
import { twitchClient, listener, onlineSub, offlineSub, startStreamWatching } from "@/utils/twitch"
|
|
import { logConsole, logConsoleError } from "@/utils/console"
|
|
import type { GuildPlayer, Disco, GuildTwitch, GuildFbx } from "@/types/schemas"
|
|
import * as Freebox from "@/utils/freebox"
|
|
import dbGuildInit from "@/utils/dbGuildInit"
|
|
import dbGuild from "@/schemas/guild"
|
|
|
|
export const name = Events.ClientReady
|
|
export const once = true
|
|
export async function execute(client: Client) {
|
|
logConsole('discordjs', 'ready', { tag: client.user?.tag ?? "unknown" })
|
|
client.user?.setActivity("some bangers...", { type: ActivityType.Listening })
|
|
|
|
const player = useMainPlayer()
|
|
await player.extractors.register(SpotifyExtractor, {}).then(() => { logConsole('discord_player', 'extractor_loaded', { extractor: 'Spotify' }) }).catch(console.error)
|
|
await player.extractors.register(YoutubeiExtractor, {}).then(() => { logConsole('discord_player', 'extractor_loaded', { extractor: 'Youtube' }) }).catch(console.error)
|
|
if (process.env.NODE_ENV === "development") console.log(player.scanDeps())
|
|
|
|
const mongo_url = `mongodb://${process.env.MONGOOSE_USER}:${process.env.MONGOOSE_PASSWORD}@${process.env.MONGOOSE_HOST}/${process.env.MONGOOSE_DATABASE}`
|
|
await connect(mongo_url).catch(console.error)
|
|
|
|
if (process.env.NODE_ENV === "development") await twitchClient.eventSub.deleteAllSubscriptions()
|
|
const streamerIds: string[] = []
|
|
|
|
await Promise.all(client.guilds.cache.map(async guild => {
|
|
let guildProfile = await dbGuild.findOne({ guildId: guild.id })
|
|
guildProfile ??= await dbGuildInit(guild)
|
|
|
|
const dbDataPlayer = guildProfile.get("guildPlayer") as GuildPlayer
|
|
const botInstance = dbDataPlayer.instances?.find(instance => instance.botId === client.user?.id)
|
|
if (botInstance?.replay.trackUrl) await playerReplay(client, dbDataPlayer)
|
|
|
|
client.disco = { interval: {} as NodeJS.Timeout }
|
|
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
client.disco.interval = setInterval(async () => {
|
|
const guildProfile = await dbGuild.findOne({ guildId: guild.id })
|
|
const dbDataDisco = guildProfile?.get("guildPlayer.disco") as Disco
|
|
|
|
if (dbDataDisco.enabled) {
|
|
const state = await playerDisco(client, guild, dbDataDisco)
|
|
if (state === "clear") clearInterval(client.disco.interval)
|
|
}
|
|
}, 3000)
|
|
|
|
// Gestion du timer LCD Freebox
|
|
const dbDataFbx = guildProfile.get("guildFbx") as GuildFbx
|
|
if (dbDataFbx.enabled && dbDataFbx.lcd) {
|
|
if (dbDataFbx.lcd.enabled && dbDataFbx.lcd.botId === client.user?.id) {
|
|
logConsole('freebox', 'lcd_timer_restored', { guild: guild.name })
|
|
Freebox.Timer.schedule(client, guild.id, dbDataFbx)
|
|
}
|
|
}
|
|
|
|
const dbDataTwitch = guildProfile.get("guildTwitch") as GuildTwitch
|
|
if (!dbDataTwitch.enabled) return
|
|
if (!dbDataTwitch.streamers.length) { logConsole('twitch', 'ready.no_streamers_configured', { guild: guild.name }); return }
|
|
|
|
await Promise.all(dbDataTwitch.streamers.map(async streamer => {
|
|
if (streamerIds.includes(streamer.twitchUserId)) return
|
|
streamerIds.push(streamer.twitchUserId)
|
|
|
|
const user = await twitchClient.users.getUserById(streamer.twitchUserId)
|
|
if (!user) { logConsole('twitch', 'ready.user_not_found', { guild: guild.name, userId: streamer.twitchUserId }); return }
|
|
|
|
const userSubs = await twitchClient.eventSub.getSubscriptionsForUser(streamer.twitchUserId)
|
|
if (!userSubs.data.find(sub => sub.transportMethod === "webhook" && sub.type === "stream.online")) {
|
|
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
listener.onStreamOnline(streamer.twitchUserId, onlineSub)
|
|
logConsole('twitch', 'listener_registered', { type: 'stream.online', name: user.name, id: streamer.twitchUserId })
|
|
}
|
|
if (!userSubs.data.find(sub => sub.transportMethod === "webhook" && sub.type === "stream.offline")) {
|
|
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
listener.onStreamOffline(streamer.twitchUserId, offlineSub)
|
|
logConsole('twitch', 'listener_registered', { type: 'stream.offline', name: user.name, id: streamer.twitchUserId })
|
|
}
|
|
|
|
logConsole('twitch', 'user_operational', { name: user.name, id: streamer.twitchUserId })
|
|
|
|
const stream = await user.getStream()
|
|
if (stream && streamer.messageId) {
|
|
logConsole('twitch', 'ready.stream_restoration', { guild: guild.name, userName: user.name, userId: streamer.twitchUserId })
|
|
|
|
// Vérifier que le message existe encore
|
|
if (!dbDataTwitch.channelId) return
|
|
const channel = await guild.channels.fetch(dbDataTwitch.channelId)
|
|
if (channel && (channel.type === ChannelType.GuildText || channel.type === ChannelType.GuildAnnouncement)) {
|
|
try {
|
|
await channel.messages.fetch(streamer.messageId)
|
|
startStreamWatching(guild.id, streamer.twitchUserId, user.name, streamer.messageId)
|
|
logConsole('twitch', 'ready.monitoring_restored', { guild: guild.name, userName: user.name })
|
|
} catch (error) {
|
|
logConsoleError('twitch', 'ready.message_not_found', { guild: guild.name, userName: user.name }, error as Error)
|
|
await cleanupMessageId(guildProfile, streamer.twitchUserId)
|
|
}
|
|
}
|
|
} else if (streamer.messageId) {
|
|
// Il y a un messageId mais le stream n'est plus en ligne, nettoyer
|
|
logConsole('twitch', 'ready.stream_offline_cleanup', { guild: guild.name, userName: user.name })
|
|
await cleanupMessageId(guildProfile, streamer.twitchUserId)
|
|
}
|
|
|
|
logConsole('twitch', 'user_operational', { name: user.name, id: streamer.twitchUserId })
|
|
}))
|
|
}))
|
|
|
|
const subs = await twitchClient.eventSub.getSubscriptions()
|
|
await Promise.all(subs.data.map(async sub => {
|
|
if (streamerIds.includes(sub.condition.broadcaster_user_id as string)) return
|
|
if (sub.type !== "stream.online" && sub.type !== "stream.offline") return
|
|
|
|
await sub.unsubscribe().catch(console.error)
|
|
logConsole('twitch', 'unsubscribed', { type: sub.type, id: sub.condition.broadcaster_user_id as string })
|
|
}))
|
|
}
|
|
|
|
async function cleanupMessageId(guildProfile: Document, twitchUserId: string) {
|
|
try {
|
|
const dbData = guildProfile.get("guildTwitch") as GuildTwitch
|
|
|
|
const streamerIndex = dbData.streamers.findIndex(s => s.twitchUserId === twitchUserId)
|
|
if (streamerIndex === -1) return
|
|
|
|
dbData.streamers[streamerIndex].messageId = ""
|
|
|
|
guildProfile.set("guildTwitch", dbData)
|
|
guildProfile.markModified("guildTwitch")
|
|
await guildProfile.save().catch(console.error)
|
|
} catch (error) {
|
|
logConsoleError('twitch', 'ready.cleanup_error', { userId: twitchUserId }, error as Error)
|
|
}
|
|
}
|