- name
- openclaw-multi-channel-ai-assistant
- description
- Self-hosted multi-channel AI assistant platform with unified Gateway, supporting WhatsApp, Telegram, Discord, and 20+ chat platforms with Claude, GPT, DeepSeek integration
- triggers
- ["how do I set up OpenClaw with Telegram","configure OpenClaw gateway and channels","deploy OpenClaw AI assistant","connect OpenClaw to WhatsApp or Discord","OpenClaw agent configuration and tools","troubleshoot OpenClaw channel connection","setup OpenClaw with Claude or GPT","OpenClaw node and plugin system"]
# OpenClaw Multi-Channel AI Assistant
> Skill by [ara.so](https://ara.so) — Hermes Skills collection.
OpenClaw is a self-hosted multi-channel AI assistant platform that connects Web control UI, chat channels (WhatsApp, Telegram, Discord, Slack, Signal, Feishu, etc.), nodes, tools, and AI models through a unified Gateway architecture. This skill covers installation, configuration, channel setup, AI provider integration, plugin development, and troubleshooting.
## What OpenClaw Does
- **Unified Gateway**: Central control plane that routes messages between channels, nodes, and AI agents
- **Multi-Channel Support**: 20+ chat platforms including WhatsApp, Telegram, Discord, Slack, Signal, iMessage, Feishu, Teams, Matrix
- **Multi-Model Support**: Anthropic Claude, OpenAI GPT, DeepSeek, Qwen, Kimi, GLM, Ollama, and more
- **Tool System**: Browser automation, code execution, skills, sub-agents
- **Plugin Architecture**: Hooks, adapters, and extensible agent framework
- **Mobile Nodes**: Remote execution nodes for distributed AI workflows
- **Web UI**: Browser-based control panel for configuration and monitoring
## Installation
### Quick Start (Docker)
```bash
# Clone the repository
git clone https://github.com/openclaw/openclaw.git
cd openclaw
# Copy environment template
cp .env.example .env
# Edit .env with your configuration
# Required: OPENAI_API_KEY or ANTHROPIC_API_KEY
nano .env
# Start with Docker Compose
docker-compose up -d
# Access Web UI at http://localhost:3000
```
### Node.js Installation
```bash
# Prerequisites: Node.js 18+ and npm
git clone https://github.com/openclaw/openclaw.git
cd openclaw
# Install dependencies
npm install
# Configure environment
cp .env.example .env
# Edit .env with API keys and settings
# Start Gateway
npm run gateway:start
# Start Web UI (separate terminal)
npm run web:start
# Start a channel adapter (example: Telegram)
npm run channel:telegram
```
### Cloud Deployment
```bash
# Deploy to VPS (Ubuntu/Debian)
curl -fsSL https://get.openclaw.ai | bash
# Or use the official installer
wget https://github.com/openclaw/openclaw/releases/latest/download/install.sh
chmod +x install.sh
./install.sh
# Follow prompts to configure Gateway, channels, and models
```
## Core Architecture
### Gateway Configuration
The Gateway is the central hub. Configure in `config/gateway.yaml`:
```yaml
gateway:
host: 0.0.0.0
port: 3000
secret: ${GATEWAY_SECRET}
channels:
- type: telegram
enabled: true
token: ${TELEGRAM_BOT_TOKEN}
- type: whatsapp
enabled: true
provider: baileys # or twilio
- type: discord
enabled: true
token: ${DISCORD_BOT_TOKEN}
models:
- provider: anthropic
model: claude-3-5-sonnet-20241022
apiKey: ${ANTHROPIC_API_KEY}
- provider: openai
model: gpt-4-turbo
apiKey: ${OPENAI_API_KEY}
- provider: ollama
model: llama3
baseURL: http://localhost:11434
agent:
defaultModel: claude-3-5-sonnet-20241022
temperature: 0.7
maxTokens: 4096
contextWindow: 200000
memory:
provider: sqlite # or postgres, redis
retentionDays: 30
tools:
browser: true
codeExecution: false # requires sandboxed environment
webSearch: true
```
### Environment Variables
Create `.env` file:
```bash
# Gateway
GATEWAY_SECRET=your-secure-random-secret
GATEWAY_PORT=3000
# AI Providers
ANTHROPIC_API_KEY=sk-ant-xxxxx
OPENAI_API_KEY=sk-xxxxx
DEEPSEEK_API_KEY=sk-xxxxx
# Channels - Telegram
TELEGRAM_BOT_TOKEN=123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11
# Channels - Discord
DISCORD_BOT_TOKEN=MTk4NjIy...
# Channels - WhatsApp (Baileys)
WHATSAPP_SESSION_PATH=./sessions/whatsapp
# Database
DATABASE_URL=postgresql://user:pass@localhost:5432/openclaw
# or
DATABASE_URL=sqlite:./data/openclaw.db
# Memory
MEMORY_PROVIDER=sqlite
MEMORY_RETENTION_DAYS=30
# Tools
ENABLE_BROWSER_TOOL=true
ENABLE_CODE_EXECUTION=false
SEARXNG_URL=http://localhost:8080
```
## CLI Commands
### Gateway Management
```bash
# Start Gateway server
npm run gateway:start
# or
./openclaw gateway start
# Check Gateway status
./openclaw gateway status
# Reload configuration without restart
./openclaw gateway reload
# View Gateway logs
./openclaw gateway logs --tail 100
```
### Channel Management
```bash
# List available channels
./openclaw channels list
# Start a specific channel adapter
./openclaw channel start telegram
./openclaw channel start whatsapp
./openclaw channel start discord
# Stop a channel
./openclaw channel stop telegram
# Channel authentication (WhatsApp)
./openclaw channel auth whatsapp
# Scan QR code with WhatsApp mobile app
```
### Node Management
```bash
# Register a new node
./openclaw node register --name "mobile-node-1" --type mobile
# List active nodes
./openclaw node list
# Start a node
./openclaw node start mobile-node-1
# Node health check
./openclaw node health mobile-node-1
```
### Plugin Management
```bash
# List installed plugins
./openclaw plugin list
# Install a plugin
./openclaw plugin install @openclaw/plugin-calendar
# Create new plugin scaffold
./openclaw plugin create my-custom-plugin
# Enable/disable plugin
./openclaw plugin enable my-custom-plugin
./openclaw plugin disable my-custom-plugin
```
## Channel Adapter Implementation
### Creating a Custom Channel Adapter
```javascript
// plugins/channels/my-channel/index.js
import { ChannelAdapter } from '@openclaw/core';
export default class MyChannelAdapter extends ChannelAdapter {
constructor(config) {
super(config);
this.client = null;
}
async initialize() {
// Initialize your channel client
this.client = new MyChannelClient({
token: this.config.token,
apiUrl: this.config.apiUrl
});
// Set up incoming message handler
this.client.on('message', this.handleIncomingMessage.bind(this));
await this.client.connect();
this.logger.info('MyChannel adapter initialized');
}
async handleIncomingMessage(rawMessage) {
// Normalize to OpenClaw message format
const message = {
id: rawMessage.id,
channelType: 'my-channel',
channelUserId: rawMessage.sender.id,
text: rawMessage.content,
timestamp: rawMessage.timestamp,
metadata: {
chatId: rawMessage.chat.id,
messageType: rawMessage.type
}
};
// Route to Gateway for Agent processing
await this.routeToAgent(message);
}
async sendMessage(sessionKey, response) {
// Extract channel-specific routing info
const { chatId } = this.extractRoutingInfo(sessionKey);
// Send through channel API
await this.client.sendMessage({
chatId,
text: response.text,
attachments: response.attachments
});
}
async cleanup() {
if (this.client) {
await this.client.disconnect();
}
}
}
// Plugin manifest
export const manifest = {
name: 'my-channel',
version: '1.0.0',
type: 'channel-adapter',
requiredConfig: ['token'],
optionalConfig: ['apiUrl']
};
```
### Register Channel in Gateway
```javascript
// config/channels.js
import MyChannelAdapter from './plugins/channels/my-channel/index.js';
export const channelRegistry = {
telegram: TelegramAdapter,
whatsapp: WhatsAppAdapter,
discord: DiscordAdapter,
'my-channel': MyChannelAdapter
};
```
## Agent Configuration & Tools
### Custom Agent Prompt
```javascript
// config/agent.js
export const agentConfig = {
systemPrompt: `You are a helpful AI assistant with access to various tools.
Available tools:
- browser: Navigate websites and extract information
- webSearch: Search the internet using SearXNG
- executeCode: Run Python code (sandboxed)
Guidelines:
- Be concise but helpful
- Always cite sources when using web search
- Ask for confirmation before executing code
- Respect user privacy`,
model: 'claude-3-5-sonnet-20241022',
temperature: 0.7,
maxTokens: 4096,
// Tool configuration
tools: {
browser: {
enabled: true,
timeout: 30000,
userAgent: 'OpenClaw/1.0'
},
webSearch: {
enabled: true,
searxngUrl: process.env.SEARXNG_URL,
maxResults: 5
},
codeExecution: {
enabled: false, // Requires secure sandbox
languages: ['python', 'javascript'],
timeout: 10000
}
},
// Memory configuration
memory: {
enabled: true,
contextWindow: 50, // Last 50 messages
summarization: true,
summaryThreshold: 30
}
};
```
### Implementing a Custom Tool
```javascript
// plugins/tools/weather-tool.js
import { Tool } from '@openclaw/core';
export default class WeatherTool extends Tool {
constructor() {
super({
name: 'getWeather',
description: 'Get current weather for a location',
parameters: {
type: 'object',
properties: {
location: {
type: 'string',
description: 'City name or coordinates'
},
units: {
type: 'string',
enum: ['metric', 'imperial'],
default: 'metric'
}
},
required: ['location']
}
});
}
async execute({ location, units = 'metric' }) {
const apiKey = process.env.WEATHER_API_KEY;
const response = await fetch(
`https://api.openweathermap.org/data/2.5/weather?q=${location}&units=${units}&appid=${apiKey}`
);
if (!response.ok) {
throw new Error(`Weather API error: ${response.statusText}`);
}
const data = await response.json();
return {
location: data.name,
temperature: data.main.temp,
condition: data.weather[0].description,
humidity: data.main.humidity,
units
};
}
}
// Register tool
import { registerTool } from '@openclaw/core';
registerTool(new WeatherTool());
```
### Agent with Tool Usage
```javascript
// Example: Agent processing with tool invocation
import { Agent } from '@openclaw/core';
const agent = new Agent({
model: 'claude-3-5-sonnet-20241022',
apiKey: process.env.ANTHROPIC_API_KEY,
tools: ['getWeather', 'webSearch', 'browser']
});
async function processUserMessage(message, sessionKey) {
// Load conversation context
const context = await agent.getContext(sessionKey);
// Process with tool support
const response = await agent.process({
messages: [...context, { role: 'user', content: message }],
sessionKey,
toolChoice: 'auto' // Let agent decide when to use tools
});
// Response includes tool calls if any were made
if (response.toolCalls) {
console.log('Tools used:', response.toolCalls.map(t => t.name));
}
// Save to memory
await agent.saveContext(sessionKey, response);
return response.content;
}
```
## Session & Context Management
### Session Key Format
OpenClaw uses session keys to route conversations:
```javascript
// Format: channel:channelUserId:chatId
const sessionKey = 'telegram:123456789:987654321';
const sessionKey = 'whatsapp:+1234567890:group123';
const sessionKey = 'discord:user123:channel456';
// Parse session key
function parseSessionKey(sessionKey) {
const [channel, userId, chatId] = sessionKey.split(':');
return { channel, userId, chatId };
}
// Create session key
function createSessionKey(channel, userId, chatId) {
return `${channel}:${userId}:${chatId || userId}`;
}
```
### Context Window Management
```javascript
// services/context-manager.js
import { ContextManager } from '@openclaw/core';
const contextManager = new ContextManager({
provider: 'sqlite',
dbPath: './data/context.db',
maxMessages: 50,
summarizationThreshold: 30
});
// Store message
await contextManager.addMessage(sessionKey, {
role: 'user',
content: 'What is the weather in Tokyo?',
timestamp: Date.now()
});
// Retrieve context with automatic summarization
const context = await contextManager.getContext(sessionKey, {
maxTokens: 4000, // Token budget for context
includeSummary: true
});
// Manual context pruning
await contextManager.pruneContext(sessionKey, {
keepLast: 20,
summarizeRest: true
});
// Clear context for session
await contextManager.clearContext(sessionKey);
```
## Plugin Development
### Plugin Hook System
```javascript
// plugins/my-plugin/index.js
export default class MyPlugin {
constructor(core) {
this.core = core;
}
// Hook: Before message is sent to agent
async onBeforeAgentProcess(message, context) {
console.log('Processing message:', message.text);
// Modify message or context
if (message.text.includes('urgent')) {
Ver no GitHub