← back to Designer Wallcoverings

DW-Agents/dw-agents/HOOKS-API-INTEGRATION-GUIDE.md

594 lines

# DW-Agents Hooks API Integration Guide

## Overview

The `shared-hooks-api.ts` module provides a unified interface for all DW-Agents to execute DW-MCP hooks without code duplication. This module centralizes hook execution, error handling, and provides both REST API endpoints and programmatic access.

## Quick Start

### 1. Basic Integration (REST API)

Add to any agent's server setup:

```typescript
import express from 'express';
import { setupHooksAPI } from '../shared-hooks-api';

const app = express();
app.use(express.json());

// Add hooks API endpoints
setupHooksAPI(app);

// Your agent's routes...
app.get('/', (req, res) => {
  res.send('My Agent Dashboard');
});

app.listen(3000);
```

This automatically creates the following endpoints:
- `GET /api/hooks` - List all available hooks
- `GET /api/hooks/:hookName` - Get info about specific hook
- `POST /api/hooks/:hookName` - Execute a hook

### 2. Programmatic Integration

Execute hooks directly from your agent code:

```typescript
import { executeHook, hooks } from '../shared-hooks-api';

// Direct execution
const result = await executeHook('gmail', 'send test@example.com "Subject" "Body"');

if (result.success) {
  console.log('Email sent:', result.output);
} else {
  console.error('Failed:', result.error);
}

// Using convenience wrappers
await hooks.gmail.send('test@example.com', 'Subject', 'Body');
await hooks.slack.send('general', 'Hello team!');
await hooks.twilio.sms('+12125551234', 'Your order shipped');
```

### 3. Type-Safe Client

For TypeScript projects with full type safety:

```typescript
import { HooksClient } from '../shared-hooks-api';

const hooksClient = new HooksClient(60000); // 60s timeout

// Type-safe method calls
await hooksClient.gmail('send', 'test@example.com', 'Subject', 'Body');
await hooksClient.slack('send', 'general', 'Hello');
await hooksClient.healthCheck('web');
await hooksClient.processOrder('12345678');
await hooksClient.notifyError('critical', 'Database down');
```

## API Endpoints

### List All Hooks

```bash
GET /api/hooks
```

**Response:**
```json
{
  "success": true,
  "hooks": {
    "gmail": {
      "description": "Gmail API operations (send, read, search)",
      "examples": ["send test@example.com \"Subject\" \"Body\""]
    },
    "slack": {
      "description": "Slack messaging and channel operations",
      "examples": ["send general \"Hello team\""]
    }
    // ... more hooks
  },
  "usage": {
    "endpoint": "POST /api/hooks/:hookName",
    "body": {
      "action": "string (optional)",
      "params": "object (optional)"
    }
  }
}
```

### Get Hook Info

```bash
GET /api/hooks/gmail
```

**Response:**
```json
{
  "success": true,
  "hook": "gmail",
  "info": {
    "description": "Gmail API operations (send, read, search)",
    "examples": [
      "send test@example.com \"Subject\" \"Body\"",
      "read 5",
      "search \"from:boss@company.com\""
    ]
  }
}
```

### Execute Hook (Action String)

```bash
POST /api/hooks/gmail
Content-Type: application/json

{
  "action": "send test@example.com \"New Order\" \"Order #12345 received\""
}
```

**Response:**
```json
{
  "success": true,
  "output": "Email sent successfully to test@example.com",
  "timestamp": "2025-11-12T20:30:00.000Z",
  "hookName": "gmail",
  "executionTime": 1234
}
```

### Execute Hook (Params Object)

```bash
POST /api/hooks/slack
Content-Type: application/json

{
  "params": {
    "channel": "general",
    "message": "New deployment complete!"
  }
}
```

**Response:**
```json
{
  "success": true,
  "output": "Message sent to #general",
  "timestamp": "2025-11-12T20:30:00.000Z",
  "hookName": "slack",
  "executionTime": 567
}
```

### Error Response

```json
{
  "success": false,
  "error": "Hook execution failed: Connection timeout",
  "timestamp": "2025-11-12T20:30:00.000Z",
  "hookName": "gmail",
  "executionTime": 60000
}
```

## Available Hooks

### Communication Hooks

| Hook | Description | Examples |
|------|-------------|----------|
| `gmail` | Gmail operations | `send`, `read`, `search` |
| `slack` | Slack messaging | `send`, `list-channels` |
| `twilio` | SMS and voice | `sms`, `call` |
| `calendar` | Google Calendar | `list`, `create` |

### Service Hooks

| Hook | Description | Examples |
|------|-------------|----------|
| `shopify` | Shopify operations | `list-orders`, `get-product` |
| `weather` | Weather data | `current`, `forecast` |

### Monitoring Hooks

| Hook | Description | Examples |
|------|-------------|----------|
| `service-health-check` | Service health | `web`, `gmail`, `slack` |
| `agent-health-monitor` | Agent monitoring | `check`, `restart`, `status` |

### Processing Hooks

| Hook | Description | Examples |
|------|-------------|----------|
| `order-processing` | Process orders | Order ID |
| `product-import-pipeline` | Import products | `import`, `validate` |

### System Hooks

| Hook | Description | Examples |
|------|-------------|----------|
| `error-notification` | Error alerts | `critical`, `high` |
| `mcp-server-startup` | Startup validation | Service name |
| `pre-commit-env-check` | Env validation | - |
| `post-deployment-health-check` | Post-deploy checks | - |

### Chat System Hooks

| Hook | Description | Examples |
|------|-------------|----------|
| `inter-agent-chat` | Inter-agent comms | `send`, `broadcast` |
| `chat-verification-and-logging` | Chat logging | `verify`, `log-stats` |

## Real-World Examples

### Example 1: Marketing Agent with Automated Notifications

```typescript
import express from 'express';
import { setupHooksAPI, hooks } from '../shared-hooks-api';

const app = express();
app.use(express.json());

// Setup hooks API
setupHooksAPI(app);

// Custom route that uses hooks
app.post('/api/campaigns/launch', async (req, res) => {
  const { campaignName, targetAudience } = req.body;

  try {
    // Notify team via Slack
    await hooks.slack.send('marketing',
      `New campaign launched: ${campaignName} targeting ${targetAudience}`
    );

    // Send summary email
    await hooks.gmail.send(
      'team@company.com',
      `Campaign Launched: ${campaignName}`,
      `Campaign ${campaignName} is now live. Target audience: ${targetAudience}`
    );

    // Log to inter-agent chat
    await hooks.execute('inter-agent-chat',
      `send agent-executive-ceo "New marketing campaign: ${campaignName}"`
    );

    res.json({ success: true, message: 'Campaign launched and notifications sent' });
  } catch (error) {
    // Notify error
    await hooks.errors.notify('high', `Campaign launch failed: ${error.message}`);
    res.status(500).json({ success: false, error: error.message });
  }
});

app.listen(9800);
```

### Example 2: Server Uptime Agent with Health Monitoring

```typescript
import { setupHooksAPI, HooksClient } from '../shared-hooks-api';

const app = express();
const hooksClient = new HooksClient();

setupHooksAPI(app);

// Monitor all services every 5 minutes
setInterval(async () => {
  const services = ['web', 'gmail', 'slack', 'shopify'];

  for (const service of services) {
    const result = await hooksClient.healthCheck(service);

    if (!result.success) {
      // Service is down, notify immediately
      await hooksClient.notifyError('critical',
        `Service ${service} is down: ${result.error}`
      );

      // Notify via Slack
      await hooksClient.slack('send', 'critical-alerts',
        `CRITICAL: ${service} service is not responding`
      );

      // Notify via SMS
      await hooksClient.twilio('sms', '+12125551234',
        `ALERT: ${service} service down`
      );
    }
  }
}, 5 * 60 * 1000);

app.listen(9888);
```

### Example 3: E-commerce Agent with Order Processing

```typescript
import { setupHooksAPI, executeHook } from '../shared-hooks-api';

const app = express();
setupHooksAPI(app);

// Shopify webhook handler
app.post('/webhooks/shopify/order/created', async (req, res) => {
  const order = req.body;

  try {
    // Process order through hook (validation, enrichment, notifications)
    const result = await executeHook('order-processing', order.id);

    if (result.success) {
      console.log('Order processed:', result.output);

      // High-value order? Notify sales team
      if (order.total_price >= 500) {
        await executeHook('slack',
          `send high-value-orders "New order: $${order.total_price} from ${order.customer.email}"`
        );

        await executeHook('gmail',
          `send sales@company.com "High-Value Order Alert" "Order #${order.id} - $${order.total_price}"`
        );
      }

      res.status(200).send('OK');
    } else {
      throw new Error(result.error);
    }
  } catch (error) {
    // Error notification
    await executeHook('error-notification',
      `high "Order processing failed for #${order.id}: ${error.message}"`
    );

    res.status(500).json({ error: 'Order processing failed' });
  }
});

app.listen(9850);
```

### Example 4: Dashboard with Hooks API UI

```typescript
import { setupHooksAPI, AVAILABLE_HOOKS } from '../shared-hooks-api';

const app = express();
app.use(express.json());

setupHooksAPI(app);

// Dashboard route showing available hooks
app.get('/dashboard', (req, res) => {
  res.send(`
    <!DOCTYPE html>
    <html>
    <head>
      <title>Agent Dashboard - Hooks API</title>
      <style>
        body { font-family: Arial; padding: 20px; }
        .hook { border: 1px solid #ccc; padding: 15px; margin: 10px 0; border-radius: 5px; }
        .hook-name { font-size: 18px; font-weight: bold; color: #2563eb; }
        .hook-desc { color: #666; margin: 5px 0; }
        .example { background: #f5f5f5; padding: 5px 10px; margin: 5px 0; font-family: monospace; }
        button { background: #2563eb; color: white; padding: 8px 16px; border: none; border-radius: 4px; cursor: pointer; }
        button:hover { background: #1d4ed8; }
      </style>
    </head>
    <body>
      <h1>Available Hooks</h1>
      ${Object.entries(AVAILABLE_HOOKS).map(([name, info]) => `
        <div class="hook">
          <div class="hook-name">${name}</div>
          <div class="hook-desc">${info.description}</div>
          <div>
            ${info.examples.map(ex => `<div class="example">${ex}</div>`).join('')}
          </div>
          <button onclick="testHook('${name}', '${info.examples[0]}')">Test</button>
        </div>
      `).join('')}

      <script>
        async function testHook(name, example) {
          const result = await fetch('/api/hooks/' + name, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ action: example })
          });
          const data = await result.json();
          alert(data.success ? 'Success: ' + data.output : 'Error: ' + data.error);
        }
      </script>
    </body>
    </html>
  `);
});

app.listen(9900);
```

## Integration Checklist

When integrating hooks API into an agent:

- [ ] Import the module: `import { setupHooksAPI } from '../shared-hooks-api';`
- [ ] Setup Express middleware: `app.use(express.json());`
- [ ] Call `setupHooksAPI(app)` before your custom routes
- [ ] Test hooks API endpoints: `GET /api/hooks`
- [ ] Update agent documentation with hooks usage
- [ ] Consider which hooks your agent needs programmatically
- [ ] Add error handling with `hooks.errors.notify()`
- [ ] Update agent's ecosystem.config.js if needed

## Migration from Direct Hook Execution

**Before (duplicated code):**
```typescript
import { exec } from 'child_process';
import { promisify } from 'util';
const execAsync = promisify(exec);

// Every agent has this duplicated...
async function sendSlackMessage(channel: string, message: string) {
  try {
    await execAsync(`node /root/DW-MCP/DW-Hooks/slack-hook.js send ${channel} "${message}"`);
  } catch (error) {
    console.error('Failed:', error);
  }
}
```

**After (shared module):**
```typescript
import { hooks } from '../shared-hooks-api';

// One line, with error handling built-in
await hooks.slack.send(channel, message);
```

## Error Handling

The module provides consistent error handling:

```typescript
import { executeHook } from '../shared-hooks-api';

const result = await executeHook('gmail', 'send test@example.com "Test" "Body"');

if (result.success) {
  console.log('Success:', result.output);
  console.log('Took:', result.executionTime, 'ms');
} else {
  console.error('Failed:', result.error);
  console.error('After:', result.executionTime, 'ms');

  // Notify about the failure
  await executeHook('error-notification',
    `high "Gmail hook failed: ${result.error}"`
  );
}
```

## Custom Timeout

By default, hooks timeout after 60 seconds. Adjust as needed:

```typescript
import { executeHook, HooksClient } from '../shared-hooks-api';

// One-off custom timeout
await executeHook('product-import-pipeline', 'import-large-file', 300000); // 5 minutes

// Client with custom default timeout
const hooksClient = new HooksClient(120000); // 2 minutes default
await hooksClient.processOrder('12345678');
```

## Security Considerations

1. **Input Sanitization**: Hook names are sanitized to prevent command injection
2. **Auth Required**: Protect hooks endpoints with your agent's authentication
3. **Rate Limiting**: Consider rate limiting hooks endpoints
4. **Logging**: All hook executions are logged with timestamps

```typescript
import { setupHooksAPI } from '../shared-hooks-api';
import rateLimit from 'express-rate-limit';

const app = express();

// Rate limit hooks API
const hooksLimiter = rateLimit({
  windowMs: 1 * 60 * 1000, // 1 minute
  max: 30 // 30 requests per minute
});

app.use('/api/hooks', hooksLimiter);

// Add authentication
app.use('/api/hooks', requireAuth);

setupHooksAPI(app);
```

## Testing

Test your integration:

```bash
# List all hooks
curl http://localhost:9800/api/hooks

# Get specific hook info
curl http://localhost:9800/api/hooks/gmail

# Execute a hook
curl -X POST http://localhost:9800/api/hooks/slack \
  -H "Content-Type: application/json" \
  -d '{"params": {"channel": "general", "message": "Test from API"}}'

# Execute with action string
curl -X POST http://localhost:9800/api/hooks/gmail \
  -H "Content-Type: application/json" \
  -d '{"action": "send test@example.com \"Subject\" \"Body\""}'
```

## Troubleshooting

### Hook not found
```
Error: Hook "gmails" not found
```
**Solution**: Check hook name spelling. Use `GET /api/hooks` to see available hooks.

### Timeout errors
```
Error: Command failed: timeout of 60000ms exceeded
```
**Solution**: Increase timeout or optimize hook execution time.

### Permission denied
```
Error: EACCES: permission denied
```
**Solution**: Ensure hook files are executable: `chmod +x /root/DW-MCP/DW-Hooks/*.js`

### Hook exists but fails
```
Error: Cannot find module '@slack/web-api'
```
**Solution**: Install dependencies in DW-MCP directory: `cd /root/DW-MCP && npm install`

## Support

For issues or questions:
1. Check this guide for integration examples
2. Review `/root/DW-MCP/DW-Hooks/README.md` for hook-specific docs
3. Test hooks directly: `node /root/DW-MCP/DW-Hooks/[hook-name]-hook.js`
4. Check agent logs for execution errors

---

**Last Updated:** 2025-11-12
**Module Version:** 1.0.0
**Maintained by:** DW-Agents Development Team