Chat
The main entry point for creating a multi-platform chat bot.
The Chat class coordinates adapters, state, and event handlers. Create one instance and register handlers for different event types.
import { Chat } from "chat";Constructor
const bot = new Chat(config);Prop
Type
Event handlers
onNewMention
Fires when the bot is @-mentioned in a thread it has not subscribed to. This is the primary entry point for new conversations.
bot.onNewMention(async (thread, message) => {
await thread.subscribe();
await thread.post("Hello!");
});Prop
Type
onSubscribedMessage
Fires for every new message in a subscribed thread. Once subscribed, all messages (including @-mentions) route here instead of onNewMention.
bot.onSubscribedMessage(async (thread, message) => {
if (message.isMention) {
// User @-mentioned us in a thread we're already watching
}
await thread.post(`Got: ${message.text}`);
});onNewMessage
Fires for messages matching a regex pattern in unsubscribed threads.
bot.onNewMessage(/^!help/i, async (thread, message) => {
await thread.post("Available commands: !help, !status");
});Prop
Type
onReaction
Fires when a user adds or removes an emoji reaction.
import { emoji } from "chat";
// Filter to specific emoji
bot.onReaction([emoji.thumbs_up, emoji.heart], async (event) => {
if (event.added) {
await event.thread.post(`Thanks for the ${event.emoji}!`);
}
});
// Handle all reactions
bot.onReaction(async (event) => { /* ... */ });Prop
Type
onAction
Fires when a user clicks a button or selects an option in a card.
// Single action
bot.onAction("approve", async (event) => {
await event.thread.post("Approved!");
});
// Multiple actions
bot.onAction(["approve", "reject"], async (event) => { /* ... */ });
// All actions
bot.onAction(async (event) => { /* ... */ });Prop
Type
onModalSubmit
Fires when a user submits a modal form.
bot.onModalSubmit("feedback", async (event) => {
const comment = event.values.comment;
if (event.relatedThread) {
await event.relatedThread.post(`Feedback: ${comment}`);
}
});Prop
Type
Returns ModalResponse | undefined to control the modal after submission:
{ action: "close" }— close the modal{ action: "errors", errors: { fieldId: "message" } }— show validation errors{ action: "update", modal: ModalElement }— replace the modal content{ action: "push", modal: ModalElement }— push a new modal view onto the stack
onSlashCommand
Fires when a user invokes a /command in the message composer. Currently supported on Slack.
// Specific command
bot.onSlashCommand("/status", async (event) => {
await event.channel.post("All systems operational!");
});
// Multiple commands
bot.onSlashCommand(["/help", "/info"], async (event) => {
await event.channel.post(`You invoked ${event.command}`);
});
// Catch-all
bot.onSlashCommand(async (event) => {
console.log(`${event.command} ${event.text}`);
});Prop
Type
onModalClose
Fires when a user closes a modal (requires notifyOnClose: true on the modal).
bot.onModalClose("feedback", async (event) => { /* ... */ });onAssistantThreadStarted
Fires when a user opens a new assistant thread (Slack Assistants API). Use this to set suggested prompts, show a status indicator, or send an initial greeting.
bot.onAssistantThreadStarted(async (event) => {
const slack = bot.getAdapter("slack") as SlackAdapter;
await slack.setSuggestedPrompts(event.channelId, event.threadTs, [
{ title: "Get started", message: "What can you help me with?" },
]);
});Prop
Type
onAssistantContextChanged
Fires when a user navigates to a different channel while the assistant panel is open (Slack Assistants API). Use this to update suggested prompts or context based on the new channel.
bot.onAssistantContextChanged(async (event) => {
const slack = bot.getAdapter("slack") as SlackAdapter;
await slack.setAssistantStatus(event.channelId, event.threadTs, "Updating context...");
});The event shape is identical to onAssistantThreadStarted.
onAppHomeOpened
Fires when a user opens the bot's Home tab in Slack. Use this to publish a dynamic Home tab view.
bot.onAppHomeOpened(async (event) => {
const slack = bot.getAdapter("slack") as SlackAdapter;
await slack.publishHomeView(event.userId, {
type: "home",
blocks: [{ type: "section", text: { type: "mrkdwn", text: "Welcome!" } }],
});
});Prop
Type
Utility methods
webhooks
Type-safe webhook handlers keyed by adapter name. Pass these to your HTTP route handler.
bot.webhooks.slack(request, { waitUntil });
bot.webhooks.teams(request, { waitUntil });getAdapter
Get an adapter instance by name.
const slack = bot.getAdapter("slack");openDM
Open a direct message thread with a user.
const dm = await bot.openDM("U123456");
await dm.post("Hello via DM!");
// Or with an Author object
const dm = await bot.openDM(message.author);channel
Get a Channel by its channel ID.
const channel = bot.channel("slack:C123ABC");
for await (const msg of channel.messages) {
console.log(msg.text);
}initialize / shutdown
Manually manage the lifecycle. Initialization happens automatically on the first webhook, but you can call it explicitly for non-webhook use cases.
await bot.initialize();
// ... do work ...
await bot.shutdown();reviver
Get a JSON.parse reviver that deserializes Thread and Message objects from workflow payloads.
const data = JSON.parse(payload, bot.reviver());
await data.thread.post("Hello from workflow!");