Move Webhooks and Custom Content sections to dedicated docs

This commit is contained in:
Louis King
2026-04-17 22:38:15 +01:00
parent ccadfa73fd
commit f1dc155a0f
6 changed files with 209 additions and 136 deletions
+96
View File
@@ -0,0 +1,96 @@
# Custom Content
The web dashboard supports custom content including markdown pages and media files. Content is served from the `CONTENT_HOME` directory (default: `./content`).
## Directory Structure
```
content/
├── pages/ # Custom markdown pages
│ └── about.md
└── media/ # Custom media files
└── images/
├── logo.svg # Full-color custom logo (default)
└── logo-invert.svg # Monochrome custom logo (darkened in light mode)
```
## Custom Logos
The web dashboard supports custom logo images placed in `media/images/`:
- `logo.svg` — full-color logo, displayed as-is in both themes (no automatic darkening)
- `logo-invert.svg` — monochrome/two-tone logo, automatically darkened in light mode for visibility
If no custom logos are provided, the default MeshCore Hub logos are used.
## Markdown Pages
Custom pages are written in Markdown with optional YAML frontmatter for metadata. Pages automatically appear in the navigation menu and sitemap.
### Setup
```bash
# Create content directory structure
mkdir -p content/pages content/media
# Create a custom page
cat > content/pages/about.md << 'EOF'
---
title: About Us
slug: about
menu_order: 10
---
# About Our Network
Welcome to our MeshCore mesh network!
## Getting Started
1. Get a compatible LoRa device
2. Flash MeshCore firmware
3. Configure your radio settings
EOF
```
### Frontmatter Fields
Pages use YAML frontmatter for metadata:
```markdown
---
title: About Us # Browser tab title and nav link (not rendered on page)
slug: about # URL path (default: filename without .md)
menu_order: 10 # Nav sort order (default: 100, lower = earlier)
---
# About Our Network
Markdown content here (include your own heading)...
```
| Field | Default | Description |
|-------|---------|-------------|
| `title` | Filename titlecased | Browser tab title and navigation link text (not rendered on page) |
| `slug` | Filename without `.md` | URL path (e.g., `about``/pages/about`) |
| `menu_order` | `100` | Sort order in navigation (lower = earlier) |
The markdown content is rendered as-is, so include your own `# Heading` if desired.
## Docker Configuration
With Docker, mount the content directory as a read-only volume. This is already configured in `docker-compose.yml`:
```yaml
volumes:
- ${CONTENT_HOME:-./content}:/content:ro
environment:
- CONTENT_HOME=/content
```
To customize the content path, set `CONTENT_HOME` in your `.env` file:
```bash
# .env
CONTENT_HOME=./content
```
+74
View File
@@ -0,0 +1,74 @@
# Webhooks
The collector can forward certain events to external HTTP endpoints. This is useful for integrating MeshCore Hub with external systems, notification services, or custom processing pipelines.
## Configuration
| Variable | Default | Description |
| -------------------------------- | -------- | ---------------------------------------- |
| `WEBHOOK_ADVERTISEMENT_URL` | _(none)_ | Webhook URL for advertisement events |
| `WEBHOOK_ADVERTISEMENT_SECRET` | _(none)_ | Secret sent as `X-Webhook-Secret` header |
| `WEBHOOK_MESSAGE_URL` | _(none)_ | Webhook URL for all message events |
| `WEBHOOK_MESSAGE_SECRET` | _(none)_ | Secret for message webhook |
| `WEBHOOK_CHANNEL_MESSAGE_URL` | _(none)_ | Override URL for channel messages only |
| `WEBHOOK_CHANNEL_MESSAGE_SECRET` | _(none)_ | Secret for channel message webhook |
| `WEBHOOK_DIRECT_MESSAGE_URL` | _(none)_ | Override URL for direct messages only |
| `WEBHOOK_DIRECT_MESSAGE_SECRET` | _(none)_ | Secret for direct message webhook |
| `WEBHOOK_TIMEOUT` | `10.0` | Request timeout in seconds |
| `WEBHOOK_MAX_RETRIES` | `3` | Max retry attempts on failure |
| `WEBHOOK_RETRY_BACKOFF` | `2.0` | Exponential backoff multiplier |
### URL Routing
- `WEBHOOK_MESSAGE_URL` receives **both** channel and direct message events unless overridden.
- `WEBHOOK_CHANNEL_MESSAGE_URL` overrides the URL for channel messages only.
- `WEBHOOK_DIRECT_MESSAGE_URL` overrides the URL for direct messages only.
### Secrets
Each webhook URL can optionally have a corresponding secret. When configured, the secret is sent as the `X-Webhook-Secret` HTTP header, allowing the receiving endpoint to verify the request origin.
### Retries
Failed webhook deliveries are retried with exponential backoff:
- **`WEBHOOK_MAX_RETRIES`** — Maximum number of retry attempts (default: 3).
- **`WEBHOOK_RETRY_BACKOFF`** — Backoff multiplier applied between retries (default: 2.0). For example, with the default settings, retries occur at approximately 2s, 4s, and 8s.
## Payload Format
All webhooks send a JSON POST request with the following structure:
```json
{
"event_type": "advertisement",
"public_key": "abc123...",
"payload": { ... }
}
```
### Event Types
| Event Type | Trigger | Payload Content |
| ----------------- | -------------------------------- | ---------------------------- |
| `advertisement` | Node advertisement received | Advertisement event data |
| `channel_message` | Channel message received | Channel message event data |
| `direct_message` | Direct message received | Direct message event data |
### Example: Advertisement Webhook
```bash
# .env
WEBHOOK_ADVERTISEMENT_URL=https://example.com/webhook
WEBHOOK_ADVERTISEMENT_SECRET=my-secret-key
```
### Example: Separate Channel and Direct Message Webhooks
```bash
# .env
WEBHOOK_CHANNEL_MESSAGE_URL=https://example.com/channel-webhook
WEBHOOK_CHANNEL_MESSAGE_SECRET=channel-secret
WEBHOOK_DIRECT_MESSAGE_URL=https://example.com/direct-webhook
WEBHOOK_DIRECT_MESSAGE_SECRET=direct-secret
```