Examples

Code Recipes

Copy-paste examples covering the most common use cases. Each example is self-contained and ready to run.

Post Bot Stats

Update your bot's server count on DiscordForge.

statsbasics
1import { ForgeClient } from "discordforge-sdk";
2 
3const forge = new ForgeClient(
4 process.env.FORGE_API_KEY,
5 process.env.FORGE_BOT_ID
6);
7 
8// Post stats on bot startup
9await forge.postStats({
10 serverCount: client.guilds.cache.size,
11 shardCount: client.shard?.count ?? 1,
12 userCount: client.users.cache.size,
13});
14 
15console.log("Stats posted to DiscordForge!");

Check If User Voted

Verify if a user voted in the last 8 hours for vote-gated features.

votesbasics
1const vote = await forge.checkVote("123456789012345678");
2 
3if (vote.hasVoted) {
4 console.log(`User voted at ${vote.votedAt}`);
5 console.log(`Next vote at ${vote.nextVoteAt}`);
6 // Grant premium features
7} else {
8 console.log("User hasn't voted yet");
9 console.log("Vote: https://discordforge.org/bots/YOUR_BOT");
10}

Get Bot Info

Fetch public info about any listed bot – no auth required.

botsbasics
1// No API key needed for this endpoint
2const bot = await forge.getBot();
3 
4console.log(bot.name);
5console.log(`Votes: ${bot.voteCount}`);
6console.log(`Servers: ${bot.serverCount}`);

Sync Commands on Startup

Automatically sync your slash commands to DiscordForge when your bot starts.

commandsadvanced
1import { ForgeClient } from "discordforge-sdk";
2 
3const forge = new ForgeClient(
4 process.env.FORGE_API_KEY,
5 process.env.FORGE_BOT_ID
6);
7 
8await forge.syncCommands([
9 {
10 name: "help",
11 description: "Show all available commands",
12 category: "General",
13 },
14 {
15 name: "ban",
16 description: "Ban a member from the server",
17 usage: "/ban @user [reason]",
18 category: "Moderation",
19 },
20 {
21 name: "play",
22 description: "Play a song in voice channel",
23 usage: "/play <url|search>",
24 category: "Music",
25 },
26]);
27 
28console.log("Commands synced to DiscordForge!");

Vote Webhook Handler

Receive and process vote notifications with Express.

webhooksadvanced
1import express from "express";
2 
3const app = express();
4app.use(express.json());
5 
6app.post("/webhook/vote", (req, res) => {
7 if (req.headers.authorization !== process.env.FORGE_WEBHOOK_SECRET) {
8 return res.status(401).json({ error: "Unauthorized" });
9 }
10 
11 const { id, username, weeklyVotes, totalVotes, isTest } = req.body;
12 
13 if (isTest) {
14 console.log("Test webhook received!");
15 return res.status(200).json({ ok: true });
16 }
17 
18 console.log(`${username} (${id}) voted!`);
19 console.log(`Weekly: ${weeklyVotes} | Total: ${totalVotes}`);
20 
21 // Grant rewards to the voter
22 // await grantPremium(id, 24 * 60 * 60 * 1000);
23 
24 res.status(200).json({ ok: true });
25});
26 
27app.listen(3000);

Error Recovery Pattern

Handle API errors with the ForgeAPIError class.

errorsadvanced
1import { ForgeClient, ForgeAPIError } from "discordforge-sdk";
2 
3async function safePostStats(serverCount: number) {
4 try {
5 await forge.postStats({ serverCount });
6 console.log("Stats posted!");
7 } catch (error) {
8 if (error instanceof ForgeAPIError) {
9 console.error(`API error ${error.status}: ${error.message}`);
10 
11 if (error.status === 401) {
12 console.error("API key invalid – check your credentials");
13 process.exit(1);
14 }
15 if (error.retryAfter) {
16 console.log(`Rate limited. Retrying in ${error.retryAfter}s`);
17 await new Promise(r => setTimeout(r, error.retryAfter * 1000));
18 return forge.postStats({ serverCount });
19 }
20 }
21 throw error;
22 }
23}