Skip to content

omarperezr/SmarttyBot

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

22 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

SmarttyBot

An LLM-powered, multi-platform chat assistant written in Go β€” one bot that lives in Telegram, Discord, Slack and Email, understands natural language, and gets work done: GitLab reports, email delivery, cross-platform message sync, and more.

Go Report Card CI Maintainability Go Version License: GPL v3

Address the bot on any platform β€” @mention it, reply to it, or call it by name β€” and it decides what to do via LLM tool calling (Groq's free OpenAI-compatible API). No command syntax to memorize.

you>      @smartty gitlab report for webapp
smartty>  πŸ“Š webapp β€” 12 open issues (3 in progress, 75% done) …

you>      and the oldest ones?
smartty>  πŸ•° The 5 oldest open issues are …        ← follow-ups work: per-chat memory

Highlights

  • Assistant-first UX β€” natural language on every platform, parsed into typed tool calls (gitlab_report, send_email, cross_post, toggle_sync). Un-addressed messages never touch the LLM, keeping API usage near zero.
  • Conversation memory β€” bounded per-chat context (mutex-safe, oldest-evicted) so follow-up questions like "and the in-progress ones?" just work.
  • Interactive reports β€” GitLab reports in Telegram render with an inline-keyboard pager; sections swap in place via callbacks, with a bounded tracker so memory stays flat.
  • Two-way channel sync β€” opt-in mirroring between same-named Telegram/Discord/Slack channels through a platform-agnostic Messenger interface.
  • Push everywhere, poll nowhere β€” Slack over Socket Mode (no public endpoint), email over IMAP IDLE (with automatic polling fallback), Discord and Telegram over their streaming APIs.
  • Every channel is optional β€” each platform enables itself only when its tokens are configured; any subset (or none) runs fine, and one misconfigured channel never takes down the rest.
  • Zero-dependency persistence β€” embedded SQLite behind generic, mutex-safe stores; no external database to operate.
  • Production hygiene β€” graceful signal-based shutdown, structured logging (log/slog), /healthz + /metrics endpoints, Docker Compose deployment.

Architecture

flowchart LR
    subgraph channels["Chat channels β€” each optional"]
        TG[Telegram]
        DC[Discord]
        SL[Slack<br/>Socket Mode]
        EM[Email<br/>SMTP + IMAP IDLE]
    end

    HUB[Hub<br/>cross-post & two-way sync]
    AST[Assistant<br/>Groq tool calling + memory]
    GL[GitLab client<br/>+ report renderer]
    DB[(SQLite<br/>persisted stores)]
    HS[health server<br/>/healthz Β· /metrics]

    TG <--> HUB
    DC <--> HUB
    SL <--> HUB
    EM <--> HUB
    TG -- "addressed msgs" --> AST
    DC -- "addressed msgs" --> AST
    SL -- "addressed msgs" --> AST
    AST --> GL
    AST -- send --> EM
    AST --> HUB
    HUB --- DB
    AST --- DB
Loading
Package Responsibility
cmd/smartty_bot Entrypoint: config, dependency wiring, signal-based graceful shutdown
internal/config Env loading, SQLite bootstrap, persisted stores
internal/store Generic, mutex-safe, SQLite-backed key/value maps
internal/assistant The LLM brain: Groq tool calling, per-chat memory, addressed-message detection
internal/hub Cross-platform router: cross-posting + opt-in channel sync over a Messenger interface
internal/telegram Telegram client, commands, callback handling, interactive report pagination
internal/discord Discord client, prefix + slash commands
internal/slack Slack client via Socket Mode
internal/email SMTP sending + IMAP IDLE inbox listener
internal/gitlab GitLab REST API client
internal/gitlabreport Renders GitLab data into chat replies and paged report sections
internal/health /healthz + /metrics HTTP server

Design notes for the curious:

  • New platforms plug in by implementing the hub's small Messenger interface β€” each platform is a self-contained package with no cross-imports between siblings.
  • New assistant abilities are two steps: declare the tool schema in internal/assistant/tools.go, dispatch it in internal/assistant/assistant.go.
  • Concurrency is treated as a first-class concern: shared state lives behind mutex-guarded stores and every CI run executes the full test suite under the race detector.
  • Tested with fakes at the seams (FakeMessenger, FakeReporter, fake routers) β€” no network calls in tests.

Quick start

Requires Go 1.25+.

git clone https://github.com/omarperezr/SmarttyBot
cd SmarttyBot
cp .exampleenv .env   # fill in tokens for the channels you want
go build ./cmd/smartty_bot
./smartty_bot

State lives in data/smartty.db (SQLite), created automatically on first run.

Or with Docker:

docker compose up --build

.env supplies configuration; a named volume persists data/.

Configuration

Every channel is optional. The bot enables each platform solely based on whether its tokens are set, starts fine with any subset, and a misconfigured channel logs its own error without affecting the others. See .exampleenv for the full variable list (including BOT_NAME, PORT, LOG_LEVEL, DB_PATH).

Groq β€” natural-language assistant

Create a free API key at https://console.groq.com/keys, then:

GROQ_API_KEY="gsk_..."
GROQ_MODEL="llama-3.3-70b-versatile"   # optional; this is the default
GitLab β€” reports

Create a personal access token with read_api scope at https://gitlab.com/-/user_settings/personal_access_tokens, then:

GITLAB_TOKEN="glpat-..."
GITLAB_URL="https://gitlab.com/"
Telegram

Message @BotFather, send /newbot, choose a name and a username ending in bot, then:

TELEGRAM_API_KEY="123456:ABC-DEF..."

The bot discovers its own username automatically.

Discord

Create an application at the Discord Developer Portal, open Bot β†’ Reset Token, then:

DISCORD_API_KEY="..."
Email
EMAIL_ACCOUNT="account@gmail.com"
EMAIL_PASSWORD="app-password"
SMTP_SERVER="smtp.gmail.com"
SMTP_PORT=587
IMAP_SERVER="imap.gmail.com"
IMAP_PORT=993

Incoming mail is delivered via IMAP IDLE (instant push); servers without IDLE fall back to polling automatically.

Slack

Slack uses Socket Mode β€” no public endpoint required. In your Slack app config: enable Socket Mode, add an app-level token with connections:write, subscribe to app_mention (and optionally message.channels) events, and install the bot. Then:

SLACK_APP_TOKEN="xapp-..."   # app-level token
SLACK_BOT_TOKEN="xoxb-..."   # bot token

Slack stays disabled unless both tokens are set.

Using the assistant

On any platform, address the bot to trigger the LLM:

  • @mention it, reply to one of its messages, or start your message with its name (BOT_NAME, default smartty)
  • e.g. @smartty gitlab report for webapp, or smartty email alice@x.com subject "hi" body "..."

Plain, un-addressed messages are never sent to the LLM. In a synced channel they are mirrored to the paired channels instead.

Legacy prefix commands still work alongside natural language:

Platform Commands
Telegram -m/-mention <text> Β· -p/-parse <text> Β· -r/-register @TelegramUser discordUser Β· -sync on|off
Discord -a/-answer (/answer) Β· -r (/register) Β· -rm (/register-email) Β· -m/-send-email (/send-email) Β· -sync (/sync)

Discord also registers native slash commands (/answer, /register, /send-email, /sync, …).

Development

go build ./...        # compile everything
go vet ./...          # static analysis
go test -race ./...   # full suite under the race detector
golangci-lint run     # lint (errcheck, staticcheck, ineffassign, misspell, …)

CI runs formatting checks, go vet, race-enabled tests, golangci-lint and a Docker build on every push and pull request.

Updating

Running an existing deployment? Updating is a pull-and-rebuild:

git pull
go build ./cmd/smartty_bot && ./smartty_bot   # binary deployment
# or
docker compose up --build -d                   # Docker deployment

The SQLite schema is created/migrated automatically on startup and data/ is preserved across updates (named volume under Docker). To bump dependencies during development:

go get -u ./... && go mod tidy
go test -race ./...

Roadmap

  • More platforms (WhatsApp, Matrix) β€” the hub's Messenger interface makes each new platform a self-contained package
  • Real observability β€” Prometheus client metrics (messages handled, LLM latency, tool-call counts per platform) plus a ready-to-import Grafana dashboard
  • Long-term memory (RAG) β€” persist conversation history in SQLite so the assistant can recall past context ("what did we decide last week?")
  • Scheduled digests β€” natural-language scheduling ("every morning at 9, post the gitlab report to #standup") via a cron tool the assistant can invoke
  • GitHub support alongside GitLab β€” one Reporter interface, two backends
  • Release automation β€” GoReleaser, signed binaries and a published container image on every tag

Support

If this project is useful to you, consider supporting it:

Ko-fi

License

GNU General Public License v3.0

About

A really smart bot that connects with your email, discord, telegram and gitlab

Topics

Resources

License

Stars

6 stars

Watchers

1 watching

Forks

Releases

No releases published

Sponsor this project

Packages

 
 
 

Contributors

Languages