> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/NapNeko/NapCatQQ/llms.txt
> Use this file to discover all available pages before exploring further.

# HTTP POST Webhook

> Configure HTTP POST webhooks for event delivery in NapCat

## Overview

The HTTP POST webhook (HTTP Client) allows NapCat to push events to your server via HTTP POST requests. This is a one-way communication method where NapCat sends events to your endpoint.

## Configuration

Configure the HTTP client in your OneBot config:

```json theme={null}
{
  "network": {
    "httpClients": [
      {
        "name": "http-client",
        "enable": true,
        "url": "http://localhost:8080",
        "messagePostFormat": "array",
        "reportSelfMessage": false,
        "token": "your_secret_token",
        "debug": false
      }
    ]
  }
}
```

### Configuration Options

| Option              | Type    | Default                 | Description                          |
| ------------------- | ------- | ----------------------- | ------------------------------------ |
| `enable`            | boolean | `false`                 | Enable HTTP POST webhook             |
| `url`               | string  | `http://localhost:8080` | Target URL for event delivery        |
| `token`             | string  | `""`                    | Secret token for HMAC signature      |
| `messagePostFormat` | string  | `array`                 | Message format (`array` or `string`) |
| `reportSelfMessage` | boolean | `false`                 | Report messages sent by bot itself   |
| `debug`             | boolean | `false`                 | Enable debug logging                 |

## Event Delivery

### Request Format

NapCat sends POST requests with the following headers:

```http theme={null}
POST / HTTP/1.1
Host: localhost:8080
Content-Type: application/json
X-Self-ID: 123456789
X-Signature: sha1=abcdef1234567890
User-Agent: NapCat
```

### Request Body

The request body contains the event data:

```json theme={null}
{
  "time": 1234567890,
  "self_id": 123456789,
  "post_type": "message",
  "message_type": "private",
  "sub_type": "friend",
  "message_id": 12345,
  "user_id": 87654321,
  "message": "Hello!",
  "raw_message": "Hello!",
  "font": 0,
  "sender": {
    "user_id": 87654321,
    "nickname": "Friend"
  }
}
```

## Security and Authentication

### HMAC Signature Verification

NapCat signs each request using HMAC-SHA1. Verify the signature to ensure requests are authentic:

```javascript theme={null}
const crypto = require('crypto');
const express = require('express');
const app = express();

const SECRET_TOKEN = 'your_secret_token';

app.post('/', express.json(), (req, res) => {
  const signature = req.headers['x-signature'];
  const body = JSON.stringify(req.body);
  
  // Calculate expected signature
  const hmac = crypto.createHmac('sha1', SECRET_TOKEN);
  hmac.update(body);
  const expectedSignature = 'sha1=' + hmac.digest('hex');
  
  // Verify signature
  if (signature !== expectedSignature) {
    return res.status(403).json({ error: 'Invalid signature' });
  }
  
  // Process event
  console.log('Event received:', req.body);
  res.json({ message: 'Event received' });
});

app.listen(8080, () => {
  console.log('Webhook server listening on port 8080');
});
```

### Python Example

```python theme={null}
import hmac
import hashlib
import json
from flask import Flask, request, jsonify

app = Flask(__name__)
SECRET_TOKEN = 'your_secret_token'

@app.route('/', methods=['POST'])
def webhook():
    signature = request.headers.get('X-Signature', '')
    body = request.get_data()
    
    # Calculate expected signature
    expected = 'sha1=' + hmac.new(
        SECRET_TOKEN.encode('utf-8'),
        body,
        hashlib.sha1
    ).hexdigest()
    
    # Verify signature
    if not hmac.compare_digest(signature, expected):
        return jsonify({'error': 'Invalid signature'}), 403
    
    # Process event
    event = request.json
    print(f'Event received: {event}')
    
    return jsonify({'message': 'Event received'})

if __name__ == '__main__':
    app.run(port=8080)
```

## Quick Actions

You can return quick actions in the webhook response to perform immediate operations:

```javascript theme={null}
app.post('/', express.json(), (req, res) => {
  const event = req.body;
  
  if (event.post_type === 'message' && event.message === 'ping') {
    // Quick reply
    return res.json({
      reply: 'pong!'
    });
  }
  
  if (event.post_type === 'message' && event.message.includes('bad word')) {
    // Delete message and kick user
    return res.json({
      delete: true,
      kick: true
    });
  }
  
  res.json({});
});
```

### Available Quick Actions

| Action         | Type         | Description                    |
| -------------- | ------------ | ------------------------------ |
| `reply`        | string/array | Send a reply message           |
| `reply_at`     | boolean      | Include @mention in reply      |
| `delete`       | boolean      | Delete the message             |
| `kick`         | boolean      | Kick the user (group only)     |
| `ban`          | boolean      | Ban/mute the user (group only) |
| `ban_duration` | number       | Ban duration in seconds        |

### Quick Action Examples

#### Auto Reply

```json theme={null}
{
  "reply": "Thanks for your message!"
}
```

#### Reply with Mention

```json theme={null}
{
  "reply": "Hello there!",
  "reply_at": true
}
```

#### Delete and Ban

```json theme={null}
{
  "delete": true,
  "ban": true,
  "ban_duration": 600
}
```

## Event Types

### Message Events

```json theme={null}
{
  "post_type": "message",
  "message_type": "private",
  "sub_type": "friend",
  "message_id": 12345,
  "user_id": 87654321,
  "message": "Hello!",
  "raw_message": "Hello!"
}
```

### Notice Events

```json theme={null}
{
  "post_type": "notice",
  "notice_type": "group_increase",
  "sub_type": "approve",
  "group_id": 12345678,
  "user_id": 87654321,
  "operator_id": 87654321
}
```

### Request Events

```json theme={null}
{
  "post_type": "request",
  "request_type": "friend",
  "user_id": 87654321,
  "comment": "Please add me",
  "flag": "unique_request_flag"
}
```

## Multiple Webhooks

You can configure multiple webhook endpoints:

```json theme={null}
{
  "network": {
    "httpClients": [
      {
        "name": "main-webhook",
        "enable": true,
        "url": "http://localhost:8080/napcat",
        "token": "main_token"
      },
      {
        "name": "backup-webhook",
        "enable": true,
        "url": "http://backup-server:8081/napcat",
        "token": "backup_token"
      },
      {
        "name": "logging-webhook",
        "enable": true,
        "url": "http://logger:8082/events",
        "token": "log_token"
      }
    ]
  }
}
```

## Error Handling

NapCat logs errors if webhook delivery fails:

```
[OneBot] [Http Client] 新消息事件HTTP上报返回快速操作失败 Error: connect ECONNREFUSED 127.0.0.1:8080
```

### Webhook Server Best Practices

1. **Return responses quickly** - NapCat may timeout on slow responses
2. **Handle errors gracefully** - Log errors but don't crash
3. **Verify signatures** - Always verify HMAC signatures in production
4. **Process asynchronously** - Handle heavy operations in background tasks
5. **Monitor uptime** - NapCat doesn't retry failed deliveries

## Testing Your Webhook

### Using ngrok for Local Testing

```bash theme={null}
# Start ngrok
ngrok http 8080

# Use the ngrok URL in NapCat config
{
  "url": "https://abc123.ngrok.io"
}
```

### Manual Testing

Send a test POST request:

```bash theme={null}
curl -X POST http://localhost:8080 \
  -H "Content-Type: application/json" \
  -H "X-Self-ID: 123456789" \
  -d '{
    "post_type": "message",
    "message_type": "private",
    "user_id": 12345,
    "message": "test"
  }'
```

## Implementation Details

The HTTP client adapter is implemented in `packages/napcat-onebot/network/http-client.ts`:

* Uses HMAC-SHA1 for request signing
* Sends `X-Self-ID` header with bot's QQ number
* Supports quick action responses
* Asynchronous event delivery with error logging

## Webhook vs WebSocket

| Feature    | HTTP Webhook         | WebSocket               |
| ---------- | -------------------- | ----------------------- |
| Direction  | One-way (push only)  | Bidirectional           |
| Connection | Request per event    | Persistent connection   |
| API Calls  | Via separate HTTP/WS | Through same connection |
| Latency    | Higher               | Lower                   |
| Setup      | Simpler              | More complex            |
| Use Case   | Simple bots, logging | Real-time apps          |

## Security Considerations

1. **Use HTTPS** - Encrypt webhook traffic in production
2. **Verify signatures** - Always check X-Signature header
3. **Restrict access** - Use firewall rules to limit webhook endpoint access
4. **Rotate tokens** - Change tokens periodically
5. **Log suspicious activity** - Monitor for invalid signatures

## Troubleshooting

### Events Not Received

* Check that the HTTP client is enabled: `"enable": true`
* Verify the webhook URL is correct and accessible
* Check server logs for connection errors
* Test the endpoint with curl

### Signature Verification Fails

* Ensure token matches exactly on both sides
* Verify you're hashing the raw request body
* Check character encoding (use UTF-8)
* Compare generated signature with received one

### Quick Actions Not Working

* Return actions in response within reasonable timeout
* Check response format matches expected structure
* Look for errors in NapCat debug logs
* Verify the event type supports the quick action

## Next Steps

* Learn about [WebSocket connections](/api/network/websocket) for bidirectional communication
* Explore [HTTP API](/api/network/http) for making API calls
* Check [API reference](/api/actions/overview) for available actions
* Read [troubleshooting guide](/resources/troubleshooting) for common issues
