app_mention

app_mention

Docs: https://api.slack.com/events/app_mention (opens in a new tab)

The app_mention event is the most commonly used event for Slack chatbots. It's triggered whenever a user mentions the bot:

@someuser: @mybot hello, bot!

If you subscribe to this event in your slack app, you'll receive a payload:

{
  "type": "app_mention",
  "user": "U061F7AUR",
  "text": "<@U0LAN0Z89> hello, bot!",
  "ts": "1515449522.000016",
  "channel": "C123ABC456",
  "event_ts": "1515449522000016"
}

Handling the event

To act on app_mention events, register an IAppMentionHandler:

builder.Services.AddSlackBotEvents()
                .AddAppMentionHandler<MyAppMentionHandler>()

The registration is of type IHandleAppMentions, and requires you to implement the interface:

public interface IHandleAppMentions
{
    Task<EventHandledResponse> Handle(EventMetaData eventMetadata, AppMentionEvent slackEvent);
}

Example:

MyAppMentionHandler.cs
class MyAppMentionHandler : IHandleAppMentions
{
    public Task<EventHandledResponse> Handle(EventMetaData meta, AppMentionEvent @evt)
    {
        Console.WriteLine("Someone mention the bot!");
        return Task.FromResult(new EventHandledResponse("OK"));
    }
}

Replying back

Sending outgoing messages back to Slack can be done via any Slack API client. For example Slackbot.Net.SlackClients.Http:

$ dotnet add package Slackbot.Net.SlackClients.Http
Program.cs
services.AddSlackHttpClient(c => c.BotToken = Environment.GetEnvironmentVariable("SLACK_TOKEN")
MyAppMentionHandler.cs
class MyAppMentionHandler : IHandleAppMentions
{
    private readonly ISlackClient _slack;
 
    public class MyAppMentionHandler(ISlackClient slack)
    {
        _slack = slack;
    }
 
    public Task<EventHandledResponse> Handle(EventMetaData meta, AppMentionEvent @evt)
    {
        Console.WriteLine("Someone mention the bot!");
        _client.ChatPostMessage(@evt.Channel, $"Hi, there!");
        return Task.FromResult(new EventHandledResponse("OK"));
    }
}

ChatPostMessage is async, but the Task is not awaited.

For small things like replying back, you won't usually see any issues. However – if you're doing any heavy lifting in a handler (>3000ms), Slack might treat it as timeouts, hence retring the notification. Your handler ends up being triggered several times.

Slacks timeout limit is 3 seconds (opens in a new tab).

While we limit the number of failure conditions we'll tolerate over time, we also gracefully retry sending your events according to an exponential backoff strategy.

– Slack

Multiple app_mention handlers

It's possible to register multiple handlers:

builder.Services.AddSlackBotEvents()
                .AddAppMentionHandler<AppMentionHandlerOne>()
                .AddAppMentionHandler<AppMentionHandlerTwo>()
ℹ️

By default, all handlers are executed in sequence

If you want to run them conditionally, implement ShouldHandle :

ShouldHandle(AppMentionEvent slackEvent)
class AppMentionHandlerOne : IHandleAppMentions
{
    public bool ShouldHandle(AppMentionEvent slackEvent) => slackEvent.Text.Contains("handlerOne");
 
    public Task<EventHandledResponse> Handle(EventMetaData meta, AppMentionEvent @evt)
    {
        Console.WriteLine("One triggered!");
        return Task.FromResult(new EventHandledResponse("OK"));
    }
}
 
class AppMentionHandlerOne : IHandleAppMentions
{
    public bool ShouldHandle(AppMentionEvent slackEvent) => slackEvent.Text.Contains("handlerTwo");
 
    public Task<EventHandledResponse> Handle(EventMetaData meta, AppMentionEvent @evt)
    {
        Console.WriteLine("Two triggered!");
        return Task.FromResult(new EventHandledResponse("OK"));
    }
}