
Security News
/Research
Wallet-Draining npm Package Impersonates Nodemailer to Hijack Crypto Transactions
Malicious npm package impersonates Nodemailer and drains wallets by hijacking crypto transactions across multiple blockchains.
A unique JavaScript library for Discord bots with modern features and extensibility.
hat653 provides a typed event system for Discord and custom events.
import { EventEmitter } from 'hat653';
const events = new EventEmitter();
// Listen for a user update
events.on('userUpdate', (oldUser, newUser) => {
console.log(`User updated: ${oldUser.username} → ${newUser.username}`);
});
// Emit a user update event
events.emit('userUpdate', oldUser, newUser);
// Listen for a message create event
events.on('messageCreate', (msg) => {
console.log('New message:', msg.content);
});
// Listen for a custom event
events.on('customEvent', (data) => {
console.log('Custom event:', data);
});
// One-time listener
events.once('messageDelete', (msg) => {
console.log('Message deleted:', msg.id);
});
// Remove a listener
const handler = (msg) => console.log(msg.content);
events.on('messageCreate', handler);
events.off('messageCreate', handler);
.on(event, listener)
— Register a listener for a typed or custom event.emit(event, ...args)
— Emit a typed or custom event.off(event, listener)
— Remove a listener.once(event, listener)
— Register a one-time listenerA modern, extensible JavaScript/TypeScript library for building Discord bots with unique features.
import { mention } from 'hat653/dist/utils';
mention('user', '123456789012345678'); // <@123456789012345678>
mention('role', '987654321098765432'); // <@&987654321098765432>
mention('channel', '112233445566778899'); // <#112233445566778899>
import { discordTimestamp } from 'hat653/dist/utils';
discordTimestamp(new Date(), 'R'); // <t:1693449600:R>
discordTimestamp(Date.now(), 'f'); // <t:1693449600:f>
import { bold, italic, underline, strikethrough, code, codeblock } from 'hat653/dist/utils';
bold('Important'); // **Important**
italic('Emphasis'); // *Emphasis*
underline('Underline'); // __Underline__
strikethrough('Removed'); // ~~Removed~~
code('inline'); // `inline`
codeblock('console.log("Hello")', 'js'); // ```js\nconsole.log("Hello")\n```
import { paginate } from 'hat653/dist/utils';
const items = Array.from({ length: 25 }, (_, i) => `Item ${i+1}`);
const { page, totalPages, pageNumber } = paginate(items, 2, 10);
// page = ['Item 11', ..., 'Item 20']
// totalPages = 3
// pageNumber = 2
npm install hat653
Import the library in your project:
import { Mat653653Bot, DiscordApiHelper, CommandManager, Logger } from 'hat653';
See the examples/
directory for sample Discord bot code using this library.
const bot = new Mat653653Bot(token, {
locale: 'es',
loggingLevel: 'info',
features: { moderation: true }
});
bot.setOnMessage(msg => Logger.info('Received message:', msg));
bot.setOnCommand((cmd, args) => Logger.info(`Command: ${cmd}`, args));
bot.setOnError(err => Logger.error('Bot error:', err));
commands.setPermissions('ban', ['admin', 'mod'], ['123456789']);
if (commands.canExecute('ban', { id: '123456789', roles: ['admin'] })) {
commands.execute('ban', 'targetUserId');
}
builder.addValidator(data => {
if (!data.content) return 'Content is required.';
return null;
});
builder.validate();
pluginManager.saveConfig('logger', { level: 'debug' });
const config = pluginManager.loadConfig('logger');
// Recurring tasks persist in advTasks.json
scheduleRecurringTask('cleanup', 3600000, () => Logger.info('Cleanup'), 2, 'maintenance');
import { localize } from 'hat653';
bot.sendMessage(channelId, localize('welcome', bot.config.locale));
Logger.logLevel = 'info';
Logger.logToFile = true;
Logger.logFile = 'bot.log';
Logger.format = (level, ...args) => `${new Date().toISOString()} [${level}] ${args.join(' ')}`;
Logger.info('Bot started');
import { MessageBuilder } from 'hat653';
const builder = new MessageBuilder();
### Moderation Utilities (Basic)
if (!builder.validate()) {
console.log('Errors:', builder.getErrors());
builder.autoFix(); // Attempts to fix errors automatically
}
import { warnUser } from 'hat653';
try {
await warnUser(token, guildId, userId, 'Reason');
} catch (err) {
if (err.code === 'MISSING_PERMISSIONS') {
console.error(err.message);
// Suggestion: err.fix
}
}
import { PluginManager } from 'hat653';
const manager = new PluginManager();
try {
manager.register({ name: 'logger', init: () => {} });
manager.register({ name: 'logger', init: () => {} }); // Will throw PLUGIN_EXISTS
} catch (err) {
if (err.code === 'PLUGIN_EXISTS') {
console.error(err.message);
// Suggestion: err.fix
}
}
MessageBuilder
lets you build Discord messages and embeds with a chainable API, validation, and auto-fix.
Features:
Example:
import { MessageBuilder } from 'hat653';
const builder = new MessageBuilder()
.setContent('Hello!')
.addEmbed({ title: 'Embed 1', description: 'First embed', color: 0x00ff00 })
.addEmbed({ title: 'Embed 2', description: 'Second embed', color: 0xff0000 })
.setImage('https://example.com/image.png')
.setThumbnail('https://example.com/thumb.png')
.setUrl('https://example.com')
.setAuthor('Bot', 'https://example.com/icon.png')
.setFooter('Footer text', 'https://example.com/icon.png')
.setTimestamp()
.addField('Field 1', 'Value 1')
.addField('Field 2', 'Value 2', true)
.setButtons([
{
type: 1,
components: [
{ type: 2, label: 'Click Me', style: 1, custom_id: 'btn1' }
]
}
])
.validate();
if (!builder.validate()) {
console.log('Errors:', builder.getErrors());
builder.autoFix();
}
console.log(builder.preview());
// Send with Discord.js: channel.send(builder.build());
API Reference:
.setContent(content: string)
.addEmbed(embed: object)
.setEmbed(embed: object)
.setImage(url: string)
.setThumbnail(url: string)
.setUrl(url: string)
.setAuthor(name: string, iconUrl?: string, url?: string)
.setFooter(text: string, iconUrl?: string)
.setTimestamp(date?: Date)
.addField(name: string, value: string, inline?: boolean)
.setButtons(components: any[])
.setSelects(selects: any[])
.setModal(modal: any)
.setComponents(components: any[])
.addValidator(fn: (data) => string | null)
.validate()
.getErrors()
.autoFix()
.preview()
.build()
import { warnUser, unbanUser, fetchAuditLogs, tempBanUser, tempMuteUser, addRole, removeRole } from 'hat653';
await warnUser(token, guildId, userId, 'Warning reason');
await unbanUser(token, guildId, userId);
const logs = await fetchAuditLogs(token, guildId, 22); // 22 = ban action type
await tempBanUser(token, guildId, userId, 60000, 'Temp ban for 1 min');
await tempMuteUser(token, guildId, userId, 60000); // mute for 1 min
await addRole(token, guildId, userId, roleId);
await removeRole(token, guildId, userId, roleId);
import { registerPlugin, removePlugin, getPlugins, triggerPluginEvent } from 'hat653';
registerPlugin({
name: 'logger',
config: { level: 'info' },
dependencies: ['database'],
filterEvents: (event) => event === 'message',
onInit: () => console.log('Plugin initializing'),
setup: () => console.log('Logger plugin loaded'),
onReady: () => console.log('Plugin ready'),
teardown: () => console.log('Logger plugin removed'),
onShutdown: () => console.log('Plugin shutting down'),
onEvent: (event, ...args) => {
if (event === 'message') console.log('Message event:', ...args);
}
});
triggerPluginEvent('message', { content: 'Hello!' });
removePlugin('logger');
import { scheduleRecurringTask, cancelRecurringTask, listAdvancedTasks } from 'hat653';
scheduleRecurringTask('heartbeat', 10000, () => {
console.log('Heartbeat every 10 seconds');
}, 1, 'system');
console.log(listAdvancedTasks());
cancelRecurringTask('heartbeat');
import { MessageBuilder } from 'hat653';
const builder = new MessageBuilder()
.setContent('Hello!')
.setEmbed({ title: 'Embed Title', description: 'Embed body', color: 0x00ff00 })
.addField('Field 1', 'Value 1')
.setAuthor('Bot', 'https://example.com/icon.png')
.setFooter('Footer text')
.setTimestamp();
const messageData = builder.build();
// Use messageData with DiscordRestApi, Mat653653Bot, or discord.js
import { kickUser, banUser, muteUser, purgeMessages } from 'hat653';
await kickUser(token, guildId, userId, 'Spamming');
await banUser(token, guildId, userId, 'Bad behavior');
await muteUser(token, guildId, userId, 10 * 60 * 1000); // mute for 10 minutes
await purgeMessages(token, channelId, ['msgId1', 'msgId2']);
import { registerPlugin, removePlugin, getPlugins, triggerPluginEvent } from 'hat653';
registerPlugin({
name: 'logger',
setup: () => console.log('Logger plugin loaded'),
teardown: () => console.log('Logger plugin removed'),
onEvent: (event, ...args) => {
if (event === 'message') console.log('Message event:', ...args);
}
});
triggerPluginEvent('message', { content: 'Hello!' });
removePlugin('logger');
import { scheduleTask, cancelTask, listScheduledTasks } from 'hat653';
scheduleTask('reminder', 60000, () => {
console.log('This runs after 1 minute');
});
console.log(listScheduledTasks());
cancelTask('reminder');
Slash command registration should be handled directly with discord.js in your bot code. This library does not provide a deploy utility for slash commands.
keepBotAlive
can accept either a callback function or a Discord.js client:
import { keepBotAlive } from 'hat653';
import { Client } from 'discord.js';
const client = new Client({ intents: [/* ... */] });
// Option 1: Pass a callback function
keepBotAlive(() => {
// Custom heartbeat logic
console.log('Bot is alive!');
});
// Option 2: Pass a Discord.js client directly
keepBotAlive(client);
const bot = new Mat653653Bot('YOUR_BOT_TOKEN');
const user = await bot.getUser('USER_ID');
const guild = await bot.getGuild('GUILD_ID');
const channel = await bot.getChannel('CHANNEL_ID');
const messages = await bot.getMessages('CHANNEL_ID', 10);
const member = await bot.getMember('GUILD_ID', 'USER_ID');
const roles = await bot.getRoles('GUILD_ID');
const emojis = await bot.getEmojis('GUILD_ID');
const invites = await bot.getInvites('GUILD_ID');
const reactions = await bot.getReactions('CHANNEL_ID', 'MESSAGE_ID', '👍');
// Send a plain message
await bot.sendMessage('CHANNEL_ID', 'Hello world!');
// Send an embed
await bot.sendEmbed('CHANNEL_ID', {
title: 'Embed Title',
description: 'Embed description',
color: 0x00ff00
});
// Send a message with buttons
await bot.sendButton('CHANNEL_ID', 'Click a button:', [
{
type: 1,
components: [
{
type: 2,
label: 'Button 1',
style: 1,
custom_id: 'btn1'
}
]
}
]);
DiscordApiHelper.getUserTag({ username: 'user', discriminator: '1234' });
DiscordApiHelper.isValidId('123456789012345678');
await DiscordApiHelper.fetchEmojis(token, guildId);
await DiscordApiHelper.fetchInvites(token, guildId);
await DiscordApiHelper.fetchReactions(token, channelId, messageId, '👍');
import { sendMessageToChannel } from 'hat653';
// Usage with discord.js Client instance:
await sendMessageToChannel(client, 'CHANNEL_ID', 'Hello from discord.js!');
const manager = new CommandManager();
manager.register({ name: 'ping', execute: () => Logger.info('Pong!') });
manager.execute('ping');
MIT
FAQs
A unique JavaScript library for Discord bots with modern features and extensibility.
The npm package hat653 receives a total of 291 weekly downloads. As such, hat653 popularity was classified as not popular.
We found that hat653 demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
/Research
Malicious npm package impersonates Nodemailer and drains wallets by hijacking crypto transactions across multiple blockchains.
Security News
This episode explores the hard problem of reachability analysis, from static analysis limits to handling dynamic languages and massive dependency trees.
Security News
/Research
Malicious Nx npm versions stole secrets and wallet info using AI CLI tools; Socket’s AI scanner detected the supply chain attack and flagged the malware.