> ## Documentation Index
> Fetch the complete documentation index at: https://docs.commentify.pro/llms.txt
> Use this file to discover all available pages before exploring further.

# Moderator webhooks

> Queued JSON POSTs to Slack or Discord when comments go pending, get reported, or are denied as spam.

Moderation that only exists inside `/admin` gets ignored until Friday. Pro can POST to the URLs your on-call already watches.

```env theme={null}
COMMENTIFY_WEBHOOKS=true
COMMENTIFY_WEBHOOK_URLS=https://hooks.slack.com/services/...,https://discord.com/api/webhooks/...
```

```php theme={null}
'webhooks' => [
    'enabled' => (bool) env('COMMENTIFY_WEBHOOKS', false),
    'urls' => /* exploded COMMENTIFY_WEBHOOK_URLS */,
    'events' => ['pending', 'report', 'spam_deny'],
    'timeout' => 5,
],
```

Each URL receives a queued job (`DispatchModeratorWebhook`) with `Http::timeout`, `Accept: application/json`, JSON body. Failed HTTP responses throw and the job retries per your queue config. Put a worker on the default queue.

## Events

| `event`     | When                                                            | Extra payload                                            |
| ----------- | --------------------------------------------------------------- | -------------------------------------------------------- |
| `pending`   | Comment saved unapproved (approval required or spam **review**) | `comment_id`, `excerpt` (250 chars), `author`            |
| `spam_deny` | Pipeline **deny** (row never saved)                             | `excerpt`, `reasons`, `author`                           |
| `report`    | A `CommentReport` is created                                    | `comment_id`, `report_id`, `reason`, `excerpt`, `author` |

Every payload also includes:

```json theme={null}
{
  "event": "pending",
  "occurred_at": "2026-09-12T14:03:11+00:00"
}
```

Events not listed in `webhooks.events` are skipped. Disable with `COMMENTIFY_WEBHOOKS=false` or an empty URL list.

Slack incoming webhooks and Discord webhook URLs both accept JSON POSTs; you may need a tiny adapter if they expect `{ "text": "…" }` instead of Commentify's schema. Keep `timeout` low so a hung chat app does not clog the queue.
