Skip to content

Instantly share code, notes, and snippets.

@apos37
Created August 12, 2022 21:32
Show Gist options
  • Save apos37/4ec2cbeb97f71c4443039dad34810e25 to your computer and use it in GitHub Desktop.
Save apos37/4ec2cbeb97f71c4443039dad34810e25 to your computer and use it in GitHub Desktop.
Pylon Bot Karma Commands and Rewards
import { commands } from './command_group';
import {
ADMIN_ROLE_ID,
BIG_HELPER_ROLE_ID,
APPROVED_FOR_HIRE_ID,
FREELANCER_FOR_HIRE_ID,
EXPERTS_FOR_HIRE_CHANNEL_ID,
} from './ids';
/**
* Courtesy of Kile on Pylon discord server
* https://github.com/Kile/karma/blob/master/karma.ts
* This is my version, with additions. Gives a role once they receive enough karma.
*/
const karmaKv = new pylon.KVNamespace('karma');
async function getBalance(userId: discord.Snowflake): Promise<number> {
const bal = await karmaKv.get<number>(userId);
return bal || 0;
}
discord.on('MESSAGE_CREATE', async (message) => {
// Stop if there are no mentions or if this message is not a reply
if (
(message.mentions[0] == null || message.mentions[0] == undefined) &&
message.type !== discord.Message.Type.REPLY
) {
return;
}
// Get the user
var userId;
var userIds = [];
// If the user is mentioned
if (message.mentions[0]) {
// Now check for multiple mentions
if (message.mentions.length > 1) {
for (let _m = 0; _m < message.mentions.length; _m++) {
userId = message.mentions[_m].id;
userIds.push(userId);
}
} else {
userId = message.mentions[0].id;
userIds.push(userId);
}
// Or if this message a reply to another message
} else if (
message.messageReference !== undefined &&
message.messageReference !== null
) {
const _channelId = message.messageReference.channelId;
const _messageId = message.messageReference.messageId;
if (_channelId !== undefined && _messageId !== undefined) {
const _channel = await discord.getGuildTextChannel(_channelId.toString());
const _originalMessage = await _channel?.getMessage(_messageId);
if (_originalMessage !== null && _originalMessage !== undefined) {
userId = _originalMessage.author.id;
userIds.push(userId);
}
}
}
// Verify that at least one user was found
if (userIds.length == 0) {
return;
}
// Check for thanks in string
if (
message.content.toLowerCase().includes('thanks') ||
message.content.toLowerCase().includes('thx') ||
message.content.toLowerCase().includes('thank you')
) {
// Make sure they are not thanking themselves
if (userIds.includes(message.author.id)) {
await message.reply('Thanking yourself will get you nowhere, buddy!');
// Remove them from the array
var myIndex = userIds.indexOf(message.author.id);
if (myIndex !== -1) {
userIds.splice(myIndex, 1);
}
}
// Now check again to see if there are any other users
if (userIds.length == 0) {
return;
}
// Get the guild
const guild = await discord.getGuild();
// Thanked by
var _thankedBy = message?.member?.nick ?? message.author.username;
// Turn on 30 minute timeout
const _timeout = false; // MANUALLY TURN THIS ON OR OFF
// Cyle through the users
for (let _uid = 0; _uid < userIds.length; _uid++) {
// Get the user
// var user = await discord.getUser(userIds[_uid]);
userId = userIds[_uid];
const _member = await guild?.getMember(userId);
const _nickname = _member?.nick;
const _user = await discord.getUser(userId);
var _username = _user?.username;
_username = _username?.toString();
var _displayName = 'Member';
if (_nickname) {
_displayName = _nickname;
} else if (_username) {
_displayName = _username;
}
// Store their current karma here
var _currentKarma = 0;
// Are we timing out?
if (_timeout) {
if (
((await karmaKv.get<any>(`timeOut.${userId}`)) ?? 0) + 1800000 <=
new Date().getTime()
) {
await karmaKv.put(`timeOut.${userId}`, new Date().getTime());
const karma = await karmaKv.get<number>(`karma.${userId}` ?? 0);
await karmaKv.cas(`karma.${userId}`, karma, (karma ?? 0) + 1);
_currentKarma = (await karmaKv.get<number>(`karma.${userId}`)) ?? 0;
await message.reply(
'🙏 ' +
_displayName +
"'s good deeds have been noticed by " +
_thankedBy +
', and karma has been awarded. They are now at ' +
_currentKarma +
' karma!'
);
} else {
await message.reply(
_displayName +
' was thanked within the last 30 minutes. Please wait to rethank them.'
);
}
} else {
await karmaKv.put(`timeOut.${userId}`, new Date().getTime());
const karma = await karmaKv.get<number>(`karma.${userId}` ?? 0);
await karmaKv.cas(`karma.${userId}`, karma, (karma ?? 0) + 1);
_currentKarma = (await karmaKv.get<number>(`karma.${userId}`)) ?? 0;
await message.reply(
'🙏 ' +
_displayName +
"'s good deeds have been noticed by " +
_thankedBy +
', and karma has been awarded. They are now at ' +
_currentKarma +
' karma!'
);
}
// Now check if they have enough karma to give them the Approved For Hire role
// Check if they have the role already
if (
_currentKarma >= 5 &&
_member?.roles.includes(FREELANCER_FOR_HIRE_ID) &&
!_member?.roles.includes(APPROVED_FOR_HIRE_ID)
) {
// Give them the role
await _member?.addRole(APPROVED_FOR_HIRE_ID);
// Reply
await message.reply(
'Hey ' +
_member.toMention() +
'! You have been given the <@&' +
APPROVED_FOR_HIRE_ID +
'> role. Thank you for being such an awesome helper! You may now post in <#' +
EXPERTS_FOR_HIRE_CHANNEL_ID +
'>'
);
}
// Check if they are a big helper
if (_currentKarma >= 20 && !_member?.roles.includes(BIG_HELPER_ROLE_ID)) {
// Give them the role
await _member?.addRole(BIG_HELPER_ROLE_ID);
// Reply
await message.reply(
'Hey ' +
_member?.toMention() +
'! You have been given the <@&' +
BIG_HELPER_ROLE_ID +
'> role for being super duper helpful. Thank you for being such an awesome contributor!'
);
}
}
}
});
/**
* Check karma
*/
commands.on(
{
name: 'karma',
description: 'Displays your karma',
},
(args) => ({
target: args.guildMemberOptional(),
}),
async (message, { target }) => {
target = target || message.member;
const karmabalance = await karmaKv.get<number>(`karma.${target.user.id}`);
var karmaValue;
if (karmabalance == undefined || karmabalance == 0) {
karmaValue = 'no';
} else {
karmaValue = karmabalance;
}
await message.reply({
content: `🙏 ${target.toMention()} has ${karmaValue} karma`,
allowedMentions: {
users: [message.author],
},
});
}
);
/**
* Give karma
*/
commands.on(
{
name: 'give',
description: 'Give karma to someone',
},
(args) => ({
member: args.guildMember(),
qty: args.string(),
keyword: args.textOptional(),
}),
async (message, { member, qty, keyword }) => {
// Get the current user
var _currentUser = message.member;
// Check if the current user has the admin role if trying to change someone else's nickname
if (!_currentUser.roles.includes(ADMIN_ROLE_ID)) {
return message.reply(
`Are you serious? You don't have the authority to give someone else karma.`
);
}
// Get their balance
var karmabalance = await karmaKv.get<number>(`karma.${member.user.id}`);
var karmaValue;
if (karmabalance == undefined || karmabalance == 0) {
karmaValue = 'no';
karmabalance = 0;
} else {
karmaValue = karmabalance;
}
// Give them the new amount
const newKarmaBalance = Number(karmabalance) + Number(qty);
await karmaKv.cas(`karma.${member.user.id}`, karmabalance, newKarmaBalance);
// Given by
var _givenBy = message.member.nick ?? message.author.username;
await message.reply({
content: `🙏 ${member.toMention()} has been given ${qty} karma by ${_givenBy} for being helpful. They are now at ${await karmaKv.get<number>(
`karma.${member.user.id}`
)} karma!`,
allowedMentions: {
users: [message.author],
},
});
// Now check if they have enough karma to give them the Approved For Hire role
// Check if they have the role already
if (
newKarmaBalance >= 10 &&
member?.roles.includes(FREELANCER_FOR_HIRE_ID) &&
!member?.roles.includes(APPROVED_FOR_HIRE_ID)
) {
// Give them the role
await member?.addRole(APPROVED_FOR_HIRE_ID);
// Reply
await message.reply(
'Hey ' +
member.toMention() +
'! You have been given the <@&' +
APPROVED_FOR_HIRE_ID +
'> role. Thank you for being such an awesome helper! You may now post in <#' +
EXPERTS_FOR_HIRE_CHANNEL_ID +
'>'
);
}
// Check if they are a big helper
if (newKarmaBalance >= 20 && !member?.roles.includes(BIG_HELPER_ROLE_ID)) {
// Give them the role
await member?.addRole(BIG_HELPER_ROLE_ID);
// Reply
await message.reply(
'Hey ' +
member?.toMention() +
'! You have been given the <@&' +
BIG_HELPER_ROLE_ID +
'> role for being super duper helpful. Thank you for being such an awesome contributor!'
);
}
// Delete the message
message.delete();
}
);
/**
* Change karma
*/
commands.on(
{
name: 'change',
description: 'Change karma for someone',
},
(args) => ({
member: args.guildMember(),
qty: args.string(),
keyword: args.text(),
}),
async (message, { member, qty, keyword }) => {
// Get the current user
var _currentUser = message.member;
// Check if the current user has the admin role if trying to change someone else's nickname
if (!_currentUser.roles.includes(ADMIN_ROLE_ID)) {
return message.reply(
`Are you kidding me? You don't have the authority to change someone else's karma.`
);
}
// Give them the new amount
await karmaKv.put(`karma.${member.user.id}`, Number(qty));
// Given by
var _givenBy = message.member.nick ?? message.author.username;
const newKarmaBalance = await karmaKv.get<number>(
`karma.${member.user.id}`
);
await message.reply({
content: `${member.toMention()}, your karma was changed to ${newKarmaBalance} by ${_givenBy}.`,
allowedMentions: {
users: [message.author],
},
});
// Now check if they have enough karma to give them the Approved For Hire role
// Check if they have the role already
if (
newKarmaBalance !== undefined &&
newKarmaBalance >= 10 &&
member?.roles.includes(FREELANCER_FOR_HIRE_ID) &&
!member?.roles.includes(APPROVED_FOR_HIRE_ID)
) {
// Give them the role
await member?.addRole(APPROVED_FOR_HIRE_ID);
// Reply
await message.reply(
'Hey ' +
member.toMention() +
'! You have been given the <@&' +
APPROVED_FOR_HIRE_ID +
'> role. Thank you for being such an awesome helper! You may now post in <#' +
EXPERTS_FOR_HIRE_CHANNEL_ID +
'>'
);
}
// Check if they are a big helper
if (
newKarmaBalance !== undefined &&
newKarmaBalance >= 20 &&
!member?.roles.includes(BIG_HELPER_ROLE_ID)
) {
// Give them the role
await member?.addRole(BIG_HELPER_ROLE_ID);
// Reply
await message.reply(
'Hey ' +
member?.toMention() +
'! You have been given the <@&' +
BIG_HELPER_ROLE_ID +
'> role for being super duper helpful. Thank you for being such an awesome contributor!'
);
}
// Delete the message
message.delete();
}
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment