A discord bot for the Nouvelle Aube Airsoft Association
25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.

193 satır
6.9 KiB

2 yıl önce
  1. const Discord = require('discord.js');
  2. const client = new Discord.Client();
  3. const { Sequelize, Model, DataTypes } = require('sequelize');
  4. const sequelize = new Sequelize({
  5. dialect: 'sqlite',
  6. storage: './database.sqlite'
  7. });
  8. const format = require('util').format;
  9. var ADMIN_ROLENAME = "admin";
  10. var MEMBER_CHANNEL_NAME = "members";
  11. var EVERYONE_CHANNEL_NAME = "general";
  12. client.login('token');
  13. class Partie extends Model { }
  14. Partie.init({
  15. date_partie: {
  16. type: DataTypes.DATE,
  17. primaryKey: true,
  18. },
  19. date_fin_exclu: DataTypes.DATE,
  20. max_joueurs: DataTypes.INTEGER
  21. }, { sequelize, modelName: 'Partie' });
  22. /*class Joueur extends Model { }
  23. Joueur.init({
  24. discord_id: {
  25. type: DataTypes.STRING,
  26. primaryKey: true
  27. }
  28. }, { sequelize, modelName: 'Joueur' });*/
  29. class Joueur_Partie extends Model { }
  30. Joueur_Partie.init({
  31. id: {
  32. type: DataTypes.INTEGER,
  33. primaryKey: true,
  34. autoIncrement: true
  35. },
  36. participe: {
  37. type: DataTypes.BOOLEAN,
  38. defaultValue: false
  39. },
  40. barbeque: {
  41. type: DataTypes.BOOLEAN,
  42. defaultValue: false
  43. },
  44. location: {
  45. type: DataTypes.BOOLEAN,
  46. defaultValue: false
  47. },
  48. envoi_dm: {
  49. type: DataTypes.BOOLEAN,
  50. defaultValue: false
  51. },
  52. partie_date_partie: {
  53. type: DataTypes.DATE
  54. },
  55. joueur_discord_id: {
  56. type: DataTypes.STRING
  57. },
  58. }, { sequelize, modelName: 'Joueur_Partie' });
  59. Partie.sync({ alter: true });
  60. Joueur.sync({ alter: true });
  61. Joueur_Partie.sync({ alter: true });
  62. function adjust_date(date) {
  63. const today = new Date();
  64. const base_date = new Date(
  65. today.getFullYear(),
  66. date[2].startsWith('0') ? date[2].substring(1, 2) - 1 : date[2] - 1,
  67. date[1].startsWith('0') ? date[1].substring(1, 2) : date[1]
  68. );
  69. if (today < base_date) {
  70. return base_date;
  71. } else {
  72. return new Date(
  73. base_date.getFullYear() + 1,
  74. base_date.getMonth(),
  75. base_date.getDay()
  76. );
  77. }
  78. }
  79. client.on('ready', () => {
  80. console.log(`Logged in as ${client.user.tag}!`);
  81. });
  82. client.on('message', async function(msg) {
  83. if(msg.guild == undefined) return; // Pour que les DM trigger pas les call
  84. const admin_role = msg.guild.roles.cache.find(r => (r.name == ADMIN_ROLENAME));
  85. const member_channel = msg.guild.channels.cache.find(r => (r.name == MEMBER_CHANNEL_NAME));
  86. if (msg.content.startsWith('/organiser ') && msg.member.roles.cache.find(r => (r == admin_role))) {
  87. const args = msg.content.split(/(\s+)/).filter(e => (e.trim().length > 0));
  88. const parser = /^(\d{2})\/(\d{2})$/;
  89. const date_de_partie = adjust_date(args[1].match(parser)).toISOString();
  90. const date_fin_exclu = adjust_date(args[2].match(parser)).toISOString();
  91. const nb_joueurs = parseInt(args[3].match(parser));
  92. const partie = Partie.build({
  93. date_partie: date_de_partie,
  94. date_fin_exclu: date_fin_exclu,
  95. max_joueurs: nb_joueurs
  96. });
  97. partie.save();
  98. const message = await member_channel.send(format(
  99. `
  100. Une partie est organisée le %s!
  101. Réagissez avec 👍 pour recevoir le formulaire d'inscription!
  102. `
  103. , args[1]));
  104. message.react('👍');
  105. const collector = message.createReactionCollector(v => (true), {});
  106. collector.on('collect', async function(m) {
  107. m.users.cache.forEach(async function(user, _) {
  108. if(user.id == client.user.id) return;
  109. const j = await Joueur.findOrCreate({where: {discord_id: user.id}, default: {discord_id: user.id}});
  110. var [p, _] = await Joueur_Partie.findOrCreate({
  111. where: {joueur_discord_id: user.id, partie_date_partie: partie.date_partie},
  112. default: {joueur_discord_id: user.id, partie_date_partie: partie.date_partie}
  113. });
  114. if(!p.envoi_dm) {
  115. const discord_user = await client.users.fetch(user.id)
  116. const dms = await discord_user.createDM();
  117. const sent_dm = await dms.send(
  118. format(`
  119. Pour vous inscrire à la partie du %s, réagissez à ce message avec l'émote appropriée:
  120. 🔫: Participe à la partie
  121. 🍴: Participe au repas
  122. 🥺: Loue une réplique
  123. `, partie.date_partie));
  124. await p.save();
  125. await sent_dm.react('🔫');
  126. await sent_dm.react('🍴');
  127. await sent_dm.react('🥺');
  128. const personal_collector = sent_dm.createReactionCollector(v => (true), {});
  129. personal_collector.on('collect', async function(m) {
  130. console.log(m._emoji.name);
  131. for(var [user, rest] of m.users.cache) {
  132. if(user != client.user.id) {
  133. var element = await Joueur_Partie.findOne({where: {joueur_discord_id: user, partie_date_partie: date_de_partie}});
  134. if(m._emoji.name == '🔫') {
  135. element.participe = true;
  136. console.log(await element.save());
  137. } else if(m._emoji.name == '🍴') {
  138. element.barbeque = true;
  139. await element.save();
  140. } else if(m._emoji.name =='🥺') {
  141. element.location = true;
  142. await element.save();
  143. }
  144. }
  145. }
  146. });
  147. p.envoi_dm = true;
  148. await p.save();
  149. }
  150. });
  151. })
  152. } else if (msg.content.startsWith('/liste ') && msg.member.roles.cache.find(r => (r == admin_role))) {
  153. const args = msg.content.split(/(\s+)/).filter(e => (e.trim().length > 0));
  154. const parser = /^(\d{2})\/(\d{2})$/;
  155. const date_de_partie = adjust_date(args[1].match(parser)).toISOString();
  156. const liste = await Joueur_Partie.findAll({where: {partie_date_partie: date_de_partie}});
  157. const dm = await msg.author.createDM();
  158. const participants = await Joueur_Partie.count({where: {partie_date_partie: date_de_partie, participe: true}});
  159. const repas = await Joueur_Partie.count({where: {partie_date_partie: date_de_partie, barbeque: true}});
  160. const loca = await Joueur_Partie.count({where: {partie_date_partie: date_de_partie, location: true}});
  161. await dm.send(format("Liste de la partie du %s\ninscrits=%i\nrepas=%i\nloca=%i", args[1], participants, repas, loca));
  162. for(const element of liste) {
  163. const inscrit = await client.users.fetch(element.joueur_discord_id);
  164. await dm.send(format(inscrit.username));
  165. }
  166. }
  167. });