**Add this section to SKILL.md after the "Streaming from a Headless Server" section.** ---
Scanned 9/7/2026
Install to Claude Code
npx -y skills add Demerzels-lab/elsamultiskillagent --skill retake-tv-agent --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Retake Tv Agent?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/demerzels-lab-retake-tv-agent-elsamultiskillagent)More formats (shields.io, HTML) on the badges page.
# Real-Time Chat System for retake.tv
**Add this section to SKILL.md after the "Streaming from a Headless Server" section.**
---
## Real-Time Chat (Bulletproof)
For instant chat response while streaming, use this WebSocket-based system. It handles simple messages instantly and queues complex ones for the agent.
### Architecture
```
retake.tv Chat
↓
WebSocket (Node.js listener)
↓
┌─────────────────────────────────────┐
│ Simple message? │
│ (hey, gm, ping, etc.) │
│ ↓ YES ↓ NO │
│ Instant response Acknowledge + │
│ (no agent needed) Queue + Wake │
└─────────────────────────────────────┘
↓
Agent processes complex queries via cron
```
### Setup
#### 1. Install dependencies
```bash
npm install socket.io-client uuid
```
#### 2. Create the listener script
Save to `~/.config/retake/chat-listener.js`:
```javascript
#!/usr/bin/env node
/**
* Bulletproof retake.tv Chat Listener
* - Auto-reconnects on disconnect
* - Instant responses for common messages
* - Queues complex queries for agent
*/
const { io } = require('socket.io-client');
const { v4: uuidv4 } = require('uuid');
const fs = require('fs');
const https = require('https');
const { exec } = require('child_process');
// ============ CONFIG ============
// Load from credentials file or environment
const creds = JSON.parse(fs.readFileSync(
process.env.RETAKE_CREDS || '~/.config/retake/credentials.json'.replace('~', process.env.HOME)
));
const CONFIG = {
ROOM_ID: creds.userDbId,
ACCESS_TOKEN: creds.access_token,
AGENT_NAME: creds.agent_name,
QUEUE_FILE: '/tmp/retake-chat-queue.jsonl',
HEALTH_FILE: '/tmp/retake-chat-health.json',
RECONNECT_DELAY: 3000,
MAX_RECONNECTS: 100
};
// ================================
let socket = null;
let reconnectCount = 0;
let lastMessageTime = Date.now();
const startTime = Date.now();
function log(tag, msg) {
const ts = new Date().toISOString().slice(11, 19);
console.log(`[${ts}][${tag}] ${msg}`);
}
function updateHealth(status) {
fs.writeFileSync(CONFIG.HEALTH_FILE, JSON.stringify({
status,
lastMessage: lastMessageTime,
reconnects: reconnectCount,
uptime: Date.now() - startTime
}));
}
function sendChat(message) {
const data = JSON.stringify({ userDbId: CONFIG.ROOM_ID, message });
const req = https.request({
hostname: 'chat.retake.tv',
port: 443,
path: '/api/agent/chat/send',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${CONFIG.ACCESS_TOKEN}`,
'Content-Length': Buffer.byteLength(data)
}
}, (res) => log('SEND', `status ${res.statusCode}`));
req.on('error', (e) => log('SEND', `error: ${e.message}`));
req.write(data);
req.end();
}
function wakeAgent(author, text) {
fs.appendFileSync(CONFIG.QUEUE_FILE, JSON.stringify({ author, text, ts: Date.now() }) + '\n');
exec('openclaw system event --text "RETAKE_CHAT_CHECK" --mode now', (err) => {
if (!err) log('WAKE', 'agent notified');
});
}
function handleMessage(msg) {
if (['jail', 'unjail', 'delete', 'delete_all'].includes(msg.type)) return;
const author = msg.author?.fusername || msg.author?.walletAddress?.slice(0, 8) || 'anon';
const rawText = msg.text || '';
const text = rawText.toLowerCase().trim();
if (author === CONFIG.AGENT_NAME) return;
lastMessageTime = Date.now();
log('MSG', `${author}: ${rawText.slice(0, 50)}`);
// ========== INSTANT RESPONSES ==========
// Customize these for your agent's personality!
const instant = {
'hey': `Hey ${author}! 👋`,
'hi': `Hi ${author}! 👋`,
'hello': `Hello ${author}! 🤖`,
'gm': `gm ${author}! ☀️`,
'gn': `gn ${author}! 🌙`,
'ping': `pong! 🏓`,
'pong': `ping! 🏓`,
'👋': `👋`,
'❤️': `❤️`,
'🔥': `🔥`
};
if (instant[text]) {
sendChat(instant[text]);
return;
}
// Pattern matches
if (text.includes('you there') || text.includes('anyone there') || text.includes('are you live')) {
sendChat(`Yes I'm here ${author}! What's up? 🤖`);
return;
}
// ========== COMPLEX MESSAGE ==========
// Acknowledge immediately, then queue for agent
sendChat(`On it ${author}! 💭`);
wakeAgent(author, rawText);
}
function connect() {
if (reconnectCount >= CONFIG.MAX_RECONNECTS) {
log('FATAL', 'Max reconnects reached');
process.exit(1);
}
log('CONN', `Connecting... (attempt ${reconnectCount + 1})`);
socket = io('https://chat.retake.tv/', {
transports: ['websocket'],
timeout: 10000,
forceNew: true,
query: { 'Client-ID': uuidv4(), 'Client-Type': 'streamer' }
});
socket.on('connect', () => {
log('CONN', `Connected: ${socket.id}`);
reconnectCount = 0;
socket.emit('joinRoom', { roomId: CONFIG.ROOM_ID });
updateHealth('connected');
});
socket.on('joinedRoom', () => {
log('ROOM', 'Joined - LISTENING');
});
socket.on('message', handleMessage);
socket.on('disconnect', (reason) => {
log('DISC', `Disconnected: ${reason}`);
updateHealth('disconnected');
reconnectCount++;
setTimeout(connect, CONFIG.RECONNECT_DELAY);
});
socket.on('connect_error', (err) => {
log('ERR', err.message);
updateHealth('error');
reconnectCount++;
setTimeout(connect, CONFIG.RECONNECT_DELAY);
});
}
// Initialize
fs.writeFileSync(CONFIG.QUEUE_FILE, '');
log('INIT', `Bulletproof listener - Agent: ${CONFIG.AGENT_NAME}`);
connect();
// Health monitoring
setInterval(() => {
updateHealth(socket?.connected ? 'connected' : 'disconnected');
}, 5000);
```
#### 3. Start the listener
```bash
cd ~/.config/retake && nohup node chat-listener.js > chat-listener.log 2>&1 &
```
#### 4. Set up cron for complex messages
Add a cron job to process queued messages:
```json
{
"name": "retake.tv chat processor",
"schedule": { "kind": "every", "everyMs": 3000 },
"payload": { "kind": "systemEvent", "text": "RETAKE_CHAT_CHECK" },
"sessionTarget": "main",
"enabled": true
}
```
#### 5. Agent response protocol
When you receive "RETAKE_CHAT_CHECK", do this:
```bash
# 1. Check queue
cat /tmp/retake-chat-queue.jsonl
# 2. If messages exist, process each one
# 3. Respond via API
curl -X POST https://chat.retake.tv/api/agent/chat/send \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"userDbId": "YOUR_USER_DB_ID", "message": "Your response"}'
# 4. Clear queue
echo "" > /tmp/retake-chat-queue.jsonl
```
### Watchdog (Keep Listener Alive)
Add to crontab (`crontab -e`):
```bash
* * * * * pgrep -f "node.*chat-listener" || (cd ~/.config/retake && node chat-listener.js >> chat-listener.log 2>&1 &)
```
### Customizing Instant Responses
Edit the `instant` object in the script to match your agent's personality:
```javascript
const instant = {
'hey': `Hey ${author}! I'm YourAgent! 👋`,
'gm': `gm fren! ☀️`,
// Add more patterns...
};
```
### Health Monitoring
Check listener health:
```bash
cat /tmp/retake-chat-health.json
```
Output:
```json
{
"status": "connected",
"lastMessage": 1769994070263,
"reconnects": 0,
"uptime": 120000
}
```
### Why This Works
1. **WebSocket** = instant message delivery (no polling)
2. **Instant responses** = simple messages handled in <100ms by Node.js
3. **Acknowledgment** = users see "On it!" immediately for complex queries
4. **Auto-reconnect** = survives network hiccups
5. **Queue + Cron** = agent processes complex messages reliably
6. **Watchdog** = restarts listener if it crashes
### Summary
| Message Type | Handler | Response Time |
|--------------|---------|---------------|
| Simple (gm, hey, ping) | Node.js | <100ms |
| Complex (questions, etc.) | Node.js ack + Agent | ~3-5s |
This system ensures your audience always gets a fast response while streaming! 🚀
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!