Discord.js Currency / Reward System

This guide will show you how to create a basic currency/rewards system for your Discord bot using Discord.js and some relatively basic Node.js.

A currency/rewards system is a great way to keep your users engaged and active on your Discord server. It can be used to reward users for being active, participating in events, or just for fun. In this guide, I'll show you how to create a simple currency/rewards system for your Discord bot using Discord.js and some basic Node.js.

For example, let's create a simple currency/reward system that gives points to users who are currently in a voice channel.

See which users are currently active:

const { Events } = require("discord.js");
const UserUtil = require("../utils/user.util.js");


class VoiceStateUpdateListener {
    /**
     * **Initialize the `Events.VoiceStateUpdate` listener.**  
     * @returns {void} Void.  
     */
    static init() {
        client.on(Events.VoiceStateUpdate, (oldState, newState) => {
            try {
                if (newState.member.user.bot) { return; }
                if (!oldState.channel && newState.channel) {
                    UserUtil.addUser(newState.id, newState.member);
                } else if (!newState.channel) {
                    UserUtil.removeUser(oldState.id);
                }
            } catch (err) {
                console.error(err);
            }
        });
    }
}

module.exports = VoiceStateUpdateListener;

In this example, we have created a listener called VoiceStateUpdateListener. This listener listens for the VoiceStateUpdate event, which is triggered whenever a user's voice state changes (e.g., they join or leave a voice channel). When a user joins a voice channel, we call the addUser function from our UserUtil utility to add the user to our list of active users. When a user leaves a voice channel, we call the removeUser function to remove the user from our list of active users.

Now that we have our listener set up, we need to add the points to the users who are currently in a voice channel. We can do this in an asychronous interval that runs every X seconds.

Add points to active users:

const { setInterval } = require("node:timers/promises");


let proccessing = false;

for await (const _ of setInterval(60_000)) {
    if (proccessing) {
        console.warn("updateUserPoints() did not completed");
        continue;
    }

    proccessing = true;

    updateUserPoints()
        .then(() => {
            proccessing = false;
        })
        .catch((err) => {
            console.error(err);
            proccessing = false;
        });
}

In this example, we use the setInterval function to run the updateUserPoints function every 60 seconds. We use a boolean variable called proccessing to prevent the function from running multiple times concurrently. If the function is already running, we log a warning message and skip the current iteration.

The updateUserPoints function is responsible for adding points to the users who are currently in a voice channel. This function can be as simple or as complex as you want, depending on your requirements. If it is a simple synchronous function, you can call it directly from the interval. If it is an asynchronous function, you can use the for await loop to wait for the function to complete before running the next iteration.

You can now create your own currency/rewards system for your Discord bot using Discord.js and Node.js. You can customize the system and add commands to buy items, check your balance, and more.