Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CoinFlips & Database Fun 🎉 #8

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# Database
data/*

# Mac
.DS_Store

# Dependencies
node_modules

Expand Down
13 changes: 12 additions & 1 deletion Bot.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ const InteractionHandler = require(`./InteractionHandler`);
const MessageHandler = require(`./MessageHandler`);
const ReactionHandler = require(`./ReactionHandler`);

const db = require(`./Database`);
const dotenv = require(`dotenv`);
const sparkles = require(`sparkles`)();

dotenv.config();

class Bot {
Expand Down Expand Up @@ -98,7 +101,7 @@ class Bot {

onGuildJoin() {
console.log(`joined new guild`);
this.InteractionHandler.updateCommands();
this.InteractionHandler.createCommands();
}

/**
Expand All @@ -108,6 +111,14 @@ class Bot {
this.InteractionHandler.updateCommands();
console.log(`Connected to Discord as ${this.client.user.username}#${this.client.user.discriminator} <@${this.client.user.id}>`);
console.log(`Using lnbits host: ${process.env.LNBITS_HOST}`);

//db.sequelize.sync({ alter: true });

//drop the table if it already exists
db.sequelize.sync({ force: true }).then(() => {
console.log(`Drop and re-sync db.`);
sparkles.emit(`setupDatabase`);
});
}
}

Expand Down
30 changes: 30 additions & 0 deletions Buttons/CancelFlip.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
const Button = require(`./Button.js`);
const db = require(`../Database`);

/*
This command will cancel an existing coinflip, only the creator can cancel
*/

class CancelFlip extends Button {
constructor() {
super();
this.name = `cancelflip`;
this.description = `Cancel a CoinFlip.`;
this.options = [];
}

async execute(Interaction) {

const coinFlipDetails = await db.coinflips.findAll({ where: { commandId: `${Interaction.message.interaction.id}` }});

if (coinFlipDetails[0].creator == Interaction.user.id) {
console.log(`Will Cancel the event`);
coinFlipDetails[0].update({ status: `closed` });
Interaction.update({content: `Coin Flip was cancelled`});
} else {
console.log(`Wrong user attempted to cancel the event`);
}
}
}

module.exports = CancelFlip;
59 changes: 59 additions & 0 deletions Buttons/JoinFlip.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
const Button = require(`./Button.js`);
const sparkles = require(`sparkles`)();
const db = require(`../Database`);

/*
This command will enroll a user in a coinflip
*/

class JoinFlip extends Button {
constructor() {
super();
this.name = `joinflip`;
this.description = `Joins a CoinFlip.`;
this.options = [];
}

async execute(Interaction) {
console.log(`button click by ${Interaction.user.id}`);
console.log(Interaction.message.content);
//console.log(`Join Interaction`, Interaction);
console.log(`Join Interaction`, Interaction.message.interaction.id);


// TODO if going to use the db directly here likely no need for events from sparkles here.
const coinFlipDetails = await db.coinflips.findAll({ where: { commandId: `${Interaction.message.interaction.id}` }});
const currentlyEntered = await db.coinflipentry.findAll({ where: { coinFlipId: `${Interaction.message.interaction.id}` }});

if (coinFlipDetails[0].maxPlayers > currentlyEntered.length) {
console.log(`there is space in the event`);
// Join Event
sparkles.emit(`joinCoinFlip`, {
Interaction,
userId: Interaction.user.id,
coinFlipId: Interaction.message.interaction.id
});

} else {
console.log(`There is no more space in the event!!`);
}

/* Update the current command body */

const allEnteredUsers = await db.coinflipentry.findAll({ where: { coinFlipId: `${Interaction.message.interaction.id}` }});
let currentPot = parseInt(allEnteredUsers.length) * parseInt(coinFlipDetails[0].entryFee);

let entrantsText = `Entrants: `;
allEnteredUsers.forEach(element => {
entrantsText += `${element.userId},`;
});

console.log(`entrantsText`, entrantsText);
let content = Interaction.message.content;
content = content.replace(/Current Pot:.*/, `Current Pot: ${currentPot}`);
content = content.replace(/Entrants:.*/, entrantsText);
Interaction.update({content: content});
}
}

module.exports = JoinFlip;
98 changes: 98 additions & 0 deletions Commands/CoinFlip.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
const Discord = require(`discord.js`);
const Command = require(`./Command.js`);
const sparkles = require(`sparkles`)();
const dedent = require(`dedent-js`);
const db = require(`../Database`);

/*
This command will create a coin flip event allowing n users to contribute to a pool with one winner.
*/

class CoinFlip extends Command {
constructor() {
super();
this.name = `coinflip`;
this.description = `Create a coin flip between a number of entrants.`;
this.options = [{
name: `numofpeople`,
type: `INTEGER`,
description: `Number of people in the event (including you)`,
required: true,
},{
name: `entryamount`,
type: `INTEGER`,
description: `Number of Satoshis required for entry`,
required: true,
}];
}

async execute(Interaction) {
const amount = Interaction.options.get(`entryamount`);
const numOfPeople = Interaction.options.get(`numofpeople`);

let member;

if (amount.value <= 0) {
Interaction.reply({
content: `Negative balances are not permitted`,
ephemeral: true
});
return;
}


try {
member = await Interaction.guild.members.fetch(Interaction.user.id);
} catch(err) {
console.log(err);
}

/* Check if User has an active flip already */

const coinFlipDetails = await db.coinflip.getUserFlips(Interaction.user.id);

if (coinFlipDetails.length > 0) {
await Interaction.deferReply({ephemeral: true});
console.log(`CoinFlip already active for this user`, coinFlipDetails);
Interaction.editReply({content: `You already have an active flip, please cancel that first.`, ephemeral: true});
} else {
await Interaction.deferReply();
sparkles.emit(`createCoinFlip`, {
Interaction,
member,
numOfPeople: numOfPeople.value,
amount: amount.value
});

try {
const row = new Discord.MessageActionRow()
.addComponents([
new Discord.MessageButton({
custom_id: `joinflip`,
label: `Join Flip!`,
emoji: { name: `➕` },
style: `SECONDARY`
}),
new Discord.MessageButton({
custom_id: `cancelflip`,
label: `Cancel Flip [creator]`,
emoji: { name: `❌` },
style: `SECONDARY`
})
]);

const msgContent = dedent(`
${Interaction.user.username} started a coinflip! ${numOfPeople.value} can enter for ${amount.value} satoshis each!
Current Pot:
Entrants:
`);

Interaction.editReply({content: msgContent, components: [row], ephemeral:false });
} catch(err) {
console.log(err);
}
}
}
}

module.exports = CoinFlip;
14 changes: 14 additions & 0 deletions Database/CoinFlip/coinflipentrants.model.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module.exports = (sequelize, Sequelize) => {
const Entrants = sequelize.define(`Entrants`, {
// Model attributes are defined here
userId: {
type: Sequelize.STRING,
allowNull: false
},
coinFlipId: {
type: Sequelize.STRING,
allowNull: false
}
});
return Entrants;
};
28 changes: 28 additions & 0 deletions Database/CoinFlip/coinflips.model.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
module.exports = (sequelize, Sequelize) => {
const Flips = sequelize.define(`CoinFlips`, {
creator: {
type: Sequelize.STRING,
allowNull: false
},
commandId: {
type: Sequelize.STRING,
allowNull: false
},
entryFee: {
type: Sequelize.INTEGER,
allowNull: false,
default: 0
},
maxPlayers: {
type: Sequelize.INTEGER,
allowNull: false,
default: 0
},
status: {
type: Sequelize.STRING,
allowNull: false,
default: `open`
}
});
return Flips;
};
73 changes: 73 additions & 0 deletions Database/CoinFlip/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
const Sequelize = require(`sequelize`);
const sparkles = require(`sparkles`)();
// const sequelize = new Sequelize(dbConfig.DB, dbConfig.USER, dbConfig.PASSWORD, {
// host: dbConfig.HOST,
// dialect: dbConfig.dialect,
// operatorsAliases: false,

// pool: {
// max: dbConfig.pool.max,
// min: dbConfig.pool.min,
// acquire: dbConfig.pool.acquire,
// idle: dbConfig.pool.idle
// }
// });

const sequelize = new Sequelize({
dialect: `sqlite`,
storage: `data/database.sqlite`
});

const db = {};

db.Sequelize = Sequelize;
db.sequelize = sequelize;

sparkles.on(`setupDatabase`, function(){
db.coinflips = require(`./coinflips.model.js`)(sequelize, Sequelize);
db.coinflipentry = require(`./coinflipentrants.model.js`)(sequelize, Sequelize);
});



db.getUserFlips = async function(userId) {
const coinFlipDetails = await db.coinflips.findAll({ where: { creator: `${userId}`, status: `open` }});
console.log(coinFlipDetails);
return coinFlipDetails;
};

sparkles.on(`createCoinFlip`, function(e){
createCoinFlip(e);
});

function createCoinFlip(event) {
console.log(`create event fired`);

const flip = {
creator: event.member.id,
commandId: event.Interaction.id,
entryFee: event.amount,
maxPlayers: event.numOfPeople,
status: `open`
};
console.log(`create flip`, flip);
db.coinflips.create(flip);
}

sparkles.on(`joinCoinFlip`, function(e){
joinCoinFlip(e);
});

function joinCoinFlip(event) {
console.log(`join event fired`);

const flip = {
userId: event.userId,
coinFlipId: event.coinFlipId
};
console.log(`create flip`, flip);
db.coinflipentry.create(flip);
}


module.exports = db;
31 changes: 31 additions & 0 deletions Database/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const Sequelize = require(`sequelize`);
// const sparkles = require(`sparkles`)();
// const sequelize = new Sequelize(dbConfig.DB, dbConfig.USER, dbConfig.PASSWORD, {
// host: dbConfig.HOST,
// dialect: dbConfig.dialect,
// operatorsAliases: false,

// pool: {
// max: dbConfig.pool.max,
// min: dbConfig.pool.min,
// acquire: dbConfig.pool.acquire,
// idle: dbConfig.pool.idle
// }
// });

const sequelize = new Sequelize({
dialect: `sqlite`,
storage: `data/database.sqlite`
});

const db = {};

db.Sequelize = Sequelize;
db.sequelize = sequelize;

db.coinflip = require(`./CoinFlip`);
db.coinflips = require(`./CoinFlip/coinflips.model.js`)(sequelize, Sequelize);
db.coinflipentry = require(`./CoinFlip/coinflipentrants.model.js`)(sequelize, Sequelize);
// db.coinflip.setup();

module.exports = db;
Loading