Skip to content

Universal event-driven omnichannel platform for AI agents to communicate across any messaging platform

Notifications You must be signed in to change notification settings

automagik-dev/omni

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1,053 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Omni — One API, Every Channel

MIT License Bun v2.0.0 Channels NATS

Universal event-driven omnichannel messaging platform

One API to send and receive messages across WhatsApp, Discord, Telegram, and more.
CLI-first. Event-driven. Built for AI agents.

InstallQuick StartAI AgentsCLIAPISDKsDevelopment


Think of Omni as a deep-sea octopus. Each channel is a tentacle — WhatsApp, Discord, Telegram — reaching into a different messaging ecosystem. Events are nerve impulses flowing through NATS JetStream. The core is the brain — identity resolution, event routing, and a unified API that lets you treat all channels as one.

Why Omni?

🔌 One API, every channel Send a WhatsApp message, a Discord embed, and a Telegram photo with the same endpoint
Event-driven Every action produces an event. Subscribe, replay, automate
🧬 Identity graph Same person on WhatsApp and Discord? Omni knows
🤖 AI-native Agent providers, automations, built to be controlled by LLMs
🔧 Plugin architecture Build new channels with the Channel SDK
📦 Multi-SDK Auto-generated TypeScript, Python, and Go SDKs

Channels

Channel Status Highlights
WhatsApp (Baileys) ✅ Stable QR/phone pairing, media, reactions, groups, contacts, presence
Discord ✅ Stable Bots, embeds, polls, buttons, threads, slash commands
Telegram ✅ New Bot API, inline keyboards, groups, channels, threads, polls
WhatsApp Cloud API 🔮 Planned
Slack 🔮 Planned

Install

Quickest (npm)

bun add -g @automagik/omni
omni install              # interactive wizard: sets up server + PM2

Migrating from @omni/cli? Run bun remove -g @omni/cli first.

Via install script (npm-first, git fallback)

curl -fsSL https://raw.githubusercontent.com/automagik-dev/omni/main/install-client.sh | bash

Full server from source

curl -fsSL https://raw.githubusercontent.com/automagik-dev/omni/main/install.sh | bash

Three modes: CLI only · Full server · CLI + connect to remote

Non-interactive & manual install
# CLI only (tries npm first, falls back to git clone)
curl -fsSL https://raw.githubusercontent.com/automagik-dev/omni/main/install.sh | bash -s -- --cli

# CLI + connect to remote
curl -fsSL https://raw.githubusercontent.com/automagik-dev/omni/main/install.sh | bash -s -- --cli https://your-omni-server.com

# Full server
curl -fsSL https://raw.githubusercontent.com/automagik-dev/omni/main/install.sh | bash -s -- --server

Manual:

git clone https://github.com/automagik-dev/omni.git && cd omni
make setup    # Install deps, create .env, start services

API runs at http://localhost:8882 · Swagger docs at /api/v2/docs · API key printed in startup banner.

Quick Start

# Authenticate
omni auth login --api-key <your-key>

# WhatsApp — scan QR
omni instances create --name "my-whatsapp" --channel whatsapp-baileys
omni instances qr <id> --watch

# Discord — connect bot
omni instances create --name "my-discord" --channel discord
omni instances connect <id> --token "BOT_TOKEN"

# Telegram — connect bot
omni instances create --name "my-telegram" --channel telegram
omni instances connect <id> --token "BOT_TOKEN"

# Send messages
omni send --to "+5511999999999" --text "Hello from the deep 🐙"

# Browse conversations
omni chats list --unread --sort unread

AI Agents

Connect any LLM provider and your instances become intelligent agents — responding to messages, reacting to events, across every channel.

Message received → NATS event → Agent Dispatcher → Provider (OpenAI/Agno/Webhook) → Humanized reply
# Connect a provider
omni providers create --name "my-llm" --schema openai --base-url "https://api.openai.com/v1" --api-key "sk-..."

# Bind to instance — it's now an agent
omni instances update <id> --agent-provider <provider-id>
Trigger When Use Case
DM Direct message Always reply
Mention @bot in group Respond to mentions
Reply Reply to bot's message Continue thread
Reaction Emoji on message 👍 approve, 🔥 prioritize

Built-in: message debouncing · per-user rate limits · access control · smart response chunking · typing presence · cross-channel identity · self-chat detection

Automations & event-driven workflows
# Auto-reply
omni automations create --name "welcome" \
  --trigger "message.received" \
  --action send_message --action-config '{"text":"Got it! 🐙"}'

# Webhook on connection
omni automations create --name "notify" \
  --trigger "instance.connected" \
  --action webhook --action-config '{"url":"https://your-app.com/hook"}'

# Route VIPs to a special agent
omni automations create --name "vip" \
  --trigger "message.received" \
  --condition '{"field":"payload.from","op":"in","value":["+551199..."]}' \
  --action call_agent --agent-id "vip-handler" --provider-id <id>

Architecture

┌─────────────┐  ┌─────────────┐  ┌─────────────┐
│  WhatsApp   │  │   Discord   │  │  Telegram   │     Tentacles
└──────┬──────┘  └──────┬──────┘  └──────┬──────┘
       └────────────────┼────────────────┘
              ┌─────────▼─────────┐
              │   NATS JetStream  │                    Nerve System
              └─────────┬─────────┘
              ┌─────────▼─────────┐
              │     Omni Core     │                    Brain
              └─────────┬─────────┘
         ┌──────────────┼──────────────┐
   ┌─────▼─────┐ ┌─────▼─────┐ ┌─────▼─────┐
   │  REST API  │ │    CLI    │ │ Dashboard  │        Interfaces
   └───────────┘ └───────────┘ └───────────┘
Project structure
packages/
├── core/               # Events, identity, schemas
├── db/                 # Drizzle ORM + PostgreSQL
├── api/                # Hono + tRPC + OpenAPI
├── channel-sdk/        # Plugin SDK
├── channel-whatsapp/   # Baileys
├── channel-discord/    # discord.js
├── channel-telegram/   # grammy
├── cli/                # `omni` command
├── media-processing/   # Media sync
├── sdk/                # TypeScript SDK
├── sdk-go/             # Go SDK
└── sdk-python/         # Python SDK
apps/
└── ui/                 # React + Vite + Tailwind

CLI Reference

Core commands — send, chats, messages, instances, channels, persons

send — Send messages

omni send --to "+5511999999999" --text "Hello!"
omni send --to "+5511999999999" --media ./photo.jpg --caption "Check this out"
omni send --to "+5511999999999" --reaction "👍" --message <messageId>
omni send --to "+5511999999999" --sticker ./sticker.webp
omni send --to "+5511999999999" --contact --name "John" --phone "+1234567890"
omni send --to "+5511999999999" --location --lat -23.55 --lng -46.63 --address "São Paulo"
omni send --to "discord-channel-id" --poll "Favorite color?" --options "Red,Blue,Green"
omni send --to "discord-channel-id" --embed --title "Alert" --description "Server rebooting" --color "#ff0000"
omni send --to "+5511999999999" --presence typing

chats — Manage conversations

omni chats list --unread --sort unread
omni chats messages <chatId> --limit 20 --rich
omni chats archive <chatId>
omni chats participants <chatId> --add "+5511999999999"

Subcommands: list · get · create · update · delete · archive · unarchive · messages · participants · read

messages — Search and manage

omni messages search "meeting tomorrow" --instance <id> --limit 10
omni messages read --chat <chatId> --instance <id>

instances — Channel connections

omni instances list
omni instances create --name "work-whatsapp" --channel whatsapp-baileys
omni instances qr <id> --watch
omni instances connect <id> --token "BOT_TOKEN"    # Discord / Telegram
omni instances sync <id> --type all --depth 30
omni instances contacts <id> --limit 50
omni instances groups <id>

Subcommands: list · get · create · delete · status · qr · pair · connect · disconnect · restart · logout · sync · syncs · update · contacts · groups · profile

persons — Contact directory

omni persons search "John"
omni persons get <id>
omni persons presence <id>
Management — keys, providers, automations, access, webhooks

keys — API key management

omni keys create --name "agent-key" --scopes "messages:*,instances:read"
omni keys list --status active
omni keys revoke <id> --reason "Compromised"

providers — AI/LLM providers

omni providers create --name "openai" --schema openai --api-key "sk-..."
omni providers list
omni providers test <id>

Schemas: agnoos · a2a · openai · anthropic · webhook · custom

automations — Event-driven workflows

omni automations create --name "Auto-reply" --trigger "message.received" \
  --action send_message --action-config '{"text":"Got it!"}'
omni automations list --enabled
omni automations test <id>

Actions: webhook · send_message · emit_event · log · call_agent

access — Access control

omni access create --type deny --instance <id> --phone "+1234567890" --action block
omni access list --instance <id>
omni access check --instance <id> --user "+1234567890"

Modes: disabled · blocklist · allowlist

webhooks — External event sources

omni webhooks create --name "github-events"
omni webhooks trigger --type "custom.event" --payload '{"key":"value"}'
System — status, auth, config, events, batch, logs
omni status                                    # Health check
omni auth login --api-key <key>                # Authenticate
omni config set defaultInstance <id>           # CLI settings
omni events list --type "message.*" --since 2h # Event history
omni events replay --start --since 2024-01-01  # Replay events
omni batch create --instance <id> --type targeted_chat_sync --chat <chatId>
omni resync --instance <id>                    # History backfill
omni logs list --level error --limit 50        # Server logs
omni dead-letters list --limit 20              # Failed events

REST API

Base URL http://localhost:8882/api/v2
Docs /api/v2/docs (Swagger UI)
OpenAPI /api/v2/openapi.json
Auth x-api-key header

20 endpoints: /auth · /instances · /messages · /chats · /events · /persons · /access · /settings · /providers · /automations · /webhooks · /keys · /logs · /batch-jobs · /dead-letters · /media · /metrics · /event-ops · /payloads

SDKs

TypeScript

import { createOmniClient } from '@omni/sdk';
const omni = createOmniClient({
  baseUrl: 'http://localhost:8882',
  apiKey: 'your-api-key',
});
await omni.messages.send({
  instanceId: '...',
  to: '+5511999999999',
  text: 'Hello from SDK!',
});

Python

from omni import OmniClient
client = OmniClient(
  base_url="http://localhost:8882",
  api_key="your-api-key"
)
instances = client.instances.list()

Go

client := omni.NewClient(
  "http://localhost:8882",
  "your-api-key",
)
instances, _ := client.Instances.List(ctx)

Regenerate after API changes: make sdk-generate

Web Dashboard

make dev-ui    # Dev → http://localhost:5173
make build-ui  # Prod → served by API on :8882

Pages: Dashboard · Instances · Chats · Chat View · Contacts · Persons · Providers · Automations · Access Rules · Batch Jobs · Dead Letters · Events · Logs · Settings

🔐 API Keys & Security

API key is generated on first boot (shown once in startup banner).

# Scoped keys
omni keys create --name "admin" --scopes "*"
omni keys create --name "reader" --scopes "messages:read,chats:read"
omni keys create --name "wa-only" --scopes "messages:*" --instances "uuid1,uuid2"

Scopes: namespace:action pattern — messages:*, instances:read, * for full access

Namespaces: messages · chats · instances · persons · events · access · settings · providers · automations · webhooks · keys · logs · batch

⚙️ Configuration & environment
Variable Default Description
API_PORT 8882 API server port
DATABASE_URL postgresql://...localhost:8432/omni PostgreSQL
NATS_URL nats://localhost:4222 NATS connection
OMNI_API_KEY (auto) Override primary key

Set *_MANAGED=false for external services. Full list in .env.example.

Service PM2 Name Port
PostgreSQL omni-pgserve 8432
NATS omni-nats 4222
API omni-api 8882

Development

make dev           # Start all services + API
make check         # typecheck + lint + test
make dev-ui        # UI dev server
make db-push       # Push schema changes
make db-studio     # Drizzle Studio
All make targets
make setup         # Full setup (deps + env + services)
make dev-api       # API only
make dev-services  # PostgreSQL + NATS via PM2
make typecheck     # TypeScript only
make lint          # Biome linter
make lint-fix      # Auto-fix
make test          # All tests
make test-api      # API tests
make test-file F=  # Specific test
make build         # Build all
make build-ui      # Build UI
make status        # Service status
make logs-api      # API logs
make restart-api   # Restart API
make db-reset      # Reset DB (DESTRUCTIVE)
make sdk-generate  # Regenerate SDKs
make cli ARGS=""   # Run CLI from source
make cli-link      # Install CLI globally
Building a channel plugin
import { BaseChannelPlugin } from '@omni/channel-sdk';

export class MyPlugin extends BaseChannelPlugin {
  readonly id = 'my-channel';
  readonly name = 'My Channel';
  readonly version = '1.0.0';
  readonly capabilities = { /* ... */ };

  async connect(instanceId: string, config: InstanceConfig) { /* ... */ }
  async disconnect(instanceId: string) { /* ... */ }
  async sendMessage(instanceId: string, message: OutgoingMessage) { /* ... */ }
}

Tech Stack

Runtime Bun
HTTP Hono
API tRPC + OpenAPI
DB PostgreSQL + Drizzle
Events NATS JetStream
Validation Zod
Frontend React + Vite + Tailwind
Monorepo Turborepo
Linter Biome

MIT — do whatever you want, just don't blame the octopus. 🐙

This README is maintained by Scroll 📜, an autonomous sub-agent of Omni.