Skip to main content

Overview

The Satori protocol integration (@proj-airi/satori-bot) provides a universal adapter that allows AIRI to connect to multiple chat platforms through a single, unified interface. Instead of creating separate bots for each platform, you can use Satori adapters to support:
  • QQ
  • WeChat
  • Line
  • WhatsApp
  • Discord (via Satori)
  • Telegram (via Satori)
  • And any other platform with a Satori adapter

What is Satori?

Satori is a cross-platform messaging protocol that provides a unified API for interacting with different chat platforms. It acts as a bridge between AIRI and various messaging services, translating platform-specific APIs into a common format.

Architecture

The Satori bot:
  1. Connects to AIRI’s server runtime via WebSocket
  2. Connects to a Satori server via WebSocket
  3. Translates messages between AIRI and Satori formats
  4. Handles multi-platform message routing

Prerequisites

  • AIRI server runtime running
  • Satori server set up and running
  • Satori adapters configured for your target platforms
  • Node.js 18+ and pnpm installed

Setup

1. Install Dependencies

cd services/satori-bot
pnpm install

2. Configure Environment

Create a .env.local file:
# Satori WebSocket connection
SATORI_WS_URL=ws://localhost:5500
SATORI_TOKEN=your-satori-token

# AIRI Server Runtime connection
AIRI_SERVER_URL=ws://localhost:6121/ws
AIRI_SERVER_TOKEN=your-airi-token

# Bot configuration
BOT_NAME=airi-satori
BOT_SELF_ID=your-bot-id

# Optional: LLM provider for direct responses
OPENAI_API_KEY=sk-...
OPENAI_MODEL=gpt-4-turbo-preview

3. Start the Bot

pnpm dev
This starts the bot with hot reload enabled.

4. Verify Connection

Check the logs for successful connections:
[Satori Bot] Connected to AIRI server at ws://localhost:6121/ws
[Satori Bot] Connected to Satori server at ws://localhost:5500
[Satori Bot] Ready to receive messages

Message Flow

Incoming Messages (User → AIRI)

  1. User sends message on platform (e.g., QQ)
  2. Satori adapter captures message
  3. Satori server forwards to Satori bot
  4. Satori bot translates to AIRI format
  5. Message sent to AIRI server runtime
  6. AIRI processes and generates response

Outgoing Messages (AIRI → User)

  1. AIRI generates response
  2. Server runtime sends to Satori bot
  3. Satori bot translates to Satori format
  4. Message sent to Satori server
  5. Satori adapter forwards to platform
  6. User receives message

Configuration Options

Adapter Configuration

Edit src/adapter/config.ts to customize:
export const config = {
  // Maximum message length before splitting
  maxMessageLength: 2000,
  
  // Retry configuration
  maxRetries: 3,
  retryDelay: 1000,
  
  // Message rate limiting
  rateLimit: {
    messages: 30,
    window: 60000 // 1 minute
  },
  
  // Platform-specific settings
  platforms: {
    qq: {
      enabled: true,
      features: ['text', 'image', 'at']
    },
    wechat: {
      enabled: true,
      features: ['text', 'image']
    }
  }
}

Capabilities

The Satori bot supports various message capabilities:
Basic text messages with formatting support.
// Markdown to platform-specific formatting
const formatted = await adapter.formatMessage({
  text: "**Bold** and *italic* text",
  platform: "qq"
})
User mentions are automatically translated.
// AIRI mentions user
{
  type: 'text',
  text: '@user123 Hello!'
}
Image attachments are forwarded with URL or base64 data.
{
  type: 'image',
  url: 'https://example.com/image.jpg'
}
Reply context is preserved across platforms.
{
  type: 'text',
  text: 'Response',
  quote: originalMessageId
}

Platform-Specific Features

QQ Integration

QQ-specific features supported:
  • Text messages with CQ codes
  • Image and file sharing
  • Group @mentions
  • Red packet notifications
  • Group member join/leave events

WeChat Integration

WeChat-specific features:
  • Text and rich media messages
  • Contact cards
  • Mini-program messages (view only)
  • Moments/timeline posts (if adapter supports)

Line Integration

Line-specific features:
  • Stickers and emojis
  • Image carousels
  • Quick reply buttons
  • Flex messages (template support)

Event Handling

The Satori bot listens for various events:
// Message events
on('message.created', handler)
on('message.deleted', handler)

// User events  
on('user.joined', handler)
on('user.left', handler)

// Guild/Group events
on('guild.updated', handler)
on('channel.created', handler)

Troubleshooting

Check:
  • Satori server is running and accessible
  • SATORI_WS_URL is correct
  • Firewall allows WebSocket connections
  • Token is valid and has required permissions
Debug:
# Test Satori server connection
wscat -c ws://localhost:5500
Check:
  • Bot has joined the target group/channel
  • Bot has read permissions
  • Message filters are not blocking content
  • Adapter is properly configured
Debug: Enable verbose logging:
DEBUG=satori:* pnpm dev
Check:
  • Bot has send permissions
  • Message format is valid for platform
  • Rate limits not exceeded
  • AIRI server runtime is reachable
Debug: Check message queue:
console.log(adapter.pendingMessages)
Check:
  • Adapter version supports the feature
  • Platform API version is compatible
  • Feature flag is enabled in config
Solution: Update Satori adapters:
pnpm update @satori/*

Advanced Usage

Custom Message Processors

Add custom message processing:
// src/core/processors/custom.ts
export class CustomProcessor {
  async process(message: Message): Promise<Message> {
    // Transform message before sending to AIRI
    if (message.text.startsWith('/command')) {
      return this.handleCommand(message)
    }
    return message
  }
}

Multi-Bot Setup

Run multiple Satori bots for different accounts:
# Bot 1
BOT_NAME=airi-qq BOT_SELF_ID=123 pnpm start

# Bot 2  
BOT_NAME=airi-wechat BOT_SELF_ID=456 pnpm start

Custom Adapters

Create platform-specific adapters:
// src/adapter/custom-platform.ts
import { BaseAdapter } from './base'

export class CustomPlatformAdapter extends BaseAdapter {
  async sendMessage(message: Message): Promise<void> {
    // Platform-specific sending logic
  }
  
  async receiveMessage(raw: any): Promise<Message> {
    // Platform-specific parsing logic
  }
}

Performance Considerations

  • Connection pooling: Reuse WebSocket connections
  • Message batching: Combine rapid messages when possible
  • Rate limiting: Respect platform limits to avoid blocks
  • Memory management: Clear old message cache periodically

Security

Keep your Satori token and platform credentials secure. Never commit them to version control.
Best practices:
  • Use environment variables for sensitive data
  • Rotate tokens periodically
  • Limit bot permissions to minimum required
  • Monitor for suspicious activity
  • Use HTTPS/WSS for production deployments

Next Steps

Satori Documentation

Learn more about the Satori protocol

Server Runtime API

Understand AIRI’s integration architecture

Discord Integration

Alternative Discord-specific integration

Telegram Integration

Alternative Telegram-specific integration

Build docs developers (and LLMs) love