A modern, NodeJS and browser-friendly ES6 WebSocket library for interacting with hack.chat servers. This engine provides an object-oriented interface, automatic keep-alives, and structured event handling.
- Node.js 14+ (This package uses ES Modules)
- NPM 6+
npm install hackchat-engine This library uses ES Modules. You must use import syntax.
import{Client}from'hackchat-engine';constbotName='MyBot';constbotPass='secretPassword';constchannel='programming';// Initialize the clientconstclient=newClient({debug: true});// Triggered when the WebSocket connects to the gatewayclient.on('connected',()=>{console.log('Connected to server!');client.ws.send({cmd: 'getchannels'});client.join(botName,botPass,channel);});// Triggered when the server assigns a session IDclient.on('session',(session)=>{console.log(`Session ID: ${session.sessionID}`);});// Triggered when the client successfully joins the channelclient.on('channelJoined',(data)=>{console.log(`Joined channel: ${data.channel}`);client.say(channel,'Hello world! I am a bot.');});// Triggered on every new messageclient.on('message',(message)=>{// Ignore our own messagesif(message.user.isMine)return;console.log(`[${message.channel}] ${message.user.name}: ${message.content}`);if(message.content==='!ping'){// Helper method to reply directly to the channelmessage.reply('Pong!');}});You can pass an options object to the Client constructor to customize the connection.
constclient=newClient({// Connection detailsws: {gateway: 'wss://hack.chat/chat-ws',// Default// gateway: 'ws://127.0.0.1:6060/' // For local development},// Set to true to see internal logs and raw packetsdebug: false,// If true, identifies as a bot to the server (default: true)isBot: true,});The client extends EventEmitter. You can listen for the following events:
| Event | Payload | Description |
|---|---|---|
connected | Client | Socket connection established. |
session | SessionStruct | Server has assigned a session ID. |
channelJoined | Object | Client has successfully joined a channel and received the user list. |
message | MessageStruct | A new message was received. |
userJoined | UserStruct | A user joined the channel. |
userLeft | UserStruct | A user left the channel. |
userUpdate | UserStruct | A user changed their flair, color, or status. |
whisper | WhisperStruct | Received a private whisper. |
invite | InviteStruct | Received an invitation to another channel. |
emote | EmoteStruct | A user sent a /me emote. |
warning | WarningStruct | Server sent a warning (e.g., rate limit). |
gotCaptcha | CaptchaStruct | Server requires a captcha solution. |
hackAttempt | HackAttemptStruct | A client upgrade request attempt. |
updateMessage | UpdateMessageStruct | A previously sent message was edited or deleted. |
client.join(nick, password, channel): Authenticate and join a specific channel.client.say(channel, text): Send a message to a channel.client.changeColor(hex): Change your nickname color (e.g.,CCCCCC).client.changeUsername(newNick): Request a nickname change.
client.kick(channel, user): Kick a user (requires permissions).client.ban(channel, user): Ban a user (requires permissions).client.enableCaptcha(channel): Turn on captcha for the channel.client.lockChannel(channel): Lock the channel (admin only).
The MessageStruct (passed in the message event) has helper methods:
message.reply(text): Automatically replies to the channel the message originated from.
client.updateMessage(customId, text, mode): Edit a message you previously sent.mode:'overwrite','append','prepend', or'complete'(delete).
If the server implements custom opcodes that are not natively handled by the engine, you can register a listener for them:
client.onCommand('customEvent',(payload)=>{console.log('Received custom packet:',payload);});Users are stored in an extended Map for easy access.
// Get a user by IDconstuser=client.users.get(12345);// Find a user by nameconstuser=client.users.find(u=>u.username==='Admin');if(user){console.log(`${user.username} is currently ${user.isOnline ? 'Online' : 'Offline'}`);}MIT