index.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. const Discord = require('discord.js');
  2. const client = new Discord.Client({ partials: ['MESSAGE', 'CHANNEL', 'REACTION'] });
  3. const config = require('./config.json');
  4. var mysql = require('mysql');
  5. var emoji = require('node-emoji');
  6. var urlRegex = /^(ftp|http|https):\/\/[^ "]+$/;
  7. client.on('ready', () => {
  8. if (config.playing !== "") {
  9. client.user.setPresence({ status: 'online', game: { name: config.playing } });
  10. }
  11. console.log(getTimestamp(), `Logged in as ${client.user.tag}!`);
  12. console.log(getTimestamp(), `To send missing messages run ${config.prefix}dump [quantity(default and limited to 99)]`);
  13. });
  14. client.on('message', message => {
  15. var serverData = undefined;
  16. config.servers.forEach(function(server) {
  17. if (message.channel.id==server.channel) serverData = server;
  18. });
  19. if (serverData==undefined) return;
  20. if (message.author.bot== true && serverData.allowBots != true) return;
  21. if (message.content.startsWith(`${serverData.prefix||config.prefix}ping`)) {
  22. message.channel.send('Pong! :ping_pong:');
  23. return;
  24. } else if (message.content.startsWith(`${serverData.prefix||config.prefix}dump`) && serverData.allowDump == true) {
  25. console.log(getTimestamp(), 'Warning, dump in progress! May cause slowdows.');
  26. number = message.content.slice(6);
  27. if (number=='') number = 99;
  28. //console.log(number);
  29. message.delete(2);
  30. var channel = message.channel;
  31. async function run() {
  32. var fetched = await channel.fetchMessages({limit: number});
  33. //console.log(fetched);
  34. var connection = mysql.createConnection({
  35. host : serverData.dbHost,
  36. port : serverData.dbPort,
  37. user : serverData.dbUser,
  38. password : serverData.dbPassword,
  39. database : serverData.db
  40. });
  41. var sql = 'SELECT * FROM `'+serverData.dbTable+'` ORDER BY `time` DESC';
  42. connection.connect();
  43. connection.query(sql, function (error, results, fields) {
  44. if (error) throw error;
  45. //console.log('Data recived from db. Result: ', results);
  46. var messages = [];
  47. var controlled = [];
  48. for (i = 0; i < number; i++) {
  49. controlled[i] = false;
  50. }
  51. fetched.forEach(messageNow => {
  52. var found = false;
  53. var edited = true;
  54. for (j = 0; j < results.length; j++) {
  55. var msg = results[j];
  56. if (messageNow.id == msg.id || messageNow.id == message.id ) {
  57. found = true;
  58. controlled[j] = true;
  59. }
  60. //console.log('message:' + ((messageNow.editedTimestamp == null) ? "nope" : messageNow.editedTimestamp) + ' db: ' + msg.timeEdit);
  61. if (found == true && (messageNow.editedTimestamp || "") == msg.timeEdit) {
  62. edited = false;
  63. }
  64. }
  65. if (found==true && edited==true) {
  66. messages.push({"message":messageNow, "action":1});
  67. } else if (found==false) {
  68. messages.push({"message":messageNow, "action":0});
  69. }
  70. });
  71. //console.log(messages);
  72. while(true) {
  73. break;
  74. }
  75. sendLoop(messages, serverData, 1000);
  76. });
  77. connection.end();
  78. }
  79. run();
  80. } else {
  81. sendToDB(message, serverData);
  82. }
  83. });
  84. client.on('messageUpdate', async (messageOld, messageNew) => {
  85. if (messageOld.partial) {
  86. // If the message was removed the fetching might result in an API error, which we need to handle
  87. try {
  88. await messageOld.fetch();
  89. } catch (error) {
  90. console.log(getTimestamp(), 'Something went wrong when fetching the message: ', error);
  91. }
  92. }
  93. if (messageNew.partial) {
  94. // If the message was removed the fetching might result in an API error, which we need to handle
  95. try {
  96. await messageNew.fetch();
  97. } catch (error) {
  98. console.log(getTimestamp(), 'Something went wrong when fetching the message: ', error);
  99. }
  100. }
  101. if (messageNew.author.bot==true) return;
  102. var serverData = undefined;
  103. config.servers.forEach(function(server) {
  104. if (messageNew.channel.id==server.channel) serverData = server;
  105. });
  106. if (serverData==undefined) return;
  107. var channel = messageNew.channel;
  108. var connection = mysql.createConnection({
  109. host : serverData.dbHost,
  110. port : serverData.dbPort,
  111. user : serverData.dbUser,
  112. password : serverData.dbPassword,
  113. database : serverData.db
  114. });
  115. var sql = 'SELECT * FROM `'+serverData.dbTable+'`';
  116. connection.connect();
  117. connection.query(sql, function (error, results, fields) {
  118. if (error) throw error;
  119. //console.log('Data recived from db. Result: ', results);
  120. var messages = [];
  121. results.forEach(messageNow => {
  122. if (messageNow.id == messageNew.id) {
  123. messages.push({"message":messageNew, "action":1});
  124. }
  125. });
  126. sendLoop(messages, serverData, 1000);
  127. });
  128. connection.end();
  129. });
  130. client.on('messageDelete', message => {
  131. if (message.author.bot==true) return;
  132. var serverData = undefined;
  133. config.servers.forEach(function(server) {
  134. if (message.channel.id==server.channel) serverData = server;
  135. });
  136. if (serverData==undefined) return;
  137. deleteFromDB(message, serverData);
  138. });
  139. client.login(config.token);
  140. async function sendLoop(messages, serverData, delay) {
  141. if (messages.length == 0) {
  142. return;
  143. }
  144. if (messages[0].action == 0) {
  145. await sendToDB(messages[0].message, serverData);
  146. } else if (messages[0].action == 1) {
  147. await updateDB(messages[0].message, serverData);
  148. } else if (messages[0].maction == 2) {
  149. deleteFromDB(messages[0].message, serverData);
  150. }
  151. messages.shift();
  152. setTimeout(sendLoop, delay, messages, serverData, delay);
  153. }
  154. async function updateDB(message, serverData) {
  155. var connection = mysql.createConnection({
  156. host : serverData.dbHost,
  157. port : serverData.dbPort,
  158. user : serverData.dbUser,
  159. password : serverData.dbPassword,
  160. database : serverData.db
  161. });
  162. var post = await prepareMessage(message, serverData);
  163. var sql = 'UPDATE '+serverData.dbTable+' SET ? WHERE id='+message.id;
  164. connection.connect();
  165. connection.query(sql, post, function (error, results, fields) {
  166. if (error) throw error;
  167. console.log(getTimestamp(), 'Data updated in db. Result: ', results);
  168. });
  169. connection.end();
  170. }
  171. async function sendToDB(message, serverData) {
  172. var connection = mysql.createConnection({
  173. host : serverData.dbHost,
  174. port : serverData.dbPort,
  175. user : serverData.dbUser,
  176. password : serverData.dbPassword,
  177. database : serverData.db
  178. });
  179. var post = await prepareMessage(message, serverData);
  180. var sql = 'INSERT INTO '+serverData.dbTable+' SET ?';
  181. connection.connect();
  182. connection.query(sql, post, function (error, results, fields) {
  183. if (error) throw error;
  184. console.log(getTimestamp(), 'Data sent to db. Result: ', results);
  185. });
  186. connection.end();
  187. }
  188. function deleteFromDB(message, serverData) {
  189. var connection = mysql.createConnection({
  190. host : serverData.dbHost,
  191. port : serverData.dbPort,
  192. user : serverData.dbUser,
  193. password : serverData.dbPassword,
  194. database : serverData.db
  195. });
  196. var sql = 'DELETE FROM '+serverData.dbTable+' WHERE id='+message.id;
  197. connection.connect();
  198. connection.query(sql, function (error, results, fields) {
  199. if (error) throw error;
  200. console.log(getTimestamp(), 'Data deleted in db. Result: ', results);
  201. });
  202. connection.end();
  203. }
  204. function prepareMessage(message, serverData) {
  205. return new Promise(async (resolve) => {
  206. var l = [];
  207. var msgCopy = message.content;
  208. msgCopy.replace(urlRegex, function(url) {
  209. l.push(url);
  210. });
  211. var i = [];
  212. message.attachments.forEach(attachment => {
  213. i.push(attachment.url);
  214. });
  215. let messageContent = message.content;
  216. await asyncForEach(message.mentions.users.array(), async (user) => {
  217. console.log(user);
  218. if (serverData.userMentionsMode == 0) {
  219. messageContent = messageContent.replace(new RegExp("<@!"+user.id+">", 'g'), "@"+user.id);
  220. } else if (serverData.userMentionsMode == 1) {
  221. messageContent = messageContent.replace(new RegExp("<@!"+user.id+">", 'g'), "@"+user.username);
  222. } else if (serverData.userMentionsMode == 2) {
  223. let nickname = await message.guild.members.fetch(user.id).then(res => res.nickname);
  224. messageContent = messageContent.replace(new RegExp("<@!"+user.id+">", 'g'), "@"+nickname);
  225. } else if (serverData.userMentionsMode == 3) {
  226. messageContent = messageContent.replace(new RegExp("<@!"+user.id+">", 'g'), "@"+user.username+"#"+user.discriminator);
  227. } else if (serverData.userMentionsMode == 4) {
  228. messageContent = messageContent.replace(new RegExp("<@!"+user.id+">", 'g'), "@"+user.id+"@");
  229. } else if (serverData.userMentionsMode == 5) {
  230. messageContent = messageContent.replace(new RegExp("<@!"+user.id+">", 'g'), "@"+user.username+"@");
  231. } else {
  232. let nickname = await message.guild.members.fetch(user.id).then(res => res.nickname);
  233. messageContent = messageContent.replace(new RegExp("<@!"+user.id+">", 'g'), "@"+nickname+"@");
  234. }
  235. });
  236. var mentions = [];
  237. message.mentions.channels.forEach(channel => {
  238. mentions.push({"channelId": channel.id, "name": channel.name});
  239. });
  240. for (mention of mentions) {
  241. if(messageContent.includes(mention.channelId)) {
  242. if (serverData.channelMentionsMode == 0) {
  243. messageContent = messageContent.replace(new RegExp("<#"+mention.channelId+">", 'g'), "#"+mention.channelId);
  244. messageContent = messageContent.replace(new RegExp("<#!"+mention.channelId+">", 'g'), "#"+mention.channelId);
  245. } else if (serverData.channelMentionsMode == 1) {
  246. messageContent = messageContent.replace(new RegExp("<#"+mention.channelId+">", 'g'), "#"+mention.name);
  247. messageContent = messageContent.replace(new RegExp("<#!"+mention.channelId+">", 'g'), "#"+mention.name);
  248. } else if (serverData.channelMentionsMode == 2) {
  249. messageContent = messageContent.replace(new RegExp("<#"+mention.channelId+">", 'g'), "#"+mention.channelId+"#");
  250. messageContent = messageContent.replace(new RegExp("<#!"+mention.channelId+">", 'g'), "#"+mention.channelId+"#");
  251. } else {
  252. messageContent = messageContent.replace(new RegExp("<#"+mention.channelId+">", 'g'), "#"+mention.name+"#");
  253. messageContent = messageContent.replace(new RegExp("<#!"+mention.channelId+">", 'g'), "#"+mention.name+"#");
  254. }
  255. }
  256. }
  257. var mentions = [];
  258. message.mentions.roles.forEach(role => {
  259. mentions.push({"roleId": role.id, "name": role.name, "color": role.color.toString(16)});
  260. });
  261. for (mention of mentions) {
  262. if(messageContent.includes(mention.roleId)) {
  263. if (serverData.roleMentionsMode == 0) {
  264. messageContent = messageContent.replace(new RegExp("<@&"+mention.roleId+">", 'g'), "&"+mention.roleId);
  265. messageContent = messageContent.replace(new RegExp("<@&!"+mention.roleId+">", 'g'), "&"+mention.roleId);
  266. } else if (serverData.roleMentionsMode == 1) {
  267. messageContent = messageContent.replace(new RegExp("<@&"+mention.roleId+">", 'g'), "&"+mention.name);
  268. messageContent = messageContent.replace(new RegExp("<@&!"+mention.roleId+">", 'g'), "&"+mention.name);
  269. } else {
  270. messageContent = messageContent.replace(new RegExp("<@&"+mention.roleId+">", 'g'), "&"+mention.name+"#"+mention.color);
  271. messageContent = messageContent.replace(new RegExp("<@&!"+mention.roleId+">", 'g'), "&"+mention.name+"#"+mention.color);
  272. }
  273. }
  274. }
  275. if (serverData.authorMode == 0) {
  276. var author = message.author.id;
  277. } else if (serverData.authorMode == 1) {
  278. var author = message.author.username;
  279. } else if (serverData.authorMode == 2) {
  280. var author = message.author.tag;
  281. } else {
  282. var author = message.member.nickname || message.author.username;
  283. }
  284. resolve({message:emoji.unemojify(messageContent), id:message.id, time:message.createdTimestamp, timeEdit:(message.editedTimestamp || ""), user:author, links:JSON.stringify(l), images:JSON.stringify(i)});
  285. });
  286. }
  287. function getTimestamp() {
  288. var d = new Date();
  289. return "["+d.getDate()+"/"+(d.getMonth()+1)+"/"+d.getFullYear()+" - "+d.getHours()+":"+d.getMinutes()+":"+d.getSeconds()+"."+d.getMilliseconds()+"]";
  290. }
  291. async function asyncForEach(array, callback) {
  292. for (let index = 0; index < array.length; index++) {
  293. await callback(array[index], index, array);
  294. }
  295. }