Skip to content
Chrxmee_Midnightt edited this page May 13, 2026 · 1 revision

Chrxmee-MP4 Bot Maker Wiki

Welcome to the official wiki for building bots on Chrxmee-MP4.


Getting Started

Prerequisites

  • A Chrxmee-MP4 account
  • An approved bot from the Developer Portal
  • Node.js 16 or higher (for local development)
  • A GitHub account (for deployment)

Installation

npm install chrxmee-mp4-bot-maker

Your First Bot

const ChrxmeeBot = require('chrxmee-mp4-bot-maker');
const bot = new ChrxmeeBot({ token: 'chrx_bot_xxxx', prefix: '!' });

bot.on('ready', () => console.log('Bot is online!'));
bot.command('ping', (ctx) => ctx.reply('Pong!'));
bot.login();

Core Concepts

The Bot Lifecycle

  1. Create — Register your bot on the Developer Portal
  2. Approval — Wait for review (no nuke/raid/spam bots)
  3. Develop — Write code locally using this package
  4. Deploy — Push to GitHub and deploy from the portal
  5. Run — Bot runs on Chrxmee-MP4 infrastructure
  6. Monitor — View logs and stats in Developer Portal

Filesystem Architecture

Everything in the bot follows a tree structure:

bot
├── guilds (GuildManager)
│   └── Guild
│       ├── channels (ChannelManager)
│       │   ├── TextChannel
│       │   ├── VoiceChannel
│       │   ├── StageChannel
│       │   ├── RadioChannel
│       │   └── TVChannel
│       ├── members (GuildMemberManager)
│       ├── roles (RoleManager)
│       ├── invites (InviteManager)
│       ├── economy (EconomyManager)
│       ├── watchParties (WatchPartyManager)
│       ├── tvSchedule (TVScheduleManager)
│       ├── achievements (AchievementManager)
│       └── events (EventManager)
├── users (UserManager)
├── videos (VideoManager)
├── plugins (PluginManager)
├── notifications (NotificationManager)
└── profiles (ProfileManager)

Events System

The bot uses an EventEmitter pattern. Listen for events with bot.on():

bot.on('messageCreate', (msg) => { /* new message */ });
bot.on('guildJoin', (guild) => { /* joined a guild */ });
bot.on('voiceJoin', (channel, user) => { /* user joined VC */ });

Context Object

Every command receives a context object:

{
    guild,      // The guild where command was run
    channel,    // The channel
    member,     // The GuildMember who ran it
    author,     // The User who ran it
    content,    // Raw message text
    voice,      // VoiceChannel if applicable
    reply(),    // Reply to the message
    send(),     // Send to channel
    dm(),       // DM the user
    react()     // React to the message
}

Command Guide

Prefix Commands

bot.command('commandname', (ctx, args) => {
    // args is an array of words after the command
    ctx.reply('Response text');
});

Users trigger with: !commandname arg1 arg2

Slash Commands

bot.slashCommand('name', 'Description', [
    { name: 'option', description: 'What it does', required: false }
], (ctx, args) => {
    ctx.reply('Response');
});

Users trigger with: /name option:value

Async Commands

bot.command('search', async (ctx, args) => {
    const results = await bot.searchVideo(args.join(' '));
    ctx.reply(`Found ${results.length} videos.`);
});

Guild Management

Joining Guilds

// Via invite code
bot.command('join', async (ctx, args) => {
    const success = await bot.joinGuild(args[0]);
    ctx.reply(success ? 'Joined!' : 'Invalid invite.');
});

Leaving Guilds

bot.command('leave', async (ctx) => {
    await ctx.guild.leave();
});

Guild Info

bot.command('serverinfo', (ctx) => {
    const g = ctx.guild;
    ctx.reply(`
        **${g.name}**
        Owner: ${g.owner.displayName}
        Members: ${g.memberCount}
        Level: ${g.level}
        Boost: ${g.boostLevel || 'None'}
        Messages: ${g.totalMessages}
    `);
});

Creating Channels

bot.command('createchannel', async (ctx, args) => {
    const name = args[0];
    const type = args[1] || 'text';
    const channel = await ctx.guild.channels.create(name, { type });
    ctx.reply(`Created #${channel.name}`);
});

Voice Channels

Joining and Playing

bot.command('play', async (ctx, args) => {
    const vc = ctx.guild.channels.find(c => c.type === 'voice');
    if (!vc) return ctx.reply('No voice channel.');
    
    await vc.join();
    await vc.play({ 
        title: args.join(' '), 
        src: 'https://example.com/video.mp4' 
    });
    ctx.reply('Now playing! 🎵');
});

DJ System

bot.command('dj', async (ctx, args) => {
    const vc = ctx.voice;
    if (!vc) return ctx.reply('Not in VC.');
    if (!ctx.member.isMod) return ctx.reply('Mods only.');
    await vc.setDJ(args[0]);
    ctx.reply(`${args[0]} is now DJ.`);
});

Queue Management

bot.command('queue', (ctx) => {
    const vc = ctx.voice;
    if (!vc) return ctx.reply('Not in VC.');
    
    const queue = vc.queue.upcoming;
    if (queue.length === 0) return ctx.reply('Queue is empty.');
    
    const list = queue.map((v, i) => `${i + 1}. ${v.title}`).join('\n');
    ctx.reply(`**Queue:**\n${list}`);
});

bot.command('skip', async (ctx) => {
    const vc = ctx.voice;
    if (!vc?.currentDJ || vc.currentDJ.id !== ctx.author.id) {
        return ctx.reply('Only the DJ can skip.');
    }
    await vc.skip();
    ctx.reply('Skipped! ⏭️');
});

Stage Channels

bot.command('speak', async (ctx) => {
    const stage = ctx.channel;
    if (!stage.isStage) return ctx.reply('Not a stage channel.');
    await stage.requestToSpeak();
    ctx.reply('Requested to speak.');
});

Economy System

Getting Coins

bot.command('daily', async (ctx) => {
    const coins = await ctx.guild.economy.rewardDaily(ctx.author.username);
    ctx.reply(`Claimed 25 coins! Balance: ${coins} 💰`);
});

bot.on('messageCreate', async (msg) => {
    if (!msg.author?.username) return;
    // Auto-reward 1 coin per message
    await msg.guild?.economy.rewardMessage(msg.author.username);
});

Checking Balance

bot.command('bal', (ctx) => {
    const coins = ctx.guild.economy.getCoins(ctx.author.username);
    ctx.reply(`Balance: ${coins} 💰`);
});

Guild Bank

bot.command('bank', (ctx) => {
    const coins = ctx.guild.economy.getBank();
    ctx.reply(`Guild Bank: ${coins} 💰`);
});

bot.command('donate', async (ctx, args) => {
    const amount = parseInt(args[0]);
    const success = await ctx.guild.economy.spendCoins(ctx.author.username, amount);
    if (!success) return ctx.reply('Not enough coins.');
    await ctx.guild.economy.addToBank(amount);
    ctx.reply(`Donated ${amount} coins to guild bank!`);
});

Leaderboard

bot.command('top', (ctx) => {
    const lb = ctx.guild.economy.getLeaderboard();
    const text = lb.map((e, i) => 
        `${i + 1}. @${e[0]}${e[1].coins} 💰`
    ).join('\n');
    ctx.reply(`**Richest Members**\n${text}`);
});

Moderation

Kick and Ban

bot.command('kick', async (ctx, args) => {
    if (!ctx.member.isMod) return ctx.reply('No permission.');
    await ctx.guild.members.kick(args[0]);
    ctx.reply(`Kicked ${args[0]}.`);
});

bot.command('ban', async (ctx, args) => {
    if (!ctx.member.isAdmin) return ctx.reply('No permission.');
    await ctx.guild.members.ban(args[0]);
    ctx.reply(`Banned ${args[0]}.`);
});

Role Management

bot.command('role', async (ctx, args) => {
    if (!ctx.member.isAdmin) return ctx.reply('No permission.');
    const username = args[0];
    const role = args[1];
    await ctx.guild.members.setRole(username, role);
    ctx.reply(`${username} is now ${role}.`);
});

Message Management

bot.command('clear', async (ctx, args) => {
    if (!ctx.member.isMod) return ctx.reply('No permission.');
    const count = parseInt(args[0]) || 10;
    const deleted = await ctx.channel.bulkDelete(count);
    ctx.reply(`Deleted ${deleted} messages.`);
});

Video Library

Searching

bot.command('video', async (ctx, args) => {
    const results = await bot.searchVideo(args.join(' '));
    if (results.length === 0) return ctx.reply('No videos found.');
    const v = results[0];
    ctx.reply(`**${v.title}**\n${v.url}\nViews: ${v.formattedViews}`);
});

Comments

bot.command('comment', async (ctx, args) => {
    const videoId = args[0];
    const text = args.slice(1).join(' ');
    const comment = await bot.comments.create(videoId, text);
    ctx.reply('Comment posted!');
});

Watch Parties

bot.command('watchparty', async (ctx, args) => {
    if (!ctx.member.hasPermission('start_watch_party')) {
        return ctx.reply('No permission.');
    }
    const wp = await ctx.guild.watchParties.start(args[0], 'Watch Party');
    ctx.reply(`Watch party started! Join at ${args[0]}`);
});

TV Schedule

bot.command('schedule', async (ctx, args) => {
    if (!ctx.member.hasPermission('manage_tv_schedule')) {
        return ctx.reply('No permission.');
    }
    const time = args[0]; // HH:MM format
    const title = args.slice(1).join(' ');
    await ctx.guild.tvSchedule.add(time, title, '');
    ctx.reply(`Scheduled "${title}" at ${time}`);
});

Notifications

bot.command('notify', async (ctx, args) => {
    const target = args[0];
    const text = args.slice(1).join(' ');
    await bot.notifications.send(target, {
        title: 'Notification',
        body: text,
        type: 'info'
    });
    ctx.reply('Notification sent!');
});

Plugins

bot.command('plugins', async (ctx) => {
    await bot.plugins.fetchAll();
    const list = bot.plugins.installed.map(p => p.name).join(', ');
    ctx.reply(`Installed plugins: ${list || 'None'}`);
});

bot.command('install', async (ctx, args) => {
    await bot.plugins.fetchAll();
    await bot.plugins.install(args[0]);
    ctx.reply(`Installed ${args[0]}!`);
});

Permissions System

Checking Permissions

if (ctx.member.hasPermission('manage_messages')) { /* can manage */ }
if (ctx.member.isOwner) { /* guild owner */ }
if (ctx.member.isAdmin) { /* admin or owner */ }
if (ctx.member.isMod) { /* mod or higher */ }

Available Permissions

  • admin — Full access
  • manage_guild — Edit guild settings
  • manage_channels — Create/delete channels
  • manage_members — Kick/ban members
  • manage_roles — Create/edit roles
  • manage_messages — Delete/pin messages
  • mention_everyone — @everyone
  • create_invite — Create invites
  • voice_connect — Join voice channels
  • dj — DJ controls in VC
  • send_messages — Send messages
  • attach_media — Attach files
  • read_messages — Read channels
  • timeout_members — Timeout users
  • start_watch_party — Start watch parties
  • manage_tv_schedule — TV scheduling
  • manage_events — Create events

Rate Limits

Bots have built-in rate limits to prevent spam:

Action Limit Reset
Messages 30/min Every 60s
DMs 10/min Every 60s
Guild Joins 5/min Every 60s
bot.on('rateLimited', (type) => {
    console.log(`Rate limited on ${type}`);
});

Error Handling

bot.command('risky', async (ctx) => {
    try {
        await someRiskyOperation();
    } catch (err) {
        if (err.name === 'PermissionError') {
            ctx.reply('Missing permission: ' + err.permission);
        } else if (err.name === 'RateLimitError') {
            ctx.reply('Slow down! Retry after ' + err.retryAfter + 'ms');
        } else if (err.name === 'VoiceError') {
            ctx.reply('Voice error: ' + err.message);
        } else {
            ctx.reply('Something went wrong.');
        }
    }
});

bot.on('commandError', (name, error, ctx) => {
    console.error(`Error in command ${name}:`, error);
});

Deployment

Deploying Your Bot

  1. Push your bot code to a GitHub repository
  2. Go to Developer Portal
  3. Click your approved bot
  4. Connect your GitHub repository
  5. Click Deploy
  6. Your bot is now live

Stopping Your Bot

  1. Go to Developer Portal
  2. Click your bot
  3. Click Stop

Viewing Logs

Logs are available in the Developer Portal under your bot's dashboard.


Troubleshooting

"Invalid token" on login

  • Make sure your bot is approved
  • Check you copied the full token
  • Token starts with chrx_bot_

"Bot is not live"

  • Go to Developer Portal
  • Click Start on your bot

Bot not responding to commands

  • Check the prefix matches
  • Make sure commands are registered before bot.login()
  • Check bot has send_messages permission in the guild

localStorage errors in Node.js

  • The package uses in-memory storage locally
  • Real data only works when deployed on Chrxmee-MP4
  • Token verification requires deployment

Best Practices

Keep Tokens Secret

// ✅ Use environment variables
const token = process.env.BOT_TOKEN;
const bot = new ChrxmeeBot({ token });

// ❌ Never hardcode in public repos
const bot = new ChrxmeeBot({ token: 'chrx_bot_actualtoken' });

Handle Errors Gracefully

bot.command('mycommand', async (ctx) => {
    try {
        await doSomething();
    } catch (err) {
        ctx.reply('Something went wrong. Try again later.');
    }
});

Check Permissions

bot.command('kick', (ctx, args) => {
    if (!ctx.member.isMod) return ctx.reply('No permission.');
    // proceed
});

Avoid Infinite Loops

// ❌ Don't reply to every message including your own
bot.on('messageCreate', (msg) => {
    msg.reply('Hello!'); // This would create an infinite loop
});

// ✅ Check it's not your own message
bot.on('messageCreate', (msg) => {
    if (msg.botMessage) return;
    if (msg.content === 'hello') msg.reply('Hello!');
});

Community


Wiki last updated: Version 1.63.0