Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
OrigamingWasTaken committed Dec 14, 2023
2 parents 5ec73dc + 2acc6b6 commit ca43c3c
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 28 deletions.
4 changes: 3 additions & 1 deletion config/bot/info.yml
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
App Name: 'ce-discord-bot'
Color: '#0D9488'
Color: '#0D9488'
Admins:
- "657938099581616139"
25 changes: 18 additions & 7 deletions src/alerts/hander.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,18 @@ const mongo = new MongoClient(process.env.mongoUri, {
}
});

let doingAlert = false;
export async function alert(data: EventAlert, client: Client) {
if (doingAlert) return
doingAlert = true
await mongo.connect()
const db: Db = mongo.db("discord")
const collection = db.collection("servers")

const servers: DiscordServerInfo[] = await collection.find({ enabled: true }).toArray()
// Sends in each server
servers.forEach(async server => {
if (!server.sources) return
if (!server.sources.includes(data.guild.id)) return
if (!server.channel) return
let channel: Channel;
Expand All @@ -31,25 +35,32 @@ export async function alert(data: EventAlert, client: Client) {
}
if (!channel.isTextBased()) return
const embed = new EmbedBuilder()
.setTitle(`Nouvel Event - ${data.eventSource.name}`)
.setDescription(`Un event a été détecté sur le serveur discord "${data.eventSource.name}". Pour plus d'informations, rendez-vous ci-dessous.\n\n`)
.setFields({ name: "Contenu du message", value: data.message.data.content })
.setTitle(`Nouvel Event - ${data.eventSource.name}`)
.setDescription(`Un event a été détecté sur le serveur discord __"${data.eventSource.name}"__. Pour plus d'informations, rendez-vous ci-dessous.\n\n`)
.setColor(BotInfo.Color)
.setThumbnail(data.guild.iconUrl)
const embed2 = new EmbedBuilder()
.setColor("#127065")
.setDescription(data.message.data.content.replace(/@/g, "`@`"))
const embed3 = new EmbedBuilder()
.setDescription("Pour plus d'informations, rendez-vous à l'annonce.")
.setColor(BotInfo.Color)
.setTimestamp()
.setFooter({ text: "By Communauté Events - https://github.com/communaute-events" })
const button = new ButtonBuilder()
.setStyle(ButtonStyle.Link)
.setURL(data.message.url)
.setLabel("Aller à l'annonce")
const row = new ActionRowBuilder<ButtonBuilder>()
.addComponents(button)
try {
const formattedStrings: string[] = Object.values(server.roles).map((roleId) => `<@&${roleId}>`);
const formattedString: string = formattedStrings.join(', ');
channel.send({ content: server.roles ? formattedString : "@here", embeds: [embed], components: [row] })
const formattedString: string = `<@&${server.roles[data.eventSource.guildId]}>`
// const formattedStrings: string[] = Object.values(server.roles).map((roleId) => `<@&${roleId}>`);
// const formattedString: string = formattedStrings.join(', ');
channel.send({ content: server.roles ? formattedString : "@here", embeds: [embed] })
channel.send({ embeds: [embed2,embed3], components: [row] })
} catch (err) {
// Missing permissions in channel
}
})
doingAlert = false
}
15 changes: 15 additions & 0 deletions src/events/messageCreate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { BotConfig } from "@src/types";
import { Message } from "discord.js";
import { reconnectWebsocket } from "..";
const BotInfo: BotConfig = loadYaml("bot/info.yml")

export const event = {
name: "messageCreate",
async execute(message: Message) {
if (message.content == "!ws reload" && BotInfo.Admins.includes(message.author.id)) {
message.reply("Restarting websockets.")
await reconnectWebsocket()
message.reply("Websocket should be up. See the console.")
}
}
}
109 changes: 90 additions & 19 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,102 @@ import { initEvents } from "./core/events"
import { alert } from "./alerts/hander"

// Imports
import { Client, Events, GatewayIntentBits } from "discord.js"
import { Client, Events, GatewayIntentBits, messageLink } from "discord.js"
import { WebSocket } from "ws"
import fetch from "cross-fetch"

// Main
const client = new Client({intents: [GatewayIntentBits.Guilds]});
const client = new Client({intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.MessageContent]});
(async()=>{
client.commands = await getCommands()
})()

// function checkWs(ws: WebSocket) {
// if (ws.readyState != WebSocket.OPEN) {
// logging(`WebSocket connection has been established. The bot is operational.`,"success")
// } else {
// setTimeout(checkWs,500)
// }
// }

let websockets: WebSocket[] = []
let isReconnecting;

export function closeWebsockets() {
websockets.forEach(ws => {
const url = ws.url
ws.terminate()
logging(`Closed ws "${url}" at "${new Date().toISOString()}"`,"minimal")
})
websockets = []
}

export async function wsConnect(): Promise<WebSocket> {
function wsError(error) {
if (isReconnecting) return
isReconnecting = true
logging(`WebSocket error, retrying to connect in 10 seconds.\n${error}: ${error.message}`, "error");
// Retry after 10 seconds
setTimeout(wsConnect, 10000);
}

isReconnecting = false
try {
const response = await fetch("https://raw.githubusercontent.com/Communaute-Events/paths/main/paths.json", {
method: "GET",
headers: { "Content-Type": "application/json" }
});

const res = await response.json();
const ws = new WebSocket(res.websocket)

// checkWs(ws)
websockets.push(ws)

ws.on("message", msg => {
try {
const data = JSON.parse(msg.toString());
if ("_type" in data && data._type === "event") {
alert(data, client);
}
} catch (error) {
logging(`Error in ws:\n${error}`,"error");
}
});

ws.on("close", (code, reason) => {
wsError({message: reason})
});

ws.on("error", error => {
wsError(error)
});

ws.on("open",()=> {
logging(`WebSocket connection has been established. The bot is operational.`,"success")
})
return ws
} catch (error) {
wsError({message: error})
}
}

export async function reconnectWebsocket() {
logging("Reconnecting to the WebSocket...","info")
logging(`Closed all Websockets. (3 sec delay)`,"info")
closeWebsockets()
await setTimeout(()=>{},3000)
logging("Re-establishing connection...","info")
const ws = await wsConnect()
logging(`Connection should be up. Current state: ${ws.readyState}`,`success`)
}

async function automaticWsRestart() {
logging(`Automatically restarting websocket (10min interval)`,"info")
await reconnectWebsocket()
logging(`Finished automated restarting function.`,"success")
}

client.once(Events.ClientReady, async(c) => {
logging("Init. Client...","info")
logging(ansi(`Logged in as %bold%${c.user.tag}%end%%light_green%!%end%`),"success");
Expand All @@ -28,23 +114,8 @@ client.once(Events.ClientReady, async(c) => {
await deployCommands()
logging(`All slash commands have been deployed.`,"success")
logging(`Connecting to the Event Websocket`,"info")
await fetch("https://raw.githubusercontent.com/Communaute-Events/paths/main/paths.json",{
method: "GET",
headers: { "Content-Type": "application/json" }
}).then(res => res.json().then(res => {
const ws = new WebSocket(res.websocket)
ws.on("message",msg => {
try {
const data = JSON.parse(msg.toString())
if ("_type" in data && data._type == "event") {
alert(data, client)
}
} catch (error) {
console.log(`Error in ws:\n${error}`)
}
})
}))
logging(`Connection to the websocket has been established. The bot is ready to run!`,"success")
await wsConnect()
setInterval(automaticWsRestart,600000)
});

// Login, needs to be at the bottom
Expand Down
3 changes: 2 additions & 1 deletion src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ export interface EventSource {

export interface BotConfig {
'App Name': string
Color: `#${string}`
Color: `#${string}`,
Admins: string[]
}

export interface HelpCommandCategory {
Expand Down

0 comments on commit ca43c3c

Please sign in to comment.