Skip to content

Channels Quick Start

Connect your AI agent to a messaging platform in minutes.

Go: Telegram Bot

This example sets up a Telegram adapter that routes messages to the OpenParallax engine.

1. Configure

Add to your config.yaml:

yaml
channels:
  telegram:
    enabled: true
    token_env: TELEGRAM_BOT_TOKEN
    allowed_users: [123456789]  # Your Telegram user ID

Set the environment variable:

bash
export TELEGRAM_BOT_TOKEN="1234567890:ABCDefGHIJKlmnOPQRSTuvwxyz"

2. Register the Adapter

go
package main

import (
    "context"

    "github.com/openparallax/openparallax/internal/channels"
    "github.com/openparallax/openparallax/internal/channels/telegram"
    "github.com/openparallax/openparallax/internal/engine"
    "github.com/openparallax/openparallax/internal/logging"
    "github.com/openparallax/openparallax/internal/types"
)

func main() {
    // Assume engine and logger are initialized.
    var eng *engine.Engine
    var log *logging.Logger

    // Create the channel manager.
    manager := channels.NewManager(eng, log)

    // Create and register the Telegram adapter.
    cfg := &types.TelegramConfig{
        Enabled:  true,
        TokenEnv: "TELEGRAM_BOT_TOKEN",
        AllowedUsers: []int64{123456789},
    }
    adapter := telegram.New(cfg, manager, log)
    if adapter != nil {
        manager.Register(adapter)
    }

    // Start all registered adapters.
    ctx, cancel := context.WithCancel(context.Background())
    defer cancel()
    manager.StartAll(ctx)

    // Block until shutdown.
    <-ctx.Done()
    manager.StopAll()
}

3. Handle Messages

The Manager automatically routes incoming messages through the engine pipeline and sends responses back. You do not need to write any message handling code.

When a user sends a message on Telegram:

  1. The adapter receives it via long-polling
  2. The Manager maps the chat to a session (creating one if needed)
  3. The Manager calls engine.ProcessMessageForWeb() with a response collector
  4. The collector aggregates streaming LLM tokens into a complete response
  5. The response is sent back to the Telegram chat via the Bot API

Go: Custom Adapter

To connect a new messaging platform, implement the ChannelAdapter interface:

go
package mychannel

import (
    "context"

    "github.com/openparallax/openparallax/internal/channels"
)

type MyAdapter struct {
    manager *channels.Manager
}

func (a *MyAdapter) Name() string { return "mychannel" }

func (a *MyAdapter) IsConfigured() bool { return true }

func (a *MyAdapter) Start(ctx context.Context) error {
    // Listen for incoming messages from your platform.
    // When you receive a message:
    //   response, err := a.manager.HandleMessage(ctx, "mychannel", chatID, text, mode)
    //   if err == nil && response != "" {
    //       a.SendMessage(chatID, &channels.ChannelMessage{Text: response})
    //   }
    <-ctx.Done()
    return nil
}

func (a *MyAdapter) Stop() error {
    return nil
}

func (a *MyAdapter) SendMessage(chatID string, msg *channels.ChannelMessage) error {
    // Send the message to your platform.
    // Use channels.SplitMessage(msg.Text, maxLen) for long messages.
    parts := channels.SplitMessage(msg.Text, 4096)
    for _, part := range parts {
        _ = part // send to your platform
    }
    return nil
}

Register your adapter with the Manager:

go
manager.Register(&MyAdapter{manager: manager})

Multiple Platforms

You can register multiple adapters simultaneously. Each runs in its own goroutine:

go
manager := channels.NewManager(eng, log)

if tgAdapter := telegram.New(tgCfg, manager, log); tgAdapter != nil {
    manager.Register(tgAdapter)
}
if waAdapter := whatsapp.New(waCfg, manager, log); waAdapter != nil {
    manager.Register(waAdapter)
}
if dcAdapter := discord.New(dcCfg, manager, log); dcAdapter != nil {
    manager.Register(dcAdapter)
}

manager.StartAll(ctx)
// All three adapters are now running concurrently.

Each platform gets independent session management. A Telegram user and a WhatsApp user talking to the same agent have separate sessions.

macOS: iMessage

On macOS, you can connect your agent to iMessage via the AppleScript bridge to Messages.app. Add to your config.yaml:

yaml
channels:
  imessage:
    enabled: true
    apple_id: "you@icloud.com"

Grant Full Disk Access to the OpenParallax process in System Settings, ensure Messages.app is signed in, and restart the agent. See the iMessage adapter documentation for full setup details.