OpenClaw is an open-source autonomous AI agent framework with over 200K GitHub stars. It connects to LLMs like Claude, GPT, or DeepSeek and executes multi-step tasks through messaging platforms. By connecting OpenClaw to InstantDM's webhook system, you can build a fully autonomous Instagram DM agent that qualifies leads, answers questions, books appointments, and manages customer conversations - all running locally on your machine with the LLM of your choice.
Why OpenClaw for Instagram DMs?
| Advantage | Details |
|---|---|
| Any LLM backend | Use Claude, GPT-4o, DeepSeek, or local models via Ollama |
| Skills system | Modular skills for product lookup, CRM sync, appointment booking |
| Runs locally | Your data stays on your machine |
| Open source (MIT) | Full control, no vendor lock-in |
| Multi-platform | Same agent handles Telegram, WhatsApp, Discord, and now Instagram DMs |
| Persistent memory | Conversation history stored locally across sessions |
Architecture
Instagram User sends DM
|
v
InstantDM (receives via Meta Graph API)
|
v Webhook POST
Bridge Server (Node.js/Python)
|
v Forwards to OpenClaw
OpenClaw Agent (local)
|
v Calls LLM (Claude/GPT/DeepSeek)
LLM generates response
|
v
OpenClaw returns reply to Bridge
|
v InstantDM API
InstantDM delivers reply as Instagram DM
The bridge server sits between InstantDM and OpenClaw, translating webhook events into OpenClaw messages and sending replies back through the InstantDM API.
What You Need
| Requirement | Details |
|---|---|
| InstantDM account | Trendsetter plan or higher (API access) |
| InstantDM API key | Settings > API |
| OpenClaw installed | github.com/openclaw/openclaw |
| LLM API key | Anthropic (Claude), OpenAI (GPT), or DeepSeek |
| Node.js 18+ | For the bridge server |
Step 1: Install and Configure OpenClaw
# Clone OpenClaw
git clone https://github.com/openclaw/openclaw.git
cd openclaw
# Install dependencies
npm install
# Configure your LLM provider
cp .env.example .env
Edit .env with your LLM provider:
# For Claude (recommended)
ANTHROPIC_API_KEY=sk-ant-your-key-here
DEFAULT_MODEL=claude-sonnet-4-20250514
# Or for OpenAI
# OPENAI_API_KEY=sk-your-key-here
# DEFAULT_MODEL=gpt-4o
# Or for DeepSeek
# DEEPSEEK_API_KEY=your-key-here
# DEFAULT_MODEL=deepseek-chat
Step 2: Create an Instagram DM Skill
OpenClaw uses a skills system where each skill is a directory with a SKILL.md file. Create a skill for handling Instagram DMs:
mkdir -p skills/instagram-dm-agent
Create skills/instagram-dm-agent/SKILL.md:
# Instagram DM Agent
You are an Instagram DM customer support agent for [Your Brand].
## Instructions
- Respond to customer questions about products, pricing, shipping, and returns
- Keep responses under 280 characters (Instagram DM best practice)
- Be friendly and conversational, not corporate
- Never make up product information or pricing
- If you cannot help, offer to connect them with a human team member
- Do not use markdown formatting (Instagram does not render it)
- Qualify leads by understanding their needs and budget
## Product Information
[Add your product catalog, pricing, FAQs here]
## Lead Qualification
When a potential customer shows buying intent:
1. Understand what they are looking for
2. Ask about their timeline
3. Share relevant product links
4. Offer to book a consultation if appropriate
## Escalation Rules
Escalate to a human when:
- Customer is angry or frustrated
- Question requires account-specific information
- Customer explicitly asks for a human
- Topic involves refunds or disputes
Step 3: Build the Bridge Server
This Node.js server receives InstantDM webhooks and routes them to OpenClaw, then sends OpenClaw's responses back via the InstantDM API.
const express = require('express');
const crypto = require('crypto');
const { spawn } = require('child_process');
const app = express();
app.use(express.json());
const INSTANTDM_API_KEY = process.env.INSTANTDM_API_KEY;
const OPENCLAW_PATH = process.env.OPENCLAW_PATH || './openclaw';
// Track active OpenClaw conversations
const sessions = new Map();
function verifySignature(req) {
const sig = req.headers['x-webhook-signature'];
if (!sig) return false;
const expected = crypto
.createHmac('sha256', INSTANTDM_API_KEY)
.update(JSON.stringify(req.body))
.digest('hex');
return crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected));
}
app.post('/webhook/instantdm', async (req, res) => {
res.status(200).json({ received: true });
if (!verifySignature(req)) return;
const { event, data } = req.body;
if (event === 'dm_received') {
await handleDM(data);
}
});
async function handleDM(data) {
const { instagram_user_id, username, message_text } = data;
try {
// Send message to OpenClaw and get response
const reply = await sendToOpenClaw(instagram_user_id, message_text);
// Send reply back via InstantDM
await sendReply(instagram_user_id, reply);
} catch (err) {
console.error('OpenClaw error:', err);
await sendReply(instagram_user_id,
"Hey! Quick technical issue. A team member will follow up soon."
);
}
}
async function sendToOpenClaw(userId, message) {
return new Promise((resolve, reject) => {
// Use OpenClaw CLI to process the message
const proc = spawn('node', [
`${OPENCLAW_PATH}/index.js`,
'--skill', 'instagram-dm-agent',
'--session', `ig-${userId}`,
'--message', message,
'--format', 'text',
]);
let output = '';
let error = '';
proc.stdout.on('data', (data) => { output += data.toString(); });
proc.stderr.on('data', (data) => { error += data.toString(); });
proc.on('close', (code) => {
if (code !== 0) {
reject(new Error(`OpenClaw exited with code ${code}: ${error}`));
} else {
resolve(output.trim());
}
});
// Timeout after 30 seconds
setTimeout(() => {
proc.kill();
reject(new Error('OpenClaw timeout'));
}, 30000);
});
}
async function sendReply(recipientId, text) {
// Clean up for Instagram
if (text.length > 1000) text = text.substring(0, 997) + '...';
text = text.replace(/[*_~`#]/g, '');
const res = await fetch('https://api.instantdm.com/api-webhook', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${INSTANTDM_API_KEY}`,
},
body: JSON.stringify({
action: 'send_message',
type: 'dm',
recipient_id: recipientId,
message: { type: 'text', text: text.trim() },
}),
});
if (!res.ok) throw new Error(`InstantDM API error: ${res.status}`);
}
app.listen(3000, () => console.log('OpenClaw Instagram bridge running on port 3000'));
Step 4: Alternative - OpenClaw HTTP API Bridge
If you prefer using OpenClaw's HTTP API mode instead of the CLI, you can run OpenClaw as a server and communicate via HTTP:
const OPENCLAW_API = 'http://localhost:3001'; // OpenClaw API server
async function sendToOpenClaw(userId, message) {
const response = await fetch(`${OPENCLAW_API}/api/chat`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
session_id: `ig-${userId}`,
skill: 'instagram-dm-agent',
message: message,
}),
});
if (!response.ok) {
throw new Error(`OpenClaw API error: ${response.status}`);
}
const data = await response.json();
return data.reply;
}
Start OpenClaw in API mode:
cd openclaw
node index.js --serve --port 3001
Step 5: Add Custom Skills for Instagram Use Cases
Product Lookup Skill
Create skills/product-lookup/SKILL.md:
# Product Lookup
When a user asks about a product, search the catalog and return details.
## Tools
- search_products: Search by name, category, or keyword
- check_stock: Check availability for a specific product and size
## Response Format
Return product name, price, available sizes, and a direct link.
Keep the response under 280 characters.
Appointment Booking Skill
Create skills/book-appointment/SKILL.md:
# Appointment Booking
Help users book consultations or demos.
## Steps
1. Ask what they need help with
2. Suggest available time slots
3. Collect their name and email
4. Confirm the booking
## Tools
- get_available_slots: Returns open calendar slots
- create_booking: Books an appointment
Step 6: Connect OpenClaw to Your CRM
OpenClaw can sync lead data to your CRM as part of the conversation flow. Add a CRM skill:
# CRM Sync
After qualifying a lead, save their information to the CRM.
## Tools
- create_lead: Create a new lead in HubSpot/Salesforce
- update_lead: Update existing lead with new information
- tag_lead: Add tags based on conversation outcome (hot/warm/cold)
The bridge server can also fire webhooks to your CRM directly:
async function onLeadQualified(userId, leadData) {
// Tag the contact in InstantDM
await fetch('https://api.instantdm.com/api-webhook', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${INSTANTDM_API_KEY}`,
},
body: JSON.stringify({
action: 'tag_contact',
recipient_id: userId,
tags: [leadData.score, leadData.interest],
}),
});
// Send to your CRM webhook
await fetch('https://your-crm-webhook.com/leads', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
source: 'instagram_dm',
user_id: userId,
...leadData,
}),
});
}
LLM Recommendations for OpenClaw + Instagram
| Model | Best For | Cost |
|---|---|---|
| Claude Sonnet 4 | Best overall quality for DM conversations | ~$3/1K input, $15/1K output |
| GPT-4o-mini | High volume, cost-effective | ~$0.15/1M input |
| DeepSeek V3 | Budget option with good quality | ~$0.14/1M input |
| Hermes 3 8B (Ollama) | Free, self-hosted, full privacy | $0 (local GPU) |
Deployment
Run Locally (Development)
# Terminal 1: Start OpenClaw
cd openclaw && node index.js --serve --port 3001
# Terminal 2: Start the bridge server
INSTANTDM_API_KEY=your-key OPENCLAW_API=http://localhost:3001 node bridge.js
Deploy to Railway
# Push both OpenClaw and the bridge server to a repo
git push origin main
# Connect to Railway - it will detect the Node.js app
# Set environment variables in Railway dashboard:
# INSTANTDM_API_KEY, ANTHROPIC_API_KEY (or your LLM key)
Deploy to a VPS (DigitalOcean, Hetzner)
# Install Node.js and clone your repo
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo bash -
sudo apt install -y nodejs
git clone https://github.com/your-repo/openclaw-instagram-bridge.git
cd openclaw-instagram-bridge
npm install
# Run with PM2 for process management
npm install -g pm2
pm2 start bridge.js --name openclaw-bridge
pm2 start openclaw/index.js --name openclaw-agent -- --serve --port 3001
pm2 save
Troubleshooting
| Issue | Fix |
|---|---|
| OpenClaw not responding | Check if OpenClaw is running: curl http://localhost:3001/health |
| Slow responses | Use a faster LLM (GPT-4o-mini or Claude Haiku) |
| Skill not loading | Verify SKILL.md exists in the correct directory |
| Webhook not firing | Check InstantDM Settings > API for correct webhook URL |
| LLM rate limited | Add retry logic with exponential backoff in the bridge |
| Responses too long | Add character limit instructions to your SKILL.md |
What's Next
- Install OpenClaw and create your Instagram DM skill
- Deploy the bridge server with a public URL
- Test with real Instagram DMs
- Add product lookup and appointment booking skills
- Connect to your CRM with HubSpot or Salesforce
- Set up Slack notifications for human handoff alerts