Middleware & Handler Patterns
Middleware
| Aspect | Slack (Bolt) | Teams SDK v2 |
|---|---|---|
| Global middleware | app.use(async (\{ next \}) => \{ ... await next(); \}) | app.use(async (ctx) => \{ ... ctx.next(); \}) |
| Chaining | Explicit await next() — omitting drops the event silently | Explicit ctx.next() — omitting stops the pipeline |
| Listener middleware | Passed as extra args to app.message(filter, middleware, handler) | No equivalent — use guard functions at handler start |
| Authorization | Custom middleware checking Slack user/workspace | Bot Framework JWT validation is automatic |
Rating: GREEN — both have middleware, but Slack's is more granular.
Key Difference
Slack supports listener middleware — functions that run only for specific handlers. Teams has no equivalent. Convert listener middleware to guard conditions at the top of each handler:
typescript
// Slack: listener middleware
app.message(isAdmin, async ({ say }) => { await say("Admin action"); });
// Teams: guard function
app.on("message", async (ctx) => {
if (!isAdmin(ctx.activity.from.id)) return;
await ctx.send("Admin action");
});