A comprehensive chat bot framework modeled after GitHub's Campfire bot for building extensible chat bots across multiple platforms
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Comprehensive message pattern matching and response system for different types of chat interactions and events.
Methods for registering different types of message listeners and event handlers.
/**
* Listen for messages matching a regular expression
* @param regex - Pattern to match against message text
* @param options - Optional listener configuration
* @param callback - Function called when pattern matches
*/
hear(regex: RegExp, options?: ListenerOptions, callback: ListenerCallback): void;
/**
* Listen for messages directed at the robot (mentions or direct messages)
* @param regex - Pattern to match against message text
* @param options - Optional listener configuration
* @param callback - Function called when pattern matches
*/
respond(regex: RegExp, options?: ListenerOptions, callback: ListenerCallback): void;
/**
* Listen for user entering the room/channel
* @param options - Optional listener configuration
* @param callback - Function called when user enters
*/
enter(options?: ListenerOptions, callback: ListenerCallback): void;
/**
* Listen for user leaving the room/channel
* @param options - Optional listener configuration
* @param callback - Function called when user leaves
*/
leave(options?: ListenerOptions, callback: ListenerCallback): void;
/**
* Listen for room/channel topic changes
* @param options - Optional listener configuration
* @param callback - Function called when topic changes
*/
topic(options?: ListenerOptions, callback: ListenerCallback): void;
/**
* Catch all messages that don't match other listeners
* @param options - Optional listener configuration
* @param callback - Function called for unmatched messages
*/
catchAll(options?: ListenerOptions, callback: ListenerCallback): void;
/**
* Register error handler for listener errors
* @param callback - Function called when listener errors occur
*/
error(callback: (error: Error, response?: Response) => void): void;
/**
* Register custom listener with matcher function
* @param matcher - Function that tests if message matches
* @param options - Optional listener configuration
* @param callback - Function called when matcher returns true
*/
listen(matcher: (message: Message) => boolean, options?: ListenerOptions, callback: ListenerCallback): void;Usage Examples:
import { Robot } from "hubot";
const robot = new Robot("Shell");
// Basic text pattern matching
robot.hear(/hello/i, (res) => {
res.send("Hello there!");
});
// Respond to direct mentions
robot.respond(/how are you/i, (res) => {
res.reply("I'm doing great, thanks for asking!");
});
// Capture pattern groups
robot.hear(/remember (.+)/i, (res) => {
const thing = res.match[1];
robot.brain.set('memory', thing);
res.send(`I'll remember: ${thing}`);
});
// User events
robot.enter((res) => {
res.send(`Welcome, ${res.message.user.name}!`);
});
robot.leave((res) => {
res.send(`Goodbye, ${res.message.user.name}!`);
});
// Topic changes
robot.topic((res) => {
res.send(`New topic: ${res.message.text}`);
});
// Catch unmatched messages
robot.catchAll((res) => {
res.send("I didn't understand that. Try 'help' for commands.");
});
// Error handling
robot.error((error) => {
console.error('Listener error:', error);
});
// Custom listener with matcher function
robot.listen(
(message) => message.text && message.text.includes("urgent"),
{ id: "urgent-detector" },
(res) => {
res.send("I detected an urgent message!");
}
);The Response class provides methods for sending messages back to the chat and accessing message context.
/**
* Response context for sending messages back to chat
* @param robot - Robot instance
* @param message - Original message that triggered listener
* @param match - Regex match results (if applicable)
*/
class Response {
constructor(robot: Robot, message: Message, match?: RegExpMatchArray);
// Properties
robot: Robot;
message: Message;
match: RegExpMatchArray | null;
envelope: Envelope;
// Sending methods
async send(...strings: string[]): Promise<void>;
async reply(...strings: string[]): Promise<void>;
async emote(...strings: string[]): Promise<void>;
async topic(...strings: string[]): Promise<void>;
async play(...strings: string[]): Promise<void>;
async locked(...strings: string[]): Promise<void>;
// Utility methods
random(items: any[]): any;
finish(): void;
http(url: string, options?: HttpOptions): HttpClient;
}Usage Examples:
robot.hear(/joke/i, (res) => {
// Send message to same room
res.send("Why did the robot cross the road?");
// Reply mentioning the user
res.reply("To get to the other side!");
// Send emote/action message
res.emote("laughs at own joke");
// Pick random response
const responses = [
"That's funny!",
"Good one!",
"I don't get it..."
];
res.send(res.random(responses));
// Mark message as handled
res.finish();
});
// Access message context
robot.hear(/who am i/i, (res) => {
const user = res.message.user;
res.send(`You are ${user.name} (ID: ${user.id})`);
if (user.room) {
res.send(`You're in room: ${user.room}`);
}
});
// Use regex match groups
robot.hear(/calculate (\d+) \+ (\d+)/i, (res) => {
const a = parseInt(res.match[1]);
const b = parseInt(res.match[2]);
res.send(`${a} + ${b} = ${a + b}`);
});Hierarchy of message types representing different chat events.
/**
* Base message class
* @param user - User who sent the message
* @param done - Whether message processing is complete
*/
class Message {
constructor(user: User, done?: boolean);
user: User;
done: boolean;
room: string;
finish(): void;
}
/**
* Text-based chat message
* @param user - User who sent the message
* @param text - Message text content
* @param id - Message ID
*/
class TextMessage extends Message {
constructor(user: User, text: string, id?: string);
text: string;
id?: string;
match(regex: RegExp): RegExpMatchArray | null;
toString(): string;
}
/**
* User entering room event
* @param user - User who entered
*/
class EnterMessage extends Message {
constructor(user: User);
}
/**
* User leaving room event
* @param user - User who left
*/
class LeaveMessage extends Message {
constructor(user: User);
}
/**
* Room topic change message
* @param user - User who changed topic
* @param text - New topic text
* @param id - Message ID
*/
class TopicMessage extends TextMessage {
constructor(user: User, text: string, id?: string);
}
/**
* Wrapper for unmatched messages in catchAll
* @param message - Original unmatched message
*/
class CatchAllMessage extends Message {
constructor(message: Message);
message: Message;
}Classes for handling different types of message matching.
/**
* Base listener class with custom matcher function
* @param robot - Robot instance
* @param matcher - Function that tests if message matches
* @param options - Listener configuration
* @param callback - Function called on match
*/
class Listener {
constructor(robot: Robot, matcher: (message: Message) => boolean, options: ListenerOptions, callback: ListenerCallback);
robot: Robot;
matcher: (message: Message) => boolean;
options: ListenerOptions;
callback: ListenerCallback;
async call(message: Message, middleware: Middleware): Promise<void>;
}
/**
* Regex-based text message listener
* @param robot - Robot instance
* @param regex - Regular expression to match
* @param options - Listener configuration
* @param callback - Function called on match
*/
class TextListener extends Listener {
constructor(robot: Robot, regex: RegExp, options: ListenerOptions, callback: ListenerCallback);
regex: RegExp;
}interface ListenerOptions {
id?: string;
}
interface Envelope {
room: string;
user: User;
message: Message;
}
type ListenerCallback = (response: Response) => void | Promise<void>;
interface HttpOptions {
timeout?: number;
headers?: Record<string, string>;
[key: string]: any;
}