mirror of
https://github.com/legop3/MultiRoombaRover.git
synced 2026-09-15 17:12:59 -04:00
3.5 KiB
3.5 KiB
Simple spectator bot
A spectator bot connects to the rover server with Socket.IO. It can receive the current session, read chat, and send messages that are visually tagged as bot messages.
Install
Create a small Node.js project and install the Socket.IO client:
npm install socket.io-client
Example bot
Create bot.js:
import { io } from 'socket.io-client';
// Replace this with the public URL of the MultiRoombaRover server.
const socket = io('https://your-rover-server.example', {
// Match the transports supported by the server while retaining polling as a
// fallback for networks or proxies that do not allow WebSocket connections.
transports: ['websocket', 'polling'],
});
// Socket.IO acknowledgements use callbacks. This small wrapper turns them into
// promises so setup failures and rejected chat messages are easy to handle.
function emitWithAck(event, payload) {
return new Promise((resolve, reject) => {
socket.emit(event, payload, (response = {}) => {
if (response.error) {
reject(new Error(response.error));
return;
}
resolve(response);
});
});
}
socket.on('connect', async () => {
console.log('Connected:', socket.id);
try {
// Set the name that will appear beside this connection and its messages.
await emitWithAck('nickname:set', {
nickname: 'My spectator bot',
});
// Ask the server to make this passive connection a spectator. Performing
// this after every connection also restores the role after a reconnect.
await emitWithAck('session:setRole', {
role: 'spectator',
});
console.log('Connected as a spectator');
} catch (error) {
console.error('Spectator setup failed:', error.message);
}
});
// Each session:sync event is a complete current session snapshot. Replace any
// previously stored session with this object instead of merging snapshots.
socket.on('session:sync', (session) => {
console.log('Session:', session);
});
// chat:init contains the recent chat history available when the bot connects.
socket.on('chat:init', (messages) => {
console.log('Recent chat:', messages);
});
// chat:message fires whenever a new message is broadcast, including messages
// sent by this bot itself.
socket.on('chat:message', (message) => {
console.log(`${message.nickname || 'Unknown'}: ${message.text}`);
});
socket.on('disconnect', (reason) => {
console.log('Disconnected:', reason);
});
// Setting bot to true adds the normal bot tag to the displayed chat message.
// It does not grant the connection any additional permissions.
function sendBotMessage(text) {
return emitWithAck('chat:send', {
text,
bot: true,
});
}
// Send one example message after the connection has had time to finish setup.
// A real bot would call sendBotMessage from its own message-handling logic.
setTimeout(() => {
sendBotMessage('Hello from my spectator bot!').catch((error) => {
console.error('Message failed:', error.message);
});
}, 5000);
Run it with:
node bot.js
Events used
nickname:setsets the bot's visible nickname.session:setRolechanges the connection to a spectator.session:syncprovides the latest complete session state.chat:initprovides recent chat history after connecting.chat:messageprovides new chat messages.chat:sendsends a chat message. Includebot: trueto give it the bot tag.
The server can reject spectator access or a chat message. Always check the acknowledgement callback, as the example does, so those errors are not silently ignored.