A modern, feature-rich Discord giveaway manager with TypeScript support, flexible storage adapters, and comprehensive event system. Built as an improved alternative to existing Discord giveaway packages.
# Stable version (latest)
npm install better-giveaways@latest
# Unstable version with beta features (dev)
npm install better-giveaways@dev
import { Client } from "discord.js";
import { GiveawayManager, JSONAdapter } from "better-giveaways";
const client = new Client({
intents: ["Guilds", "GuildMessages", "GuildMessageReactions"],
});
// Initialize with JSON storage
const adapter = new JSONAdapter("./giveaways.json");
const giveawayManager = new GiveawayManager(client, adapter, {
reaction: "🎉",
botsCanWin: false,
language: "en",
});
// Start a giveaway
await giveawayManager.start({
channelId: "123456789012345678",
prize: "Discord Nitro",
winnerCount: 1,
duration: 24 * 60 * 60 * 1000, // 24 hours
requirements: {
requiredRoles: ["roleIdHere"],
accountAgeMin: Date.now() - 7 * 24 * 60 * 60 * 1000, // 7 days old account
},
});
new GiveawayManager(client: Client, adapter: BaseAdapter, options: GiveawayManagerOptions)
start(options: GiveawayOptions): Promise<GiveawayData>
- Start a new giveawayend(giveawayId: string): Promise<void>
- End a giveaway manuallyreroll(giveawayId: string): Promise<void>
- Reroll giveaway winnersgetGiveaway(giveawayId: string): Promise<GiveawayData | null>
- Get giveaway datagetAllGiveaways(): Promise<GiveawayData[]>
- Get all giveawaysdeleteGiveaway(giveawayId: string): Promise<void>
- Delete a giveawayimport { JSONAdapter } from "better-giveaways";
const adapter = new JSONAdapter("./data/giveaways.json");
import { SequelizeAdapter } from "better-giveaways";
import { Sequelize } from "sequelize";
const sequelize = new Sequelize("database", "username", "password", {
host: "localhost",
dialect: "mysql",
});
const adapter = new SequelizeAdapter(sequelize);
import { BaseAdapter } from "better-giveaways";
class CustomAdapter extends BaseAdapter {
async save(data: GiveawayData[]): Promise<void> {
// Your custom save logic
}
async load(): Promise<GiveawayData[]> {
// Your custom load logic
}
}
const requirements = {
requiredRoles: ["Member", "Active"], // Role names or IDs
accountAgeMin: Date.now() - 30 * 24 * 60 * 60 * 1000, // 30 days
joinedServerBefore: Date.now() - 7 * 24 * 60 * 60 * 1000, // 7 days
custom: async (userId: string) => {
// Your custom logic here
const user = await client.users.fetch(userId);
const hasNitro = user.premiumType !== null;
return {
passed: hasNitro,
reason: hasNitro ? "User has Nitro" : "User must have Discord Nitro",
};
},
};
// Listen to giveaway events
giveawayManager.events.on("giveawayStarted", (giveaway) => {
console.log(`Giveaway started: ${giveaway.prize}`);
});
giveawayManager.events.on("giveawayEnded", (giveaway, winners) => {
console.log(
`Giveaway ended: ${giveaway.prize}, Winners: ${winners.join(", ")}`
);
});
giveawayManager.events.on("requirementsFailed", (giveaway, user, reason) => {
console.log(`User ${user.tag} failed requirements: ${reason}`);
});
Supported languages:
en
- English (default)cs
- Czechconst giveawayManager = new GiveawayManager(client, adapter, {
reaction: "🎉",
botsCanWin: false,
language: "cs", // Use Czech language
});
Contributions are welcome! Please feel free to submit a Pull Request.
git checkout -b feature/AmazingFeature
)git commit -m 'Add some AmazingFeature'
)git push origin feature/AmazingFeature
)This project is licensed under the GPL-3.0 License - see the LICENSE file for details.
If you have any questions or need help, please open an issue on GitHub.