initial commit
This commit is contained in:
commit
f455121741
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
node_modules
|
||||
package-lock.json
|
||||
config.json
|
||||
.idea
|
55
database.sql
Normal file
55
database.sql
Normal file
@ -0,0 +1,55 @@
|
||||
DROP TABLE IF EXISTS vote_member;
|
||||
DROP TABLE IF EXISTS member;
|
||||
DROP TABLE IF EXISTS vote;
|
||||
DROP TABLE IF EXISTS poll;
|
||||
DROP TABLE IF EXISTS guild;
|
||||
|
||||
CREATE TABLE guild
|
||||
(
|
||||
guild_id VARCHAR(255),
|
||||
PRIMARY KEY (guild_id)
|
||||
);
|
||||
|
||||
CREATE TABLE poll
|
||||
(
|
||||
poll_id UUID,
|
||||
creator VARCHAR(255),
|
||||
guild_id VARCHAR(255),
|
||||
question VARCHAR(255),
|
||||
opened BOOLEAN,
|
||||
PRIMARY KEY (poll_id),
|
||||
FOREIGN KEY (guild_id) REFERENCES guild (guild_id)
|
||||
);
|
||||
|
||||
CREATE TABLE vote
|
||||
(
|
||||
poll_id UUID,
|
||||
vote_id VARCHAR(255),
|
||||
vote_option VARCHAR(255),
|
||||
PRIMARY KEY (vote_id),
|
||||
FOREIGN KEY (poll_id) REFERENCES poll (poll_id)
|
||||
);
|
||||
|
||||
CREATE TABLE member
|
||||
(
|
||||
user_id VARCHAR(255),
|
||||
guild_id VARCHAR(255),
|
||||
username VARCHAR(255),
|
||||
points bigint DEFAULT 50 NOT NULL CHECK (points >= 50),
|
||||
bet_value bigint DEFAULT 50,
|
||||
PRIMARY KEY (user_id),
|
||||
FOREIGN KEY (guild_id) REFERENCES guild (guild_id)
|
||||
);
|
||||
|
||||
CREATE TABLE vote_member
|
||||
(
|
||||
user_id VARCHAR(255),
|
||||
guild_id VARCHAR(255),
|
||||
vote_id VARCHAR(255),
|
||||
poll_id UUID,
|
||||
bet_value bigint DEFAULT 50,
|
||||
FOREIGN KEY (guild_id) REFERENCES guild (guild_id),
|
||||
FOREIGN KEY (user_id) REFERENCES member (user_id),
|
||||
FOREIGN KEY (vote_id) REFERENCES vote (vote_id),
|
||||
FOREIGN KEY (poll_id) REFERENCES poll (poll_id)
|
||||
);
|
18
package.json
Normal file
18
package.json
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "gambling-bot",
|
||||
"version": "1.0.0",
|
||||
"description": "a simple gambling discord bot",
|
||||
"license": "ISC",
|
||||
"author": "",
|
||||
"type": "commonjs",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"dependencies": {
|
||||
"discord-api-types": "^0.38.13",
|
||||
"discord.js": "^14.21.0",
|
||||
"pg": "^8.16.3",
|
||||
"uuid": "^11.1.0"
|
||||
}
|
||||
}
|
45
src/constants.js
Normal file
45
src/constants.js
Normal file
@ -0,0 +1,45 @@
|
||||
const {SlashCommandBuilder} = require("discord.js");
|
||||
|
||||
const POLL_COMMAND_NAME = 'poll';
|
||||
const BET_COMMAND_NAME = 'bet';
|
||||
const CLOSE_COMMAND_NAME = 'close';
|
||||
const PROFIL_COMMAND_NAME = 'profil';
|
||||
|
||||
const POLL_COMMAND = new SlashCommandBuilder()
|
||||
.setName("poll")
|
||||
.setDescription("Des votes sur lesquels gamble");
|
||||
|
||||
const BET_COMMAND = new SlashCommandBuilder()
|
||||
.setName("bet")
|
||||
.setDescription("Pour pouvoir planifier le prochain pari !")
|
||||
.addNumberOption(option => option
|
||||
.setName("somme")
|
||||
.setDescription("La somme du prochain pari")
|
||||
.setRequired(true)
|
||||
.setMinValue(0));
|
||||
|
||||
const CLOSE_COMMAND = new SlashCommandBuilder()
|
||||
.setName("close")
|
||||
.setDescription("Pour clôturer un sondage")
|
||||
.addStringOption(option => option
|
||||
.setName("option")
|
||||
.setDescription("L'issue du sondage")
|
||||
.setRequired(true));
|
||||
|
||||
const PROFIL_COMMAND = new SlashCommandBuilder()
|
||||
.setName("profil")
|
||||
.setDescription("Afficher des informations sur un utilisateur")
|
||||
.addUserOption(option => option
|
||||
.setName("user")
|
||||
.setDescription("La personne concernée")
|
||||
.setRequired(false));
|
||||
|
||||
exports.POLL_COMMAND_NAME = POLL_COMMAND_NAME
|
||||
exports.BET_COMMAND_NAME = BET_COMMAND_NAME
|
||||
exports.CLOSE_COMMAND_NAME = CLOSE_COMMAND_NAME
|
||||
exports.PROFIL_COMMAND_NAME = PROFIL_COMMAND_NAME
|
||||
|
||||
exports.POLL_COMMAND = POLL_COMMAND
|
||||
exports.BET_COMMAND = BET_COMMAND
|
||||
exports.CLOSE_COMMAND = CLOSE_COMMAND
|
||||
exports.PROFIL_COMMAND = PROFIL_COMMAND
|
25
src/database.js
Normal file
25
src/database.js
Normal file
@ -0,0 +1,25 @@
|
||||
const { Client } = require('pg');
|
||||
const {DB_NAME, DB_USER, DB_PASSWORD, DB_ADDRESS, DB_PORT} = require('../config.json');
|
||||
|
||||
const DATABASE_CLIENT = new Client({
|
||||
user: DB_USER,
|
||||
password: DB_PASSWORD,
|
||||
host: DB_ADDRESS,
|
||||
port: DB_PORT,
|
||||
database: DB_NAME,
|
||||
});
|
||||
|
||||
async function userExists() {
|
||||
const res = await DATABASE_CLIENT.query("SELECT * FROM member");
|
||||
return res.rows;
|
||||
}
|
||||
|
||||
async function insertPollIntoDB(creatorId, pollId, guildId, questionLabel) {
|
||||
const response = await DATABASE_CLIENT.query("INSERT INTO poll(creator, poll_id, guild_id, question, opened) VALUES ($1, $2, $3, $4, true)", [creatorId, pollId, guildId, questionLabel])
|
||||
return response.rows;
|
||||
}
|
||||
|
||||
exports.DATABASE_CLIENT = DATABASE_CLIENT;
|
||||
exports.userExists = userExists;
|
||||
exports.insertPollIntoDB = insertPollIntoDB;
|
||||
|
13
src/deploy-commands.js
Normal file
13
src/deploy-commands.js
Normal file
@ -0,0 +1,13 @@
|
||||
const {POLL_COMMAND, BET_COMMAND, CLOSE_COMMAND, PROFIL_COMMAND} = require("./constants")
|
||||
const {TOKEN, APPLICATION_ID} = require('../config.json')
|
||||
const {REST} = require("discord.js");
|
||||
const { Routes } = require('discord-api-types/v10');
|
||||
|
||||
const commands = [POLL_COMMAND, BET_COMMAND, CLOSE_COMMAND, PROFIL_COMMAND].map(command => command.toJSON());
|
||||
const rest = new REST({version: '10'}).setToken(TOKEN);
|
||||
|
||||
console.log(commands)
|
||||
|
||||
rest.put(Routes.applicationCommands(APPLICATION_ID), { body: commands })
|
||||
.then(() => console.log('Successfully registered application commands.'))
|
||||
.catch(console.error);
|
129
src/main.js
Normal file
129
src/main.js
Normal file
@ -0,0 +1,129 @@
|
||||
const {
|
||||
Client,
|
||||
Events,
|
||||
GatewayIntentBits,
|
||||
ModalBuilder,
|
||||
TextInputBuilder,
|
||||
ActionRowBuilder,
|
||||
EmbedBuilder,
|
||||
Colors, ButtonBuilder
|
||||
} = require('discord.js');
|
||||
const {DATABASE_CLIENT, insertPollIntoDB} = require('./database');
|
||||
const {TOKEN} = require('../config.json');
|
||||
const {v4: uuidv4} = require('uuid');
|
||||
const {POLL_COMMAND_NAME} = require("./constants");
|
||||
const {ButtonStyle} = require("discord-api-types/v10");
|
||||
|
||||
const client = new Client({intents: [GatewayIntentBits.Guilds]});
|
||||
|
||||
client.once(Events.ClientReady, async readyClient => {
|
||||
console.log(`Ready! Logged in as ${readyClient.user.tag}`);
|
||||
await DATABASE_CLIENT.connect();
|
||||
});
|
||||
|
||||
client.on(Events.InteractionCreate, async interaction => {
|
||||
if (interaction.isCommand()) {
|
||||
const {commandName} = interaction;
|
||||
|
||||
if (commandName === POLL_COMMAND_NAME) {
|
||||
await interaction.showModal(buildPollModal());
|
||||
}
|
||||
} else if (interaction.isModalSubmit()) {
|
||||
const pollToCreate = interaction.components;
|
||||
const sender = interaction.user;
|
||||
const guildFromWhereUserSendedInteraction = interaction.member.guild;
|
||||
const pollQuestionObj = pollToCreate[0].components[0];
|
||||
let voteOptions = [
|
||||
pollToCreate[1].components[0].value,
|
||||
pollToCreate[2].components[0].value,
|
||||
pollToCreate[3].components[0].value,
|
||||
pollToCreate[4].components[0].value
|
||||
];
|
||||
|
||||
voteOptions = [...new Set(voteOptions)].filter(voteOption => voteOption !== '');
|
||||
const introEmbed = new EmbedBuilder()
|
||||
.setTitle("Les paris sont ouverts !")
|
||||
.setDescription("Vous pouvez parier vos points, ils ne passeront pas en dessous de 50")
|
||||
.setColor(Colors.Aqua);
|
||||
const buttons = new ActionRowBuilder();
|
||||
|
||||
let pollDesc = '';
|
||||
voteOptions.forEach((voteOption, index) => {
|
||||
buttons.addComponents(new ButtonBuilder()
|
||||
.setCustomId(`${interaction.customId}_${voteOption}_${index + 1}`)
|
||||
.setLabel(voteOption)
|
||||
.setStyle(ButtonStyle.Primary));
|
||||
pollDesc += `Option ${index + 1}: ${voteOption}\n`
|
||||
});
|
||||
|
||||
const pollEmbed = new EmbedBuilder()
|
||||
.setTitle(`Sondage: ${pollQuestionObj.value}`)
|
||||
.setDescription(pollDesc)
|
||||
.setColor(Colors.Green);
|
||||
|
||||
insertPollIntoDB(sender.id, interaction.customId, guildFromWhereUserSendedInteraction.id, pollQuestionObj.value);
|
||||
|
||||
await interaction.reply({embeds: [introEmbed, pollEmbed], components: [buttons]});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
function buildPollModal() {
|
||||
const pollId = uuidv4();
|
||||
|
||||
const pollModal = new ModalBuilder()
|
||||
.setTitle("Créer un vote")
|
||||
.setCustomId(pollId)
|
||||
|
||||
const questionRow = new ActionRowBuilder().addComponents(
|
||||
new TextInputBuilder()
|
||||
.setCustomId("label")
|
||||
.setLabel("Question du vote")
|
||||
.setPlaceholder("Shy aime-t-il les robots?")
|
||||
.setStyle(1)
|
||||
.setMinLength(1)
|
||||
.setRequired(true)
|
||||
);
|
||||
|
||||
const firstOption = new ActionRowBuilder().addComponents(
|
||||
new TextInputBuilder()
|
||||
.setCustomId("vote1")
|
||||
.setLabel("Première option")
|
||||
.setPlaceholder("Oui")
|
||||
.setStyle(1)
|
||||
.setMinLength(1)
|
||||
.setRequired(true)
|
||||
);
|
||||
|
||||
const secondOption = new ActionRowBuilder().addComponents(
|
||||
new TextInputBuilder()
|
||||
.setCustomId("vote2")
|
||||
.setLabel("Deuxième option")
|
||||
.setPlaceholder("Non")
|
||||
.setStyle(1)
|
||||
.setMinLength(1)
|
||||
.setRequired(false)
|
||||
);
|
||||
const thirdOption = new ActionRowBuilder().addComponents(
|
||||
new TextInputBuilder()
|
||||
.setCustomId("vote3")
|
||||
.setLabel("Troisième option")
|
||||
.setPlaceholder("Peut-être")
|
||||
.setStyle(1)
|
||||
.setMinLength(1)
|
||||
.setRequired(false)
|
||||
);
|
||||
const fourthOption = new ActionRowBuilder().addComponents(
|
||||
new TextInputBuilder()
|
||||
.setCustomId("vote4")
|
||||
.setLabel("Quatrième option")
|
||||
.setPlaceholder("Pas du tout")
|
||||
.setStyle(1)
|
||||
.setMinLength(1)
|
||||
.setRequired(false)
|
||||
);
|
||||
|
||||
return pollModal.addComponents(questionRow, firstOption, secondOption, thirdOption, fourthOption);
|
||||
}
|
||||
|
||||
client.login(TOKEN);
|
Loading…
Reference in New Issue
Block a user