-
Notifications
You must be signed in to change notification settings - Fork 0
Home
Chrxmee_Midnightt edited this page May 13, 2026
·
1 revision
Welcome to the official wiki for building bots on Chrxmee-MP4.
- A Chrxmee-MP4 account
- An approved bot from the Developer Portal
- Node.js 16 or higher (for local development)
- A GitHub account (for deployment)
npm install chrxmee-mp4-bot-makerconst 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();- Create — Register your bot on the Developer Portal
- Approval — Wait for review (no nuke/raid/spam bots)
- Develop — Write code locally using this package
- Deploy — Push to GitHub and deploy from the portal
- Run — Bot runs on Chrxmee-MP4 infrastructure
- Monitor — View logs and stats in Developer Portal
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)
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 */ });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
}bot.command('commandname', (ctx, args) => {
// args is an array of words after the command
ctx.reply('Response text');
});Users trigger with: !commandname arg1 arg2
bot.slashCommand('name', 'Description', [
{ name: 'option', description: 'What it does', required: false }
], (ctx, args) => {
ctx.reply('Response');
});Users trigger with: /name option:value
bot.command('search', async (ctx, args) => {
const results = await bot.searchVideo(args.join(' '));
ctx.reply(`Found ${results.length} videos.`);
});// Via invite code
bot.command('join', async (ctx, args) => {
const success = await bot.joinGuild(args[0]);
ctx.reply(success ? 'Joined!' : 'Invalid invite.');
});bot.command('leave', async (ctx) => {
await ctx.guild.leave();
});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}
`);
});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}`);
});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! 🎵');
});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.`);
});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! ⏭️');
});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.');
});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);
});bot.command('bal', (ctx) => {
const coins = ctx.guild.economy.getCoins(ctx.author.username);
ctx.reply(`Balance: ${coins} 💰`);
});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!`);
});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}`);
});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]}.`);
});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}.`);
});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.`);
});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}`);
});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!');
});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]}`);
});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}`);
});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!');
});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]}!`);
});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 */ }-
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
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}`);
});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);
});- Push your bot code to a GitHub repository
- Go to Developer Portal
- Click your approved bot
- Connect your GitHub repository
- Click Deploy
- Your bot is now live
- Go to Developer Portal
- Click your bot
- Click Stop
Logs are available in the Developer Portal under your bot's dashboard.
- Make sure your bot is approved
- Check you copied the full token
- Token starts with
chrx_bot_
- Go to Developer Portal
- Click Start on your bot
- Check the prefix matches
- Make sure commands are registered before
bot.login() - Check bot has
send_messagespermission in the guild
- The package uses in-memory storage locally
- Real data only works when deployed on Chrxmee-MP4
- Token verification requires deployment
// ✅ 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' });bot.command('mycommand', async (ctx) => {
try {
await doSomething();
} catch (err) {
ctx.reply('Something went wrong. Try again later.');
}
});bot.command('kick', (ctx, args) => {
if (!ctx.member.isMod) return ctx.reply('No permission.');
// proceed
});// ❌ 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!');
});- Platform: chrxmee-mp4-player.vercel.app
- Developer Portal: /developers
- Plugins: /plugins
- Report Bugs: GitHub Issues
- Contact: chrxmaticc@proton.me
Wiki last updated: Version 1.63.0