Skip to content

Commit

Permalink
Initial Commit
Browse files Browse the repository at this point in the history
  • Loading branch information
crock committed Jun 30, 2020
0 parents commit c8fe5b5
Show file tree
Hide file tree
Showing 9 changed files with 3,335 additions and 0 deletions.
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
TOKEN="discord bot token here"
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
serviceAccountKey.json
.env
node_modules/
7 changes: 7 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
FROM node:12-alpine

COPY package*.json ./
RUN npm install
COPY . ./

CMD npm start
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Simple Discord Points Bot

Originally created for the [Domaincord Community](https://discord.gg/R6wTYQ9).

## Usage
I'm assuming you already know how to get a bot token and add the bot to your server.

1. Rename the `.env.example` file to `.env` and fill in the appropriate values.
2. Download a Firebase Admin service account key and put it in the root directory of the bot folder and make sure to call it `serviceAccountKey.json`
2. Run `npm install`
3. Run `npm start` or use a process manager like [pm2](https://pm2.keymetrics.io/) to keep the bot running across server restarts and automatically restart the bot if it crashes.

**Make sure the bot has access to read and send messages in all channels you want the commands to be used!**
24 changes: 24 additions & 0 deletions cloudbuild.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
steps:
# Build the container image
- name: "gcr.io/cloud-builders/docker"
args: ["build", "-t", "gcr.io/$PROJECT_ID/${_REPO}", "."]
# Push the container image to Container Registry
- name: "gcr.io/cloud-builders/docker"
args: ["push", "gcr.io/$PROJECT_ID/${_REPO}"]
# Update existing compute engine vm instance with new Docker image
- name: "gcr.io/cloud-builders/gcloud"
args:
[
"compute",
"instances",
"update-container",
"${_REPO}",
"--zone",
"${_ZONE}",
"--container-image=gcr.io/$PROJECT_ID/${_REPO}",
]
substitutions:
_REPO: "points-bot"
_ZONE: "us-east1-b"
timeout: "1600s"
images: ["gcr.io/$PROJECT_ID/${_REPO}"]
190 changes: 190 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
if (process.env.NODE_ENV === 'development') {
require('dotenv').config()
}

const Discord = require('discord.js')
const client = new Discord.Client()

const prefix = "!"

const MIN_POINTS_PER_MESSAGE_SENT = 1
const MAX_POINTS_PER_MESSAGE_SENT = 10
const POINTS_PER_REP_RECEIVED = 100

const admin = require("firebase-admin");
const FieldValue = admin.firestore.FieldValue;
const serviceAccount = process.env.NODE_ENV === 'development'
? admin.credential.cert(require("./serviceAccountKey.json"))
: admin.credential.applicationDefault()

admin.initializeApp({
credential: serviceAccount,
databaseURL: "https://domaincord-market.firebaseio.com"
});

const db = admin.firestore();

const hasPositiveThanks = msg => {
const thankPattern = /(^|[^a-z]+)(thanks?|thxs?|ty|thankyou|thnx|thnks|htank|thansk)($|[^a-z]+)/g
return thankPattern.test(msg.content.toLowerCase())
}

const incrementUserPointsTotal = (member, points = MIN_POINTS_PER_MESSAGE_SENT ) => {
const ref = db.collection('users').doc(member.id)
ref.set({
totalPoints: FieldValue.increment(points)
}, {merge: true})
}

const decrementUserPointsTotal = (member, points = MIN_POINTS_PER_MESSAGE_SENT ) => {
const ref = db.collection('users').doc(member.id)
ref.set({
totalPoints: FieldValue.decrement(points)
}, {merge: true})
}

client.on('ready', async () => {
console.log(`Logged in as ${client.user.tag}!`)
await client.user.setActivity('Tracking member points!');
})

client.on('message', msg => {
if (msg.author.bot) return

if (msg.content.indexOf(prefix) === 0) {
const args = msg.content
.slice(prefix.length)
.trim()
.split(/ +/g)

const command = args
.shift()
.toLowerCase()
.replace('/', '')

if (command === 'points') {
let theMember = msg.mentions.members.array().length > 0 ? msg.mentions.members.first() : msg.member
let memberRef = db.collection('users').doc(theMember.id);
let getDoc = memberRef.get()
.then(doc => {
if (!doc.exists) {
console.log('No such member document!');
} else {
console.log('Document data:', doc.data().totalPoints);
const memberPointsEmbed = new Discord.RichEmbed()
.setTitle(`${theMember.user.username}'s Points`)
.setDescription(`Total Points: ${doc.data().totalPoints}`)
.setFooter(`Use "thanks @user" to give someone rep, and "${prefix}points @user" to see how much they have!`);

msg.channel.send({embed: memberPointsEmbed})
}
})
.catch(err => {
console.log('Error getting document', err);
});

}

if (command === 'top') {

db.collection('users').orderBy('totalPoints', 'desc').limit(10).get()
.then(snapshot => {
if (snapshot.empty) {
console.log('No matching documents.');
return;
}

const topTenEmbed = new Discord.RichEmbed()
.setTitle('Most Reputation');

const lines = []
const members = msg.guild.members.filter(member => !member.user.bot)

let curr = 1
snapshot.forEach(doc => {
const member = members.find(member => member.id === doc.id)
if (member) {
let line = `${curr}. ${member.user.tag}: ${doc.data().totalPoints}`
curr++
lines.push(line)
}
})

console.log(lines)
topTenEmbed.setDescription(lines.join('\n'))

msg.channel.send({embed: topTenEmbed})

})
.catch(err => {
console.log('Error getting documents', err);
});

}
}

if (msg.content.length >= 30) {
incrementUserPointsTotal(msg.member, MAX_POINTS_PER_MESSAGE_SENT)
db.collection('/points').add({
messageId: msg.id,
userId: msg.member.id,
giverId: client.user.id,
pointValue: MAX_POINTS_PER_MESSAGE_SENT,
timestamp: FieldValue.serverTimestamp()
}).then(ref => {
console.log('Added document with ID: ', ref.id);
})
} else {
incrementUserPointsTotal(msg.member)
db.collection('/points').add({
messageId: msg.id,
userId: msg.member.id,
giverId: client.user.id,
pointValue: MIN_POINTS_PER_MESSAGE_SENT,
timestamp: FieldValue.serverTimestamp()
}).then(ref => {
console.log('Added document with ID: ', ref.id);
})
}

if (hasPositiveThanks(msg)) {
console.log('thanks logged')
if (msg.mentions.members.array().length >= 1) {
msg.mentions.members.map(member => {
if (member.user.bot) {
msg.reply('You cannot thank a bot.')
} else if (member.id !== msg.member.id) {
incrementUserPointsTotal(member, POINTS_PER_REP_RECEIVED)
db.collection('/points').add({
messageId: msg.id,
userId: member.id,
giverId: msg.member.id,
pointValue: POINTS_PER_REP_RECEIVED,
timestamp: FieldValue.serverTimestamp()
}).then(ref => {
console.log('Added document with ID: ', ref.id);
const mentionsString = msg.mentions.members.array().join(' & ')
const thankActionVerb = msg.mentions.members.array().length === 1 ? 'has' : 'have'

const thanksEmbed = new Discord.RichEmbed()
.setTitle('Thanks Received!')
.setDescription(`${mentionsString} ${thankActionVerb} been thanked by **${msg.member.user.tag}**!`)
.setFooter(`Use "thanks @user" to give someone rep, and "${prefix}points @user" to see how much they have!`);

msg.channel.send({embed: thanksEmbed})
})
} else {
msg.reply(`You can't thank yourself, you silly goose!`)
}
})
} else {
msg.reply('You must tag someone to thank them.')
}
}
})

if (process.env.TOKEN !== null) {
client.login(process.env.TOKEN)
} else {
console.error('Bot token is empty!')
}
Loading

3 comments on commit c8fe5b5

@adham113v
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i need a help give me your discord name plz

@adham113v
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yo crock are you here @crock

@adham113v
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

helppppppp

Please sign in to comment.