Popii - v0.5.1
    Preparing search index...

    Events

    Events let you react to things that happen on Discord — members joining, messages being sent, reactions added, and so on. Each file in src/events/ handles one Discord event type.

    Name the file after the Discord.js event you want to handle:

    src/events/
    guildMemberAdd.tsfires when a member joins
    messageCreate.tsfires on every message
    guildCreate.tsfires when the bot joins a server
    interactionCreate.ts → (usually not neededPopii handles this)

    Popii detects which intents are needed based on the filenames in your events directory. You don't need to declare intents manually.

    // src/events/guildMemberAdd.ts
    import { event } from "popii";

    export default event(async (pop, member) => {
    const channel = member.guild.systemChannel;
    if (channel) {
    await channel.send(`Welcome, ${member}! 👋`);
    }
    });

    The first argument is always the Popii EventPop context (client, localization helpers, cache, etc.). Remaining arguments are the raw Discord.js event arguments — fully typed based on the event name.

    import { event } from "popii";

    export default event(async (pop, guild) => {
    pop.log.info(`Joined ${guild.name} (${guild.memberCount} members)`);
    pop.client.discord.guilds.cache.get(guild.id); // full discord.js access
    });

    Create multiple files that handle the same event by using subfolders or a naming suffix:

    src/events/
    messageCreate/
    spam-filter.ts
    xp-reward.ts
    automod.ts

    All files are loaded and run for the same event.

    // src/events/clientReady.ts
    import { event } from "popii";

    export default event(async (pop) => {
    pop.log.info(`Logged in as ${pop.client.discord.user?.tag}`);
    });

    The EventPop context gives you the same helpers available in commands:

    import { event } from "popii";

    export default event(async (pop, message) => {
    if (message.author.bot) return;

    // Caching
    const count = await pop.cache(`msg_count:${message.author.id}`, 60_000, async () => {
    return 0;
    });

    // i18n
    const greeting = pop.translate("welcome_message");

    // Cooler (shared KV store)
    await pop.cooler.set(`last_seen:${message.author.id}`, Date.now(), 86_400_000);
    });

    Popii reads your event filenames and automatically enables the required intents. For example:

    Event file Intent added
    guildMemberAdd.ts GuildMembers
    presenceUpdate.ts GuildPresences
    messageReactionAdd.ts GuildMessageReactions
    voiceStateUpdate.ts GuildVoiceStates

    You can override this by setting intents manually in popiiClient().