├── README.md ├── config.json ├── data ├── enmap.sqlite ├── enmap.sqlite-shm └── enmap.sqlite-wal ├── index.js ├── modmail.js ├── package-lock.json └── package.json /README.md: -------------------------------------------------------------------------------- 1 |

2 | 📬ModMail Bot⚙ 3 |

4 | 5 | --- 6 | ## 🔱 » Menu 7 | 8 | - [☄・Deploys](#deploys) 9 | - [🔰・Features](#features) 10 | - [🌌・Discord](https://discord.gg/zM6ZN9UfRs) 11 | - [🎉・Setting up](#setup) 12 | - [⚙・Config](#config) 13 | ## ☄ » Deploys 14 | > [Deploy with REPLIT](https://replit.com/github/Nekros-dsc/ModMail-Bot) 15 | 16 | ## 🛠 » Features 17 | 18 | 19 | ## 📁 » Setting up 20 | 21 | 1. Install [Nodejs](https://nodejs.org/) 22 | 2. Open up [config.json](https://discord.gg/zM6ZN9UfRs) with notepad or some other editor 23 | 24 | # ⚙ » Config 25 | 26 | If you want to change the config, open up [config.json](https://discord.gg/zM6ZN9UfRs) and locate it at the top. There you can configure the following: 27 | 28 | ```js 29 | { 30 | "token": "TOKEN", 31 | "prefix": "m!" 32 | } 33 | ``` 34 | 35 | --- -------------------------------------------------------------------------------- /config.json: -------------------------------------------------------------------------------- 1 | { 2 | "token": "TOKEN", 3 | "prefix": "m!" 4 | } -------------------------------------------------------------------------------- /data/enmap.sqlite: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nekros-dsc/ModMail-Bot/8121599f102074736b22d9ff1cfe4c482c5babcd/data/enmap.sqlite -------------------------------------------------------------------------------- /data/enmap.sqlite-shm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nekros-dsc/ModMail-Bot/8121599f102074736b22d9ff1cfe4c482c5babcd/data/enmap.sqlite-shm -------------------------------------------------------------------------------- /data/enmap.sqlite-wal: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nekros-dsc/ModMail-Bot/8121599f102074736b22d9ff1cfe4c482c5babcd/data/enmap.sqlite-wal -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const Discord = require("discord.js"); 2 | const Enmap = require("enmap"); 3 | const config = require("./config.json") 4 | 5 | const client = new Discord.Client({ 6 | shards: "auto", // 1800+ , 7 | allowedMentions: { 8 | parse: ["roles", "users"], 9 | repliedUser: false, 10 | }, 11 | failIfNotExists: false, 12 | presence: { 13 | activity: { 14 | name: `Dm me for help | m!help`, 15 | type: "STREAMING", 16 | url: "https://twitch.tv/nekros_95" 17 | }, 18 | status: "online" 19 | }, 20 | restTimeOffset: 0, 21 | partials: ["CHANNEL", "MESSAGE", "REACTION"], 22 | intents: [ 23 | Discord.Intents.FLAGS.GUILDS, 24 | Discord.Intents.FLAGS.GUILD_MEMBERS, 25 | Discord.Intents.FLAGS.GUILD_MESSAGES, 26 | Discord.Intents.FLAGS.DIRECT_MESSAGES, 27 | ] 28 | }); 29 | client.modmailDb = new Enmap({ 30 | name: "Modmail-Database", 31 | //dataDir: "./databases/modmail" //create the folder(s) 32 | }); 33 | client.settings = new Enmap({ 34 | name: "Settings-Database", 35 | //dataDir: "./databases/settings" //create the folder(s) 36 | }); 37 | client.login(config.token) 38 | client.on("ready", () => { 39 | console.log(`${client.user.tag} is now online!`); 40 | }) 41 | 42 | require("./modmail")(client); -------------------------------------------------------------------------------- /modmail.js: -------------------------------------------------------------------------------- 1 | const Discord = require("discord.js"); 2 | const moment = require("moment"); 3 | const fs = require("fs") 4 | const config = require("./config.json") 5 | module.exports = client => { 6 | 7 | // Server 8 | client.on("messageCreate", async (message) => { 9 | if(message.guild && !message.author.bot) { 10 | let serverauthor = message.author; 11 | client.modmailDb.ensure(message.guild.id, { 12 | enabled: false, 13 | category: null, 14 | message: "Commencez à taper ce dont vous avez besoin et obtenez de l'aide !" 15 | }) 16 | let data = client.modmailDb.get(message.guild.id) 17 | client.settings.ensure(message.guild.id, { 18 | prefix: config.prefix 19 | }); 20 | let prefix = client.settings.get(message.guild.id, `prefix`); 21 | const prefixRegex = new RegExp(`^(<@!?${client.user.id}>|${escapeRegex(prefix)})\\s*`); 22 | if(prefixRegex.test(message.content)) { 23 | const [, matchedPrefix] = message.content.match(prefixRegex); 24 | let args = message.content.slice(matchedPrefix.length).trim().split(/ +/); 25 | let cmd = args.shift()?.toLowerCase(); //PinG --> ping; 26 | if(cmd.length == 0 && matchedPrefix.includes(client.user.id)){ 27 | return message.reply({embeds: [ 28 | new Discord.MessageEmbed().setColor("BLURPLE").setTitle(`:white_check_mark: **Mon préfix est: \`${prefix}\`**`) 29 | ]}).catch(console.error); 30 | } 31 | if(cmd && cmd.length > 0){ 32 | if(cmd == "invite" || cmd == "add"){ 33 | message.reply({ 34 | embeds: [new Discord.MessageEmbed().setColor("BLURPLE").setTitle(`:white_check_mark: **Merci de m'avoir invité**`) 35 | .setDescription(`[**Click ici pour m'inviter!**](https://discord.com/api/oauth2/authorize?client_id=${client.user.id}&permissions=8&scope=bot)`) 36 | ]}) 37 | } else if(cmd == "setup"){ 38 | if(!message.member.permissions.has(Discord.Permissions.FLAGS.ADMINISTRATOR)) { 39 | return message.reply({ 40 | embeds: [ 41 | new Discord.MessageEmbed() 42 | .setAuthor(serverauthor.tag, serverauthor.displayAvatarURL({dynamic: true})) 43 | .setTimestamp() 44 | .setFooter(`ID: ${serverauthor.id}`, serverauthor.displayAvatarURL({dynamic: true})) 45 | .setColor("RED") 46 | .setTitle("❌ Seul les admins sont autorisés à utiliser cette commande!") 47 | ] 48 | }).catch(console.error) 49 | } 50 | if(!args[0]){ 51 | return message.reply({ 52 | embeds: [ 53 | new Discord.MessageEmbed() 54 | .setAuthor(serverauthor.tag, serverauthor.displayAvatarURL({dynamic: true})) 55 | .setTimestamp() 56 | .setFooter(`ID: ${serverauthor.id}`, serverauthor.displayAvatarURL({dynamic: true})) 57 | .setColor("RED") 58 | .setTitle("❌ Utilisation invalide !") 59 | .setDescription(`Utilisation: \`${config.prefix}setup `) 60 | ] 61 | }).catch(console.error) 62 | } 63 | let category = message.guild.channels.cache.get(args[0]); 64 | if(!category || category.type != "GUILD_CATEGORY"){ 65 | return message.reply({ 66 | embeds: [ 67 | new Discord.MessageEmbed() 68 | .setAuthor(serverauthor.tag, serverauthor.displayAvatarURL({dynamic: true})) 69 | .setTimestamp() 70 | .setFooter(`ID: ${serverauthor.id}`, serverauthor.displayAvatarURL({dynamic: true})) 71 | .setColor("RED") 72 | .setTitle("❌ ID de catégorie non valide") 73 | .setDescription(`${args[0]} n'est pas une catégorie !`.substr(0, 2048)) 74 | ] 75 | }).catch(console.error) 76 | } 77 | client.modmailDb.set(message.guild.id, { 78 | enabled: true, 79 | category: category.id, 80 | message: args[1] ? args.slice(1).join(" ").substr(0, 2000) : "Commencez à taper ce dont vous avez besoin et obtenez de l'aide !" 81 | }) 82 | return message.reply({ 83 | embeds: [ 84 | new Discord.MessageEmbed() 85 | .setAuthor(serverauthor.tag, serverauthor.displayAvatarURL({dynamic: true})) 86 | .setTimestamp() 87 | .setFooter(`ID: ${serverauthor.id}`, serverauthor.displayAvatarURL({dynamic: true})) 88 | .setColor("GREEN") 89 | .setTitle("✅ Activé et configuré avec succès la configuration !") 90 | ] 91 | }).catch(console.error) 92 | } 93 | else if(cmd == "deletesetup"){ 94 | if(!message.member.permissions.has(Discord.Permissions.FLAGS.ADMINISTRATOR)) { 95 | return message.reply({ 96 | embeds: [ 97 | new Discord.MessageEmbed() 98 | .setAuthor(serverauthor.tag, serverauthor.displayAvatarURL({dynamic: true})) 99 | .setTimestamp() 100 | .setFooter(`ID: ${serverauthor.id}`, serverauthor.displayAvatarURL({dynamic: true})) 101 | .setColor("RED") 102 | .setTitle("❌ Seuls les administrateurs sont autorisés à exécuter cette commande !") 103 | ] 104 | }).catch(console.error) 105 | } 106 | if(!client.modmailDb.has(guild.id)){ 107 | return message.reply({ 108 | embeds: [ 109 | new Discord.MessageEmbed() 110 | .setAuthor(serverauthor.tag, serverauthor.displayAvatarURL({dynamic: true})) 111 | .setTimestamp() 112 | .setFooter(`ID: ${serverauthor.id}`, serverauthor.displayAvatarURL({dynamic: true})) 113 | .setColor("RED") 114 | .setTitle("❌ Vous n'étiez pas configuré avant !") 115 | ] 116 | }).catch(console.error) 117 | } 118 | client.modmailDb.delete(message.guild.id) 119 | return message.reply({ 120 | embeds: [ 121 | new Discord.MessageEmbed() 122 | .setAuthor(serverauthor.tag, serverauthor.displayAvatarURL({dynamic: true})) 123 | .setTimestamp() 124 | .setFooter(`ID: ${serverauthor.id}`, serverauthor.displayAvatarURL({dynamic: true})) 125 | .setColor("GREEN") 126 | .setTitle("✅ Suppression réussie de la configuration !") 127 | ] 128 | }).catch(console.error) 129 | } 130 | else if(cmd == "forceclose"){ 131 | if(data.category == message.channel.parentId){ 132 | let authorId = client.modmailDb.findKey(d => d.id == message.guild.id && d.channel == message.channel.id); 133 | if(authorId) client.modmailDb.delete(authorId); 134 | return message.reply({ 135 | embeds: [ 136 | new Discord.MessageEmbed() 137 | .setAuthor(serverauthor.tag, serverauthor.displayAvatarURL({dynamic: true})) 138 | .setTimestamp() 139 | .setFooter(`ID: ${serverauthor.id}`, serverauthor.displayAvatarURL({dynamic: true})) 140 | .setColor("GREEN") 141 | .setTitle("✅ Forcer la fermeture de ce ticket") 142 | .setDescription(`VOUS POUVEZ MAINTENANT LE SUPPRIMER SI VOUS LE VOULEZ !`) 143 | ] 144 | }).catch(console.error) 145 | } else { 146 | return message.reply({ 147 | embeds: [ 148 | new Discord.MessageEmbed() 149 | .setAuthor(serverauthor.tag, serverauthor.displayAvatarURL({dynamic: true})) 150 | .setTimestamp() 151 | .setFooter(`ID: ${serverauthor.id}`, serverauthor.displayAvatarURL({dynamic: true})) 152 | .setColor("RED") 153 | .setTitle("❌ Le salon n'est pas un ticket") 154 | ] 155 | }).catch(console.error) 156 | } 157 | } 158 | else if(cmd == "close"){ 159 | if(data.category == message.channel.parentId){ 160 | let authorId = client.modmailDb.findKey(d => d.id == message.guild.id && d.channel == message.channel.id); 161 | if(!authorId) 162 | return message.reply({ 163 | embeds: [ 164 | new Discord.MessageEmbed() 165 | .setAuthor(serverauthor.tag, serverauthor.displayAvatarURL({dynamic: true})) 166 | .setTimestamp() 167 | .setFooter(`ID: ${serverauthor.id}`, serverauthor.displayAvatarURL({dynamic: true})) 168 | .setColor("RED") 169 | .setTitle("❌ Cette chaîne est fermée / l'utilisateur est parti !") 170 | .setDescription(`Ferme le ticket avec: \`${config.prefix}forceclose\``) 171 | ] 172 | }).catch(console.error); 173 | let author = message.guild.members.cache.get(authorId); 174 | if(!author) 175 | author = await message.guild.members.fetch(authorId).catch(e=>{ 176 | console.log(e) 177 | return message.reply({ 178 | embeds: [ 179 | new Discord.MessageEmbed() 180 | .setAuthor(serverauthor.tag, serverauthor.displayAvatarURL({dynamic: true})) 181 | .setTimestamp() 182 | .setFooter(`ID: ${serverauthor.id}`, serverauthor.displayAvatarURL({dynamic: true})) 183 | .setColor("RED") 184 | .setTitle("❌ L'utilisateur a quitté le serveur") 185 | .setDescription(`Ferme avec: \`${config.prefix}close\``) 186 | ] 187 | }).catch(console.error) 188 | }) 189 | if(!author){ 190 | return message.reply({ 191 | embeds: [ 192 | new Discord.MessageEmbed() 193 | .setAuthor(serverauthor.tag, serverauthor.displayAvatarURL({dynamic: true})) 194 | .setTimestamp() 195 | .setFooter(`ID: ${serverauthor.id}`, serverauthor.displayAvatarURL({dynamic: true})) 196 | .setColor("RED") 197 | .setTitle("❌ L'utilisateur a quitté le serveur") 198 | .setDescription(`Ferme avec: \`${config.prefix}forceclose\``) 199 | ] 200 | }).catch(console.error) 201 | } 202 | client.modmailDb.delete(authorId); 203 | msglimit = 1000; 204 | 205 | let messageCollection = new Discord.Collection(); 206 | let channelMessages = await message.channel.messages.fetch({ 207 | limit: 100 208 | }).catch(err => console.log(err)); 209 | messageCollection = messageCollection.concat(channelMessages); 210 | let tomanymsgs = 1; 211 | if (Number(msglimit) === 0) msglimit = 100; 212 | let messagelimit = Number(msglimit) / 100; 213 | if (messagelimit < 1) messagelimit = 1; 214 | while (channelMessages.size === 100) { 215 | if (tomanymsgs === messagelimit) break; 216 | tomanymsgs += 1; 217 | let lastMessageId = channelMessages.lastKey(); 218 | channelMessages = await message.channel.messages.fetch({ 219 | limit: 100, 220 | before: lastMessageId 221 | }).catch(err => console.log(err)); 222 | if (channelMessages) 223 | messageCollection = messageCollection.concat(channelMessages); 224 | } 225 | 226 | let attachment = []; 227 | try { 228 | attachment = [await create_transcript_buffer([...messageCollection.values()], message.channel, message.guild)] 229 | 230 | } catch (e){ 231 | console.log(e) 232 | attachment = [] 233 | } 234 | await author.send({ 235 | files: attachment, 236 | embeds: [ 237 | new Discord.MessageEmbed() 238 | .setAuthor(serverauthor.tag, serverauthor.displayAvatarURL({dynamic: true})) 239 | .setTimestamp() 240 | .setFooter(`ID: ${serverauthor.id}`, serverauthor.displayAvatarURL({dynamic: true})) 241 | .setColor("GREEN") 242 | .setTitle("✅ Le supporter a fermé le ticket") 243 | ] 244 | }).catch(console.error) 245 | await message.author.send({ 246 | files: attachment, 247 | embeds: [ 248 | new Discord.MessageEmbed() 249 | .setAuthor(serverauthor.tag, serverauthor.displayAvatarURL({dynamic: true})) 250 | .setTimestamp() 251 | .setFooter(`ID: ${serverauthor.id}`, serverauthor.displayAvatarURL({dynamic: true})) 252 | .setColor("GREEN") 253 | .setTitle("✅ Le supporter a fermé le ticket") 254 | ] 255 | }).catch(console.error) 256 | await message.reply({ 257 | files: attachment, 258 | embeds: [ 259 | new Discord.MessageEmbed() 260 | .setAuthor(serverauthor.tag, serverauthor.displayAvatarURL({dynamic: true})) 261 | .setTimestamp() 262 | .setFooter(`ID: ${serverauthor.id}`, serverauthor.displayAvatarURL({dynamic: true})) 263 | .setColor("GREEN") 264 | .setTitle("✅ Le supporter a fermé le ticket") 265 | .setDescription(`TU PEUX MAINTENANT LE SUPPRIMER SI VOUS LE VOULEZ !`) 266 | ] 267 | }).catch(console.error) 268 | try{ fs.unlinkSync(`${process.cwd()}/${message.channel.name}.html`)}catch(e){ console.log(e) } 269 | } else { 270 | return message.reply({ 271 | embeds: [ 272 | new Discord.MessageEmbed() 273 | .setAuthor(serverauthor.tag, serverauthor.displayAvatarURL({dynamic: true})) 274 | .setTimestamp() 275 | .setFooter(`ID: ${serverauthor.id}`, serverauthor.displayAvatarURL({dynamic: true})) 276 | .setColor("RED") 277 | .setTitle("❌ Ce salon n'est pas un ticket !") 278 | ] 279 | }).catch(console.error) 280 | } 281 | } else if(cmd == "help") { 282 | let { guild } = message 283 | let embeds = [] 284 | embeds.push(new Discord.MessageEmbed() 285 | .setColor("BLURPLE") 286 | .setTitle(`Voici mon help`) 287 | .setDescription(`Salut je suis ${guild.me.user.username}`) 288 | .setThumbnail(guild.me.user.displayAvatarURL()) 289 | .setAuthor(guild.name, guild.iconURL({dynamic: true}))) 290 | embeds.push(new Discord.MessageEmbed() 291 | .setColor("GREEN") 292 | .setTitle(`💯 Commandes utilitaire!`) 293 | .setThumbnail(guild.me.user.displayAvatarURL()) 294 | .addFields([ 295 | {name: "**ping**", value: `> *Montre le ping du bot.*`, inline: true}, 296 | {name: "**help**", value: `> *Affiche le help*`, inline: true}, 297 | ])) 298 | embeds.push(new Discord.MessageEmbed() 299 | .setColor("RED") 300 | .setTitle(`🚫 Commandes Administration!`) 301 | .setThumbnail(guild.me.user.displayAvatarURL()) 302 | .addFields([ 303 | {name: "**setup**", value: `> *Crée la configuration de votre ticket Modmail*`, inline: true}, 304 | {name: "**deletesetup**", value: `> *Supprimer la configuration de celui-ci*`, inline: true}, 305 | {name: "**prefix**", value: `> *Change le préfixe du bot!*`, inline: true}, 306 | {name: "\u200b", value: `\u200b`, inline: false}, 307 | {name: "**close**", value: `> *Ferme le ticket (ou utilise mon bouton)*`, inline: true}, 308 | {name: "**forceclose**", value: `> *Forcer le ferme afin que vous puissiez supprimer le canal et que l'utilisateur puisse en créer de nouveaux*`, inline: true}, 309 | ]) 310 | .setFooter(guild.name, guild.iconURL({dynamic: true}))) 311 | message.reply({embeds}) 312 | } else if(cmd == "ping"){ 313 | message.reply({embeds: [ 314 | new Discord.MessageEmbed().setColor("BLURPLE").setTitle(`:white_check_mark: **Pinger l'API...**`) 315 | ]}).then((msg)=>{ 316 | let botping = (Date.now() - msg.createdTimestamp) - (2 * client.ws.ping); 317 | if(botping < 0) botping = 10; 318 | msg.edit({embeds: [ 319 | new Discord.MessageEmbed().setColor("BLURPLE").setTitle(`> **API PING:** \`${client.ws.ping}\`\n\n> **BOT PING:** \`${botping}\``) 320 | ]}).catch(console.error); 321 | }).catch(console.error); 322 | } else if(cmd == "prefix"){ 323 | if(!message.member.permissions.has(Discord.Permissions.FLAGS.MANAGE_GUILD)){ 324 | return message.reply({embeds: [ 325 | new Discord.MessageEmbed().setColor("RED").setTitle(`:x: **Vous n'êtes pas autorisé à exécuter cette commande**`) 326 | ]}).catch(console.error); 327 | } 328 | 329 | if(!args[0]){ 330 | return message.reply({embeds: [ 331 | new Discord.MessageEmbed().setColor("RED").setTitle(`:x: **Vous devez me dire quel devrait être le nouveau préfixe**`) 332 | ]}).catch(console.error); 333 | } 334 | //change the prefix settings 335 | client.settings.set(message.guild.id, args[0], "prefix"); 336 | //Send success message 337 | return message.reply({embeds: [ 338 | new Discord.MessageEmbed().setColor("BLURPLE").setTitle(`:white_check_mark: **Le préfixe a été modifié avec succès: \`${args[0]}\`**`) 339 | ]}).catch(console.error); 340 | } 341 | } 342 | } 343 | if(data.category == message.channel.parentId){ 344 | let authorId = client.modmailDb.findKey(d => d.id == message.guild.id && d.channel == message.channel.id); 345 | if(!authorId) 346 | return message.reply({ 347 | embeds: [ 348 | new Discord.MessageEmbed() 349 | .setAuthor(serverauthor.tag, serverauthor.displayAvatarURL({dynamic: true})) 350 | .setTimestamp() 351 | .setFooter(`ID: ${serverauthor.id}`, serverauthor.displayAvatarURL({dynamic: true})) 352 | .setColor("RED") 353 | .setTitle("❌ Ce salon est fermé / l'utilisateur a quitté!") 354 | .setDescription(`Ferme avec: \`${config.prefix}forceclose\``) 355 | ] 356 | }).catch(console.error); 357 | let author = message.guild.members.cache.get(authorId); 358 | if(!author) 359 | author = await message.guild.members.fetch(authorId).catch(e=>{ 360 | console.log(e) 361 | return message.reply({ 362 | embeds: [ 363 | new Discord.MessageEmbed() 364 | .setAuthor(serverauthor.tag, serverauthor.displayAvatarURL({dynamic: true})) 365 | .setTimestamp() 366 | .setFooter(`ID: ${serverauthor.id}`, serverauthor.displayAvatarURL({dynamic: true})) 367 | .setColor("RED") 368 | .setTitle("❌ L'Utilisateur a quitté le Serveur") 369 | .setDescription(`Ferme avec: \`${config.prefix}close\``) 370 | ] 371 | }).catch(console.error) 372 | }) 373 | if(!author){ 374 | return message.reply({ 375 | embeds: [ 376 | new Discord.MessageEmbed() 377 | .setAuthor(serverauthor.tag, serverauthor.displayAvatarURL({dynamic: true})) 378 | .setTimestamp() 379 | .setFooter(`ID: ${serverauthor.id}`, serverauthor.displayAvatarURL({dynamic: true})) 380 | .setColor("RED") 381 | .setTitle("❌ L'Utilisateur a quitté le Serveur") 382 | .setDescription(`Ferme avec: \`${config.prefix}close\``) 383 | ] 384 | }).catch(console.error) 385 | } 386 | 387 | let attachment = []; 388 | if(message.attachments.size > 0){ 389 | if(["png", "jpeg", "jpg", "gif"].some(i => message.attachments.first()?.url?.toLowerCase()?.includes(i))){ 390 | attachment = [new Discord.MessageAttachment(message.attachments.first()?.url)] 391 | } else { 392 | attachment = []; 393 | } 394 | } 395 | let embed = new Discord.MessageEmbed() 396 | .setAuthor(serverauthor.tag, serverauthor.displayAvatarURL({dynamic: true})) 397 | .setTimestamp() 398 | .setFooter(`ID: ${serverauthor.id}`, serverauthor.displayAvatarURL({dynamic: true})) 399 | .setColor("GREEN") 400 | .setTitle("📨 Envoie un nouveau message") 401 | .setDescription(`${message.content}`.substr(0, 2048)) 402 | .addField(`Plus haut rôle:`, `${message.member.roles.highest.name} | <@&${message.member.roles.highest.id}>`); 403 | if(attachment.length > 0){ 404 | console.log(attachment) 405 | embed.setImage('attachment://unknown.png'); 406 | } 407 | author.send({ 408 | files: attachment, 409 | embeds: [embed 410 | ] 411 | }).catch(error=>{ 412 | console.log(error) 413 | return message.reply({ 414 | embeds: [ 415 | new Discord.MessageEmbed() 416 | .setAuthor(serverauthor.tag, serverauthor.displayAvatarURL({dynamic: true})) 417 | .setTimestamp() 418 | .setFooter(`ID: ${serverauthor.id}`, serverauthor.displayAvatarURL({dynamic: true})) 419 | .setColor("RED") 420 | .setTitle("❌ Impossible d'envoyer un message au salon") 421 | .setDescription(`\`\`\`${error.message ? String(error.message).substr(0, 2000) : String(e).substr(0, 2000)}\`\`\``) 422 | ] 423 | }).catch(console.error) 424 | }) 425 | .then(success=>{ 426 | message.react("📨").catch(console.error) 427 | message.react("✅").catch(console.error) 428 | }); 429 | } 430 | 431 | } 432 | }) 433 | 434 | client.on("ready", () => { 435 | client.user.setActivity({ 436 | name: "Mp moi ! | m!help | " + client.guilds.cache.size + " Guilds", type: "PLAYING", url: "https://twitch.tv/novaworld" 437 | }) 438 | setInterval(() => { 439 | client.user.setActivity({ 440 | name: "Mp moi ! | m!help | " + client.guilds.cache.size + " Guilds", type: "PLAYING", url: "https://twitch.tv/novaworld" 441 | }) 442 | }, (1000 * 60 * 5)); 443 | }) 444 | // DMS 445 | client.on("messageCreate", async (message) => { 446 | if(message.author.bot) return; 447 | if(!message.guild || message.channel.type == "DM") { 448 | let dmauthor = message.author; 449 | if(!client.modmailDb.has(dmauthor.id)){ 450 | 451 | let guildsin = [] 452 | 453 | for(let guild of [... client.guilds.cache.values()]) { 454 | try{ 455 | await guild.members.fetch(dmauthor.id); 456 | guildsin.push(guild.id); 457 | }catch (e){ 458 | // console.log(e) 459 | } 460 | } 461 | 462 | if(guildsin.length == 0){ 463 | return message.reply({ 464 | embeds: [ 465 | new Discord.MessageEmbed() 466 | .setAuthor(dmauthor.tag, dmauthor.displayAvatarURL({dynamic: true})) 467 | .setTimestamp() 468 | .setFooter(`ID: ${dmauthor.id}`, dmauthor.displayAvatarURL({dynamic: true})) 469 | .setColor("RED") 470 | .setTitle("❌ Vous ne partagez aucune guilde avec moi !") 471 | ] 472 | }).catch(console.error) 473 | } 474 | else if(guildsin.length == 1){ 475 | let guild = client.guilds.cache.get(guildsin[0]) 476 | //he is already in a support mode! 477 | client.modmailDb.set(dmauthor.id, { 478 | id: guild.id 479 | }); 480 | startSupportProcess(guild, message, dmauthor) 481 | } 482 | else { 483 | let selectedid = message.content; 484 | let guild = client.guilds.cache.get(selectedid) 485 | if(guild){ 486 | //he is already in a support mode! 487 | client.modmailDb.set(dmauthor.id, { 488 | id: guild.id 489 | }); 490 | startSupportProcess(guild, message, dmauthor) 491 | return; 492 | } else { 493 | message.reply({ 494 | embeds: [ 495 | new Discord.MessageEmbed() 496 | .setAuthor(dmauthor.tag, dmauthor.displayAvatarURL({dynamic: true})) 497 | .setTimestamp() 498 | .setFooter(`ID: ${dmauthor.id}`, dmauthor.displayAvatarURL({dynamic: true})) 499 | .setColor("RED") 500 | .setTitle("❌ Impossible de trouver la guilde sous cet ID !! (SI VOUS ESSAYEZ D'EN ENVOYER UN)") 501 | ] 502 | }).catch(console.error) 503 | 504 | } 505 | let embed = new Discord.MessageEmbed() 506 | .setAuthor(dmauthor.tag, dmauthor.displayAvatarURL({dynamic: true})) 507 | .setTimestamp() 508 | .setFooter(`ID: ${dmauthor.id}`, dmauthor.displayAvatarURL({dynamic: true})) 509 | .setColor("BLURPLE") 510 | .setTitle("✅ Toutes les guildes dans lesquelles nous sommes!") 511 | .setDescription(String(guildsin.map(id => `${client.guilds.cache.get(id) ? `**${client.guilds.cache.get(id).name}** (\`${id}\`)`: `\`${id}\``}`).join("\n")).substr(0, 2048)) 512 | .setFooter("Information : si votre guilde ne s'affiche pas, envoyez simplement l'identifiant de la guilde pour laquelle vous souhaitez obtenir de l'aide !") 513 | message.reply({ 514 | embeds: [ 515 | embed, 516 | new Discord.MessageEmbed() 517 | .setAuthor(dmauthor.tag, dmauthor.displayAvatarURL({dynamic: true})) 518 | .setTimestamp() 519 | .setFooter(`ID: ${dmauthor.id}`, dmauthor.displayAvatarURL({dynamic: true})) 520 | .setColor("GREEN") 521 | .setTitle("👍 Sélectionnez la guilde à laquelle vous souhaitez demander de l'aide !") 522 | .setDescription(`**Veuillez envoyer l'identifiant de la GUILD avec laquelle vous souhaitez obtenir de l'aide !**\n\n**Exemple:**\n> \`${guildsin[0]}\``) 523 | ] 524 | }); 525 | } 526 | } 527 | //SUPPORT MESSAGES ETC. 528 | else { 529 | let guild = client.guilds.cache.get(client.modmailDb.get(dmauthor.id, "id")); 530 | if(!guild) { 531 | return message.reply({ 532 | embeds: [ 533 | new Discord.MessageEmbed() 534 | .setAuthor(dmauthor.tag, dmauthor.displayAvatarURL({dynamic: true})) 535 | .setTimestamp() 536 | .setFooter(`ID: ${dmauthor.id}`, dmauthor.displayAvatarURL({dynamic: true})) 537 | .setColor("RED") 538 | .setTitle("❌ Impossible de trouver la GUILD de support, réessayez !") 539 | ] 540 | }).catch(console.error) 541 | } 542 | let channel = guild.channels.cache.get(client.modmailDb.get(dmauthor.id, "channel")); 543 | if(!channel) { 544 | return message.reply({ 545 | embeds: [ 546 | new Discord.MessageEmbed() 547 | .setAuthor(dmauthor.tag, dmauthor.displayAvatarURL({dynamic: true})) 548 | .setTimestamp() 549 | .setFooter(`ID: ${dmauthor.id}`, dmauthor.displayAvatarURL({dynamic: true})) 550 | .setColor("RED") 551 | .setTitle("❌ Impossible de trouver la GUILD de support, réessayez !") 552 | ], 553 | components: [ 554 | new Discord.MessageActionRow().addComponents( 555 | new Discord.MessageButton().setStyle("SECONDARY").setLabel("FORCE CLOSE").setCustomId("force_modmail_close").setEmoji("❎") 556 | ) 557 | ] 558 | }).catch(console.error) 559 | } 560 | let attachment = []; 561 | if(message.attachments.size > 0){ 562 | if(["png", "jpeg", "jpg", "gif"].some(i => message.attachments.first()?.url?.toLowerCase()?.includes(i))){ 563 | attachment = [new Discord.MessageAttachment(message.attachments.first()?.url)] 564 | } else { 565 | attachment = []; 566 | } 567 | } 568 | let embed = new Discord.MessageEmbed() 569 | .setAuthor(dmauthor.tag, dmauthor.displayAvatarURL({dynamic: true})) 570 | .setTimestamp() 571 | .setFooter(`ID: ${dmauthor.id}`, dmauthor.displayAvatarURL({dynamic: true})) 572 | .setColor("GREEN") 573 | .setTitle("📨 Envoyé un nouveau message") 574 | .setDescription(`${message.content}`.substr(0, 2048)) 575 | if(attachment.length > 0){ 576 | console.log(attachment) 577 | embed.setImage('attachment://unknown.png'); 578 | } 579 | channel.send({ 580 | files: attachment, 581 | embeds: [embed 582 | ] 583 | }).catch(error=>{ 584 | console.log(error) 585 | return message.reply({ 586 | embeds: [ 587 | new Discord.MessageEmbed() 588 | .setAuthor(dmauthor.tag, dmauthor.displayAvatarURL({dynamic: true})) 589 | .setTimestamp() 590 | .setFooter(`ID: ${dmauthor.id}`, dmauthor.displayAvatarURL({dynamic: true})) 591 | .setColor("RED") 592 | .setTitle("❌ Impossible d'envoyer un message au salon") 593 | .setDescription(`\`\`\`${error.message ? String(error.message).substr(0, 2000) : String(e).substr(0, 2000)}\`\`\``) 594 | ] 595 | }).catch(console.error) 596 | }) 597 | .then(success=>{ 598 | message.react("📨").catch(console.error) 599 | message.react("✅").catch(console.error) 600 | }); 601 | } 602 | } 603 | }) 604 | 605 | 606 | client.on("interactionCreate", async interaction => { 607 | if(interaction.isButton() && interaction.customId == "close_modmail_ticket" && !interaction.guildId){ 608 | let dmauthor = interaction.user; 609 | if(!client.modmailDb.has(dmauthor.id)) 610 | return interaction.reply({ 611 | content: "❌ **Vous n'avez plus de Ticket !**", 612 | ephemeral: true 613 | }) 614 | let guild = client.guilds.cache.get(client.modmailDb.get(dmauthor.id, "id")); 615 | if(!guild) { 616 | return interaction.reply({ 617 | embeds: [ 618 | new Discord.MessageEmbed() 619 | .setAuthor(dmauthor.tag, dmauthor.displayAvatarURL({dynamic: true})) 620 | .setTimestamp() 621 | .setFooter(`ID: ${dmauthor.id}`, dmauthor.displayAvatarURL({dynamic: true})) 622 | .setColor("RED") 623 | .setTitle("❌ Impossible de trouver la GUILD de support, réessayez !") 624 | ], 625 | ephemeral: true 626 | }).catch(console.error) 627 | } 628 | let channel = guild.channels.cache.get(client.modmailDb.get(dmauthor.id, "channel")); 629 | if(!channel) { 630 | return interaction.reply({ 631 | embeds: [ 632 | new Discord.MessageEmbed() 633 | .setAuthor(dmauthor.tag, dmauthor.displayAvatarURL({dynamic: true})) 634 | .setTimestamp() 635 | .setFooter(`ID: ${dmauthor.id}`, dmauthor.displayAvatarURL({dynamic: true})) 636 | .setColor("RED") 637 | .setTitle("❌ Impossible de trouver le canal d'assistance, réessayez !") 638 | ], 639 | components: [ 640 | new Discord.MessageActionRow().addComponents( 641 | new Discord.MessageButton().setStyle("SECONDARY").setLabel("FORCE CLOSE").setCustomId("force_modmail_close").setEmoji("❎") 642 | ) 643 | ], 644 | ephemeral: true 645 | }).catch(console.error) 646 | } 647 | interaction.reply({ 648 | content: "**Ticket fermé**", 649 | ephemeral: true 650 | }) 651 | client.modmailDb.delete(dmauthor.id); 652 | msglimit = 1000; 653 | 654 | let messageCollection = new Discord.Collection(); 655 | let channelMessages = await channel.messages.fetch({ 656 | limit: 100 657 | }).catch(err => console.log(err)); 658 | messageCollection = messageCollection.concat(channelMessages); 659 | let tomanymsgs = 1; 660 | if (Number(msglimit) === 0) msglimit = 100; 661 | let messagelimit = Number(msglimit) / 100; 662 | if (messagelimit < 1) messagelimit = 1; 663 | while (channelMessages.size === 100) { 664 | if (tomanymsgs === messagelimit) break; 665 | tomanymsgs += 1; 666 | let lastMessageId = channelMessages.lastKey(); 667 | channelMessages = await channel.messages.fetch({ 668 | limit: 100, 669 | before: lastMessageId 670 | }).catch(err => console.log(err)); 671 | if (channelMessages) 672 | messageCollection = messageCollection.concat(channelMessages); 673 | } 674 | 675 | let attachment = []; 676 | try { 677 | attachment = [await create_transcript_buffer([...messageCollection.values()], channel, channel.guild)] 678 | } catch (e){ 679 | console.log(e) 680 | attachment = [] 681 | } 682 | await dmauthor.send({ 683 | files: attachment, 684 | embeds: [ 685 | new Discord.MessageEmbed() 686 | .setAuthor(dmauthor.tag, dmauthor.displayAvatarURL({dynamic: true})) 687 | .setTimestamp() 688 | .setFooter(`ID: ${dmauthor.id}`, dmauthor.displayAvatarURL({dynamic: true})) 689 | .setColor("GREEN") 690 | .setTitle("✅ TicketUser a fermé le ticket") 691 | ] 692 | }).catch(console.error) 693 | await channel.send({ 694 | files: attachment, 695 | embeds: [ 696 | new Discord.MessageEmbed() 697 | .setAuthor(dmauthor.tag, dmauthor.displayAvatarURL({dynamic: true})) 698 | .setTimestamp() 699 | .setFooter(`ID: ${dmauthor.id}`, dmauthor.displayAvatarURL({dynamic: true})) 700 | .setColor("GREEN") 701 | .setTitle("✅ TicketUser a fermé le ticket") 702 | ] 703 | }).catch(console.error) 704 | try{ fs.unlinkSync(`${process.cwd()}/${channel.name}.html`)}catch(e){ console.log(e) } 705 | } 706 | if(interaction.isButton() && interaction.customId == "force_modmail_close" && !interaction.guildId){ 707 | if(client.modmailDb.has(interaction.user.id)) client.modmailDb.delete(interaction.user.id); 708 | interaction.reply({ 709 | content: "**Forcer la fermeture du ticket, vous pouvez maintenant en créer de nouveaux !**", 710 | ephemeral: true 711 | }) 712 | } 713 | if(interaction.isButton() && interaction.customId == "close_modmail_ticket" && interaction.guildId){ 714 | let serverauthor = interaction.user; 715 | let authorId = client.modmailDb.findKey(d => d.id == interaction.message.guild.id && d.channel == interaction.message.channel.id); 716 | if(!authorId) 717 | return interaction.reply({ 718 | embeds: [ 719 | new Discord.MessageEmbed() 720 | .setAuthor(serverauthor.tag, serverauthor.displayAvatarURL({dynamic: true})) 721 | .setTimestamp() 722 | .setFooter(`ID: ${serverauthor.id}`, serverauthor.displayAvatarURL({dynamic: true})) 723 | .setColor("RED") 724 | .setTitle("❌ Ce canal est fermé / l'utilisateur a quitté!") 725 | .setDescription(`Ferme le ticket avec: \`${config.prefix}forceclose\``) 726 | ] 727 | }).catch(console.error); 728 | let author = interaction.message.guild.members.cache.get(authorId); 729 | if(!author) 730 | author = await interaction.message.guild.members.fetch(authorId).catch(e=>{ 731 | console.log(e) 732 | return interaction.reply({ 733 | embeds: [ 734 | new Discord.MessageEmbed() 735 | .setAuthor(serverauthor.tag, serverauthor.displayAvatarURL({dynamic: true})) 736 | .setTimestamp() 737 | .setFooter(`ID: ${serverauthor.id}`, serverauthor.displayAvatarURL({dynamic: true})) 738 | .setColor("RED") 739 | .setTitle("❌ L'utilisateur a quitté le serveur") 740 | .setDescription(`Ferme le ticket avec: \`${config.prefix}close\``) 741 | ] 742 | }).catch(console.error) 743 | }) 744 | if(!author){ 745 | return interaction.reply({ 746 | embeds: [ 747 | new Discord.MessageEmbed() 748 | .setAuthor(serverauthor.tag, serverauthor.displayAvatarURL({dynamic: true})) 749 | .setTimestamp() 750 | .setFooter(`ID: ${serverauthor.id}`, serverauthor.displayAvatarURL({dynamic: true})) 751 | .setColor("RED") 752 | .setTitle("❌ L'utilisateur a quitté le serveur") 753 | .setDescription(`Ferme le ticket avec: \`${config.prefix}forceclose\``) 754 | ] 755 | }).catch(console.error) 756 | } 757 | interaction.reply({ 758 | content: "**Closed the Ticket!**", 759 | ephemeral: true 760 | }) 761 | client.modmailDb.delete(authorId); 762 | msglimit = 1000; 763 | 764 | let messageCollection = new Discord.Collection(); 765 | let channelMessages = await interaction.message.channel.messages.fetch({ 766 | limit: 100 767 | }).catch(err => console.log(err)); 768 | messageCollection = messageCollection.concat(channelMessages); 769 | let tomanymsgs = 1; 770 | if (Number(msglimit) === 0) msglimit = 100; 771 | let messagelimit = Number(msglimit) / 100; 772 | if (messagelimit < 1) messagelimit = 1; 773 | while (channelMessages.size === 100) { 774 | if (tomanymsgs === messagelimit) break; 775 | tomanymsgs += 1; 776 | let lastMessageId = channelMessages.lastKey(); 777 | channelMessages = await interaction.message.channel.messages.fetch({ 778 | limit: 100, 779 | before: lastMessageId 780 | }).catch(err => console.log(err)); 781 | if (channelMessages) 782 | messageCollection = messageCollection.concat(channelMessages); 783 | } 784 | 785 | let attachment = []; 786 | try { 787 | attachment = [await create_transcript_buffer([...messageCollection.values()], interaction.message.channel, interaction.message.guild)] 788 | 789 | } catch (e){ 790 | console.log(e) 791 | attachment = [] 792 | } 793 | await author.send({ 794 | files: attachment, 795 | embeds: [ 796 | new Discord.MessageEmbed() 797 | .setAuthor(serverauthor.tag, serverauthor.displayAvatarURL({dynamic: true})) 798 | .setTimestamp() 799 | .setFooter(`ID: ${serverauthor.id}`, serverauthor.displayAvatarURL({dynamic: true})) 800 | .setColor("GREEN") 801 | .setTitle("✅ Le supporter a fermé le ticket") 802 | ] 803 | }).catch(console.error) 804 | await interaction.user.send({ 805 | files: attachment, 806 | embeds: [ 807 | new Discord.MessageEmbed() 808 | .setAuthor(serverauthor.tag, serverauthor.displayAvatarURL({dynamic: true})) 809 | .setTimestamp() 810 | .setFooter(`ID: ${serverauthor.id}`, serverauthor.displayAvatarURL({dynamic: true})) 811 | .setColor("GREEN") 812 | .setTitle("✅ Le supporter a fermé le ticket") 813 | ] 814 | }).catch(console.error) 815 | await interaction.message.reply({ 816 | files: attachment, 817 | embeds: [ 818 | new Discord.MessageEmbed() 819 | .setAuthor(serverauthor.tag, serverauthor.displayAvatarURL({dynamic: true})) 820 | .setTimestamp() 821 | .setFooter(`ID: ${serverauthor.id}`, serverauthor.displayAvatarURL({dynamic: true})) 822 | .setColor("GREEN") 823 | .setTitle("✅ Le supporter a fermé le ticket") 824 | .setDescription(`VOUS POUVEZ MAINTENANT LE SUPPRIMER SI VOUS LE VOULEZ !`) 825 | ] 826 | }).catch(console.error) 827 | try{ fs.unlinkSync(`${process.cwd()}/${channel.name}.html`)}catch(e){ } 828 | } 829 | }) 830 | 831 | //security 832 | client.on("channelDelete", channel => { 833 | if(channel.guild){ 834 | let authorId = client.modmailDb.findKey(d => d.id == channel.guild.id && d.channel == channel.id); 835 | if(authorId) client.modmailDb.delete(authorId); 836 | } 837 | }) 838 | 839 | function startSupportProcess(guild, message, dmauthor){ 840 | client.modmailDb.ensure(guild.id, { 841 | enabled: false, 842 | category: null, 843 | message: "Commencez à taper ce dont vous avez besoin et obtenez de l'aide !" 844 | }) 845 | let data = client.modmailDb.get(guild.id) 846 | if(!data.enabled){ 847 | client.modmailDb.delete(dmauthor.id); 848 | return message.reply({ 849 | embeds: [ 850 | new Discord.MessageEmbed() 851 | .setAuthor(dmauthor.tag, dmauthor.displayAvatarURL({dynamic: true})) 852 | .setTimestamp() 853 | .setFooter(`ID: ${dmauthor.id}`, dmauthor.displayAvatarURL({dynamic: true})) 854 | .setColor("RED") 855 | .setTitle("❌ Cette guilde n'est pas encore configurée !") 856 | .setDescription(`un administrateur peut le faire avec \`${config.prefix}setup\``) 857 | ] 858 | }).catch(console.error) 859 | } 860 | let category = guild.channels.cache.get(data.category); 861 | if(category && category.type == "GUILD_CATEGORY") { 862 | if(category.children.size >= 50){ 863 | category == null; 864 | } 865 | } 866 | guild.channels.create(`${dmauthor.username}`.substr(0, 32) , { 867 | type: "GUILD_TEXT", 868 | topic: `Modmail Ticket pour: ${dmauthor.tag} | ${dmauthor.id}`, 869 | permissionOverwrites: [ 870 | { 871 | id: guild.id, 872 | deny: ["VIEW_CHANNEL"] 873 | } 874 | ] 875 | }).then(channel => { 876 | if(category) { 877 | channel.setParent(category.id); 878 | } 879 | client.modmailDb.set(dmauthor.id, channel.id, "channel"); 880 | message.reply({ 881 | embeds: [ 882 | new Discord.MessageEmbed() 883 | .setAuthor(dmauthor.tag, dmauthor.displayAvatarURL({dynamic: true})) 884 | .setTimestamp() 885 | .setFooter(`ID: ${dmauthor.id}`, dmauthor.displayAvatarURL({dynamic: true})) 886 | .setColor("BLURPLE") 887 | .setTitle("✅ Création réussie de votre ticket d'assistance !") 888 | .setDescription(`${data.message}`) 889 | .addField("Visibilité", `${!category ? "Seul les admins peuvent voir" : "Utilisation des paramètres de sa catégorie"}`) 890 | ], 891 | components: [ new Discord.MessageActionRow().addComponents(new Discord.MessageButton() 892 | .setStyle("DANGER").setEmoji("💥").setLabel("Ferme le ticket").setCustomId("close_modmail_ticket"))] 893 | }).catch(console.error) 894 | channel.send({ 895 | embeds: [ 896 | new Discord.MessageEmbed() 897 | .setAuthor(dmauthor.tag, dmauthor.displayAvatarURL({dynamic: true})) 898 | .setTimestamp() 899 | .setFooter(`ID: ${dmauthor.id}`, dmauthor.displayAvatarURL({dynamic: true})) 900 | .setColor("GREEN") 901 | .setTitle("✅ Created an Support Ticket!") 902 | .addField("Visibility", `${!category ? "Seul les admins peuvent voir!" : "Utilisation des paramètres de sa catégorie"}`) 903 | ], 904 | components: [ new Discord.MessageActionRow().addComponents(new Discord.MessageButton() 905 | .setStyle("DANGER").setEmoji("💥").setLabel("Fermer le ticket").setCustomId("close_modmail_ticket"))] 906 | }).catch(console.error) 907 | //START THE SUPPORTING HELP! 908 | }).catch(error=>{ 909 | console.log(error) 910 | client.modmailDb.delete(dmauthor.id); 911 | return message.reply({ 912 | embeds: [ 913 | new Discord.MessageEmbed() 914 | .setAuthor(dmauthor.tag, dmauthor.displayAvatarURL({dynamic: true})) 915 | .setTimestamp() 916 | .setFooter(`ID: ${dmauthor.id}`, dmauthor.displayAvatarURL({dynamic: true})) 917 | .setColor("RED") 918 | .setTitle("❌ Échec de la création du ticket d'assistance ! | ANNULÉ") 919 | .setDescription(`\`\`\`${error.message ? String(error.message).substr(0, 2000) : String(e).substr(0, 2000)}\`\`\``) 920 | ] 921 | }).catch(console.error) 922 | }) 923 | } 924 | } 925 | 926 | /** 927 | * CREATEING A TRANSCRIPT 928 | * @param {*} Messages 929 | * @param {*} Channel 930 | * @param {*} Guild 931 | * @returns ticketname.html FILE 932 | */ 933 | 934 | async function create_transcript_buffer(Messages, Channel, Guild){ 935 | return new Promise(async (resolve, reject) => { 936 | try{ 937 | let baseHTML = `` + 938 | `` + 939 | `` + 940 | `${Channel.name}` + 941 | `` + 942 | `` + 943 | `` + 944 | `` + 945 | `` + 946 | ``; 947 | let messagesArray = [] 948 | let messagescount = Messages.length; 949 | let msgs = Messages.reverse(); //reverse the array to have it listed like the discord chat 950 | //now for every message in the array make a new paragraph! 951 | await msgs.forEach(async msg => { 952 | //Aug 02, 2021 12:20 AM 953 | if(msg.type == "DEFAULT"){ 954 | let time = moment(msg.createdTimestamp).format("MMM DD, YYYY HH:MM:ss") 955 | let subcontent = `
` + 956 | `
` + 957 | `
` + 958 | `${msg.author.tag}`; 959 | if(msg.author.bot) subcontent += `BOT`; 960 | subcontent += `ID: ${msg.author.id} | ` + 961 | `${time} ${msg.editedTimestamp ? `(edited)` : msg.editedAt ? `(edited)` : ""}` + 962 | `
`; 963 | if (msg.content) { 964 | subcontent += `
${markdowntohtml(String(msg.cleanContent ? msg.cleanContent : msg.content).replace(/\n/ig, "
"))}
` 965 | } 966 | if (msg.embeds[0]){ 967 | subcontent += `
` 968 | 969 | if(msg.embeds[0].author){ 970 | subcontent += `
`; 971 | if(msg.embeds[0].author.iconURL){ 972 | subcontent += `` 973 | } 974 | if(msg.embeds[0].author.name){ 975 | subcontent += `
${markdowntohtml(String(msg.embeds[0].author.name).replace(/\n/ig, "
"))}
` 976 | } 977 | subcontent += `
` 978 | }if(msg.embeds[0].title){ 979 | subcontent += `
${markdowntohtml(String(msg.embeds[0].title).replace(/\n/ig, "
"))}
`; 980 | } 981 | if(msg.embeds[0].description){ 982 | subcontent += `
${markdowntohtml(String(msg.embeds[0].description).replace(/\n/ig, "
"))}
`; 983 | } 984 | if(msg.embeds[0].image){ 985 | subcontent += `
` 986 | } 987 | if(msg.embeds[0].fields && msg.embeds[0].fields.length > 0){ 988 | subcontent += `
` 989 | for(let i = 0; i < msg.embeds[0].fields.length; i++){ 990 | subcontent += `
` 991 | const field = msg.embeds[0].fields[i] 992 | if(field.key){ 993 | subcontent += `
${markdowntohtml(String(field.key).replace(/\n/ig, "
"))}
`; 994 | } 995 | if(field.value){ 996 | subcontent += `
${markdowntohtml(String(field.value).replace(/\n/ig, "
"))}
`; 997 | } 998 | subcontent += `
` 999 | } 1000 | subcontent += `
`; 1001 | } 1002 | if(msg.embeds[0].footer){ 1003 | subcontent += `` 1011 | } 1012 | subcontent += `
`; 1013 | if(msg.embeds[0].thumbnail && msg.embeds[0].thumbnail.url){ 1014 | subcontent += ``; 1015 | } 1016 | subcontent += `
`; 1017 | } 1018 | if (msg.reactions && msg.reactions.cache.size > 0){ 1019 | subcontent += `
` 1020 | for(const reaction of [...msg.reactions.cache.values()]){ 1021 | subcontent += `
${reaction.emoji.url ? `${"}">` : reaction.emoji.name.toString()}${reaction.count}
` 1022 | } 1023 | subcontent += `
` 1024 | } 1025 | subcontent += `
` 1026 | messagesArray.push(subcontent); 1027 | } 1028 | if(msg.type == "PINS_ADD"){ 1029 | let time = moment(msg.createdTimestamp).format("MMM DD, YYYY HH:MM:ss") 1030 | let subcontent = `
` + 1031 | `
` + 1032 | `
` + 1033 | `${msg.author.tag}`; 1034 | if(msg.author.bot) subcontent += `BOT`; 1035 | subcontent += `pinned a message to this channel.${time}
`; 1036 | messagesArray.push(subcontent); 1037 | } 1038 | }); 1039 | baseHTML += `
` + 1040 | `
` + 1046 | `
`; 1047 | baseHTML += messagesArray.join("\n"); 1048 | baseHTML += `
TICKET LOG INFORMATION✓ SYSTEMMind this Information
If there are Files, Attachments, Vidoes or Images, they won't always be displayed cause they will be unknown and we don't want to spam an API like IMGUR!
`; 1049 | fs.writeFileSync(`${process.cwd()}/${Channel.name}.html`, baseHTML); //write everything in the docx file 1050 | resolve(`${process.cwd()}/${Channel.name}.html`); 1051 | return; 1052 | function markdowntohtml(tomarkdown){ 1053 | mentionReplace(tomarkdown.split(" ")); 1054 | function mentionReplace(splitted){ 1055 | for(arg of splitted){ 1056 | const memberatches = arg.match(/<@!?(\d+)>/); 1057 | const rolematches = arg.match(/<@&(\d+)>/); 1058 | const channelmatches = arg.match(/<#(\d+)>/); 1059 | if (rolematches) { 1060 | let role = Guild.roles.cache.get(rolematches[1]) 1061 | if(role){ 1062 | let torpleace = new RegExp(rolematches[0], "g") 1063 | tomarkdown = tomarkdown.replace(torpleace, `@${role.name}`); 1064 | } 1065 | } 1066 | if(memberatches){ 1067 | let member = Guild.members.cache.get(memberatches[1]) 1068 | if(member){ 1069 | let torpleace = new RegExp(memberatches[0], "g") 1070 | tomarkdown = tomarkdown.replace(torpleace, `@${member.user.username}`); 1071 | } 1072 | } 1073 | if(channelmatches){ 1074 | let channel = Guild.channels.cache.get(channelmatches[1]) 1075 | if(channel){ 1076 | let torpleace = new RegExp(channelmatches[0], "g") 1077 | tomarkdown = tomarkdown.replace(torpleace, `@${channel.name}`); 1078 | } 1079 | } 1080 | } 1081 | } 1082 | var output = ""; 1083 | var BLOCK = "block"; 1084 | var INLINE = "inline"; 1085 | var parseMap = [ 1086 | { 1087 | //

1088 | pattern: /\n(?!<\/?\w+>|\s?\*|\s?[0-9]+|>|\>|-{5,})([^\n]+)/g, 1089 | replace: "$1
", 1090 | type: BLOCK, 1091 | }, 1092 | { 1093 | //

1094 | pattern: /\n(?:>|\>)\W*(.*)/g, 1095 | replace: "

$1

", 1096 | type: BLOCK, 1097 | }, 1098 | { 1099 | //