or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

adapters-integration.mdbrain-user-management.mdcli.mdcore-bot-management.mddatastore.mdindex.mdmessage-handling.mdscripts-middleware.md
tile.json

message-handling.mddocs/

Message Handling

Comprehensive message pattern matching and response system for different types of chat interactions and events.

Capabilities

Listener Registration

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!");
  }
);

Response Class

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}`);
});

Message Classes

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;
}

Listener Classes

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;
}

Types

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;
}