Introduction: The Evolution of Slack Agents
Slack agents have long been limited to simple command-response patterns. But with the rise of agentic AI, they need to handle complex, multi-turn conversations and proactive events. The latest update to eve brings a game-changing set of features: session-aware messaging, cancellation, reset, and event-driven reactions.
Gone are the days when you had to mention the bot every time. Now, your agent can maintain context and act autonomously within a thread, making interactions more natural and efficient.
Key Features at a Glance
- Autonomous Thread Replies: No more repeated mentions.
- Session Control: Cancel mid-turn responses or reset conversations entirely.
- Event-Driven Actions: React to any Slack event your app subscribes to.

Deep Dive: Implementing the New Hooks
Continuing Conversations Without Repeated Mentions
The core of this update is the onMessage hook. It receives incoming Slack messages and uses two helper functions: ctx.isBotMentioned() and ctx.isSubscribed(). The latter checks if the message belongs to a thread with an active session. This means once your agent is in a conversation, it can keep replying without being mentioned again.
Here's a practical implementation example:
// Example: Dispatch DMs, mentions, and thread follow-ups
export default slackChannel({
credentials: connectSlackCredentials("slack/my-agent"),
async onMessage(ctx, message) {
if (message.author?.isBot) return null;
const isDirectMessage = message.raw.channel_type === "im";
return isDirectMessage || ctx.isBotMentioned() || (await ctx.isSubscribed()) ? { auth: null } : null;
},
});
This code ensures your agent responds to direct messages, explicit mentions, and any follow-ups in an active thread. For routing based on thread participants, use ctx.thread.listParticipants() to get unique user IDs in order.
Cancelling and Resetting Sessions
Two session helpers give you fine-grained control:
ctx.cancel(): Stops the current turn but keeps the session. Call it before returning{ auth }to queue the new message as replacement input.ctx.reset(): Terminates the session entirely. The next message starts fresh with new history and state.
Here's how to implement a reset command:
// Example: Reset command triggered by user input
export default slackChannel({
credentials: connectSlackCredentials("slack/my-agent"),
async onMessage(ctx, message) {
if (message.text.trim() !== "!new") return null;
await ctx.reset({ reason: "Slack user requested !new" });
await ctx.thread.post("Started a fresh conversation.");
return null;
},
});
Handling Any Events API Callback
The onEvent hook lets your agent react to any event your Slack app subscribes to, such as reaction_added, team_join, or channel_created. Use ctx.receive() to start an agent turn, or call it multiple times to fan out events.
For instance, you can onboard new team members in multiple channels:
// Example: Fan out team_join event to multiple channels
const onboardingChannels = ["C0123ABC", "C0456DEF"];
export default slackChannel({
credentials: connectSlackCredentials("slack/my-agent"),
async onEvent({ receive }, event) {
if (event.type !== "team_join") return;
await Promise.all(
onboardingChannels.map((channelId) => receive({
message: `A user joined the Slack workspace. Onboard them from this event:\n${JSON.stringify(event)}`,
target: { channelId },
auth: null,
})),
);
},
});
This code demonstrates how to turn a single event into multiple targeted actions.

Limitations and Considerations
While these features are powerful, there are some caveats:
- Event Scope Requirements: Public channel messages require
message.channelstrigger andchannels:historybot scope. Private channels needmessage.groupsandgroups:history. Ensure your Slack app has the correct permissions. - Session State: Resetting a session ends it permanently; there's no undo. Make sure your logic is robust.
- Rate Limits: With event-driven reactions, you might hit Slack API rate limits if you have high traffic. Plan accordingly.
Next Steps for Learning
To get the most out of eve's Slack integration:
- Read the official Slack channel documentation to understand all available options.
- Experiment with different event types to see what works best for your use case.
- Combine with other features like the JIT testing approach for agentic development to ensure your agent is reliable before deployment.

Conclusion: Embrace the Agentic Era
This update marks a significant step toward more autonomous and interactive Slack agents. By leveraging these new hooks, you can build agents that feel more human and responsive. Start by implementing the onMessage hook to enable thread continuity, then explore onEvent for proactive actions. Remember to test thoroughly—consider adopting just-in-time testing practices to ensure your agent behaves correctly in production.
Happy building!
Related Articles: