Skip to content
BotServBotServ
ChatwootCustomer serviceHelpdeskSelf-hostingOpen sourceOmnichannelSupport

Chatwoot self-hosted: Open-source customer service

Self-host Chatwoot: omnichannel customer support via website, WhatsApp, email. AI integration with Ollama for automated responses.

S

schutzgeist

4 min read
Chatwoot self-hosted: Open-source customer service

Chatwoot self-hosted: customer service platform with AI

What this article covers

  • What Chatwoot is: open-source customer service with omnichannel support.
  • Docker setup and channel configuration (website, email, WhatsApp).
  • AI integration: Ollama answers tickets automatically or drafts responses.
  • Agent workflows, automation, labels, and routing.
  • Comparison to Rocket.Chat Omnichannel and Intercom.

Introduction

Chatwoot is the open-source alternative to Intercom and Zendesk: a customer service platform that consolidates all communication channels into a single inbox. Website chat widget, email, WhatsApp Business, Telegram, Facebook, even phone integrations. Agents handle everything from one interface.

For AI self-hosters, Chatwoot is the ideal frontend for AI-powered support: messages arrive, Ollama drafts a response, an agent reviews and sends it (or AI responds automatically for simple cases). Human-in-the-loop by design.

Typical use cases

  • AI-first-level support: AI answers standard questions, humans take complex cases.
  • Omnichannel inbox: website, WhatsApp, email all land in one queue.
  • Draft responses: agents receive AI-generated drafts for review (copilot mode).
  • Auto-categorization: AI tags tickets (bug, billing, inquiry) and routes them.
  • Bot handoff: Typebot or your own bot escalates to Chatwoot.

Installation: Docker

Chatwoot is a Rails app with Postgres and Redis:

services:
  chatwoot:
    image: chatwoot/chatwoot:latest
    ports: ["127.0.0.1:3000:3000"]
    environment:
      - SECRET_KEY_BASE=langer-zufaelliger-key
      - FRONTEND_URL=https://support.deine-domain.de
      - POSTGRES_HOST=postgres
      - POSTGRES_USERNAME=chatwoot
      - POSTGRES_PASSWORD=geheim
      - POSTGRES_DATABASE=chatwoot
      - REDIS_URL=redis://redis:6379
      - MAILER_SENDER_EMAIL=support@deine-domain.de
      - SMTP_ADDRESS=smtp.dein-server.de
      - SMTP_PORT=587
      - SMTP_USERNAME=...
      - SMTP_PASSWORD=...
    volumes: [chatwoot_data:/app/storage]
    depends_on: [postgres, redis]
    restart: always

  chatwoot-worker:
    image: chatwoot/chatwoot:latest
    command: bundle exec sidekiq -C config/sidekiq.yml
    environment: *same-env-vars*
    volumes: [chatwoot_data:/app/storage]
    depends_on: [postgres, redis]
    restart: always

  postgres:
    image: postgres:16
    environment:
      POSTGRES_USER: chatwoot
      POSTGRES_PASSWORD: geheim
      POSTGRES_DB: chatwoot
    volumes: [pg_data:/var/lib/postgresql/data]
    restart: always

  redis:
    image: redis:7
    volumes: [redis_data:/data]
    restart: always

volumes:
  chatwoot_data:
  pg_data:
  redis_data:

After startup, run docker exec chatwoot bundle exec rails db:prepare for database setup, then walk through the setup wizard.

Setting up channels

  • Website live chat: Inbox → Website → embed the widget snippet on your site (like Rocket.Chat Livechat, but as a dedicated support platform).
  • Email: incoming mail to support@ becomes tickets.
  • WhatsApp Business: via Twilio, 360dialog, or directly through WhatsApp Cloud API.
  • Telegram: enter a bot token; Telegram messages become tickets.
  • API channel: custom integrations via the Chatwoot API.

AI integration: Ollama as support agent

Chatwoot offers webhooks (on each new message) and a REST API (post responses). The AI agent sits in the middle:

from flask import Flask, request
import requests
import ollama

app = Flask(__name__)
CW = "https://support.deine-domain.de"
CW_TOKEN = "dein-api-access-token"
client = ollama.Client(host="http://ollama:11434")

@app.route("/webhook", methods=["POST"])
def webhook():
    data = request.json
    if data.get("event") != "message_created":
        return {"ok": True}
    if data.get("message_type") != "incoming":   # only customer messages
        return {"ok": True}

    convo_id = data["conversation"]["id"]
    text = data.get("content", "")

    # Load conversation context from Chatwoot
    msgs = requests.get(
        f"{CW}/api/v1/accounts/1/conversations/{convo_id}/messages",
        headers={"api_access_token": CW_TOKEN}).json()
    history = [{"role": "user" if m["message_type"] == 0 else "assistant",
                "content": m["content"]} for m in msgs["payload"][-10:]]

    resp = client.chat(model="llama3.1:8b", messages=[
        {"role": "system", "content":
         "Du bist Support-Agent. Antworte kurz, hilfreich. "
         "Wenn Du unsicher bist, sag 'Ich leite an einen Kollegen weiter'."}
    ] + history)
    answer = resp["message"]["content"]

    # Post response as agent
    requests.post(
        f"{CW}/api/v1/accounts/1/conversations/{convo_id}/messages",
        headers={"api_access_token": CW_TOKEN},
        json={"content": answer})
    return {"ok": True}

Copilot mode instead of auto-reply

Safer for business: AI posts a draft as a private note (visible only internally), and the agent reviews and sends it:

# private: True → visible only to staff
requests.post(url, json={"content": f"[KI-Entwurf]\n{answer}",
                         "private": True})

Automation within Chatwoot

Built-in automation rules (no code needed):

  • label assignment by keywords
  • auto-assign to agent teams
  • SLA tracking and escalation
  • canned responses (pre-written templates)

Extensible with AI webhooks: AI tags → automation routes.

Security and data protection

  • GDPR: on-premise means customer data stays with you, the main advantage over Intercom and Zendesk.
  • Customer data: support chat contains personal information. Use HTTPS and restrict agent access.
  • API tokens: use separate tokens per integration.
  • AI transparency: customers should know if they’re talking to AI or a human. Make this clear in the bot name or introduction.

Chatwoot vs. alternatives

ToolStrengthWeakness
Chatwootomnichannel, agent inbox, AI-readyRails app, somewhat heavier
Rocket.Chatteam chat + omnichannelweaker support features
Intercommost mature AI featurescloud-only, very expensive
Typebotno-code flowsno agent inbox

Further resources

Key takeaways:

  • Chatwoot = open-source Intercom: omnichannel support (website, email, WhatsApp) in one inbox.
  • Webhooks + API mean Ollama can answer tickets or draft responses for agents.
  • Human-in-the-loop: copilot mode (AI draft, agent review) is the safe approach.
  • Self-hosted means customer data stays with you (GDPR compliance).
  • The best open-source choice for real customer service with AI.

FAQ

Can AI respond completely automatically?

Technically yes (webhook → Ollama → post response). However, copilot mode is recommended: AI writes private drafts, an agent reviews and sends. Safer for customer service.

Which channels are supported?

Website widget, email, WhatsApp Business, Telegram, Facebook, Instagram, SMS, voice all in one inbox. This is Chatwoot’s core strength.

Chatwoot or Rocket.Chat for support?

Chatwoot is a dedicated support platform (tickets, agents, SLAs, routing). Rocket.Chat is a team chat with omnichannel as a feature. For pure customer service, choose Chatwoot. For team chat plus occasional support, Rocket.Chat works.

Resource requirements?

Rails, Postgres, Redis, and Sidekiq worker use around 1.5-2 GB RAM. Heavier than a single container, but manageable on a VPS or small PC.

Is it free?

Community Edition is open source and free with all core features. A cloud-hosted version with managed hosting and enterprise features exists, but self-hosters don’t need it.

WhatsApp integration?

Yes, via the official WhatsApp Business Cloud API or BSPs like Twilio and 360dialog. WhatsApp messages become tickets, and agents or AI respond from the inbox.

Sources and further reading

Back to Blog
Share:

Related Posts