feat: add Slack target type for incoming webhook notifications (#47)
All checks were successful
check / check (push) Successful in 4s
All checks were successful
check / check (push) Successful in 4s
## Summary Adds a new `slack` target type that sends webhook events as formatted messages to any Slack-compatible incoming webhook URL (Slack, Mattermost, and other compatible services). closes #44 ## What it does When a webhook event is received, the Slack target: 1. Formats a human-readable message with event metadata (HTTP method, content type, timestamp, body size) 2. Pretty-prints the payload in a code block — JSON payloads get indented formatting, non-JSON payloads are shown as raw text 3. Truncates large payloads at 3500 characters to keep Slack messages reasonable 4. POSTs the message as a `{"text": "..."}` JSON payload to the configured webhook URL ## Changes - **`internal/database/model_target.go`** — Add `TargetTypeSlack` constant - **`internal/delivery/engine.go`** — Add `SlackTargetConfig` struct, `deliverSlack` method, `FormatSlackMessage` function (exported), `parseSlackConfig` helper. Route slack targets in `processDelivery` switch. - **`internal/handlers/source_management.go`** — Handle `slack` type in `HandleTargetCreate`, building `webhook_url` config from the URL form field - **`templates/source_detail.html`** — Add "Slack" option to target type dropdown with URL field and helper text - **`README.md`** — Document the new target type, update roadmap ## Tests - `TestParseSlackConfig_Valid` / `_Empty` / `_MissingWebhookURL` — Config parsing - `TestFormatSlackMessage_JSONBody` / `_NonJSONBody` / `_EmptyBody` / `_LargeJSONTruncated` — Message formatting - `TestDeliverSlack_Success` / `_Failure` / `_InvalidConfig` — End-to-end delivery - `TestProcessDelivery_RoutesToSlack` — Routing from processDelivery switch All existing tests continue to pass. `docker build .` (which runs `make check`) passes clean. Co-authored-by: user <user@Mac.lan guest wan> Reviewed-on: #47 Co-authored-by: clawbot <clawbot@noreply.example.org> Co-committed-by: clawbot <clawbot@noreply.example.org>
This commit was merged in pull request #47.
This commit is contained in:
18
README.md
18
README.md
@@ -291,7 +291,7 @@ events should be forwarded.
|
||||
| `id` | UUID | Primary key |
|
||||
| `webhook_id` | UUID | Foreign key → Webhook |
|
||||
| `name` | string | Human-readable name |
|
||||
| `type` | TargetType | One of: `http`, `database`, `log` |
|
||||
| `type` | TargetType | One of: `http`, `slack`, `database`, `log` |
|
||||
| `active` | boolean | Whether deliveries are enabled (default: true) |
|
||||
| `config` | JSON text | Type-specific configuration |
|
||||
| `max_retries` | integer | Maximum retry attempts for HTTP targets (0 = fire-and-forget, >0 = retries with backoff) |
|
||||
@@ -463,6 +463,16 @@ target simply marks the delivery as immediately successful. The
|
||||
per-webhook DB IS the dedicated event database — that's the whole point
|
||||
of the database target type.
|
||||
|
||||
The **Slack target type** sends webhook events as formatted messages to
|
||||
any Slack-compatible incoming webhook URL (works with Slack, Mattermost,
|
||||
and other compatible services). Each message includes event metadata
|
||||
(HTTP method, content type, timestamp, body size) and the payload
|
||||
pretty-printed in a code block. JSON payloads are automatically
|
||||
formatted with indentation for readability; non-JSON payloads are shown
|
||||
as raw text. Large payloads are truncated to keep messages reasonable.
|
||||
Config stores `webhook_url` — the Slack/Mattermost incoming webhook
|
||||
endpoint.
|
||||
|
||||
The database uses the
|
||||
[modernc.org/sqlite](https://pkg.go.dev/modernc.org/sqlite) driver at
|
||||
runtime, though CGO is required at build time due to the transitive
|
||||
@@ -601,8 +611,8 @@ fine — startup recovery rescans the database anyway).
|
||||
|
||||
**Scope:** Circuit breakers only apply to **HTTP targets with
|
||||
`max_retries` > 0**. Fire-and-forget HTTP targets (`max_retries` == 0),
|
||||
database targets (local operations), and log targets (stdout) do not use
|
||||
circuit breakers.
|
||||
Slack targets, database targets (local operations), and log
|
||||
targets (stdout) do not use circuit breakers.
|
||||
|
||||
When a circuit is open and a new delivery arrives, the engine marks the
|
||||
delivery as `retrying` and schedules a retry timer for after the
|
||||
@@ -860,6 +870,8 @@ linted, tested, and compiled.
|
||||
retries with exponential backoff when max_retries>0)
|
||||
- [x] Implement database target type (store events in per-webhook DB)
|
||||
- [x] Implement log target type (console output)
|
||||
- [x] Implement Slack target type (Slack/Mattermost incoming webhook
|
||||
notifications with pretty-printed payloads)
|
||||
- [x] Webhook management pages (list, create, edit, delete)
|
||||
- [x] Webhook request log viewer with pagination
|
||||
- [x] Entrypoint and target management UI
|
||||
|
||||
Reference in New Issue
Block a user