Pethum Jeewantha
Back to blog

Building an AI Slack Bot in Go

GoAISlack

I recently built an AI-powered Slack bot that converses with users through an answer engine. Here's a short write-up of the architecture and the decisions behind it.

Why Go?

Slack bots are I/O-bound: they wait on Slack's Events API, call out to an LLM provider, and stream responses back. Go's goroutines make it natural to handle many concurrent conversations without blocking, and the single static binary is trivial to deploy.

The event loop

At its core the bot:

  1. Verifies the Slack request signature.
  2. Acknowledges the event within Slack's 3-second window.
  3. Hands the message off to a worker that calls the answer engine.
  4. Posts the response back to the channel.
func handleEvent(w http.ResponseWriter, r *http.Request) {
    // Acknowledge fast, then process asynchronously.
    go processMessage(event)
    w.WriteHeader(http.StatusOK)
}

Lessons learned

  • Acknowledge first, work later. Slack retries if you're slow, which causes duplicate replies. Return 200 OK immediately and process in a goroutine.
  • Idempotency matters. Dedupe on the Slack event ID so retries don't double-post.
  • Stream when you can. Updating a message in place feels far more responsive than waiting for the full completion.

There's plenty more to explore - threading context, rate limits, and tool use - but this foundation has been solid.