# Schedule Mattermost messages

Post to a Mattermost channel on a schedule, on Mattermost Cloud or your own server. cronservices sends the message through an incoming webhook and can fill it in from any API first.

## Example: nightly build status

```json
{
  "name": "Nightly build status",
  "cron": { "expression": "30 6 * * *", "time_zone": "UTC" },
  "nodes": [
    { "id": "build", "request": { "method": "GET", "endpoint": "https://ci.example.com/api/builds/latest?branch=main", "credential_id": "YOUR_CI_TOKEN_ID" } },
    { "id": "post", "mattermost_send_message": {
        "webhook_url": "https://chat.example.com/hooks/xjw7c9r4ofbx3ga6h1k8mzqp5e",
        "text": "Nightly build #{{ $.number }}: **{{ $.status }}** in {{ $.duration_minutes }} min",
        "username": "ci-bot" } }
  ]
}
```

## Set up

In Mattermost, open **Integrations → Incoming Webhooks → Add Incoming Webhook**, choose the channel, and copy the URL into `webhook_url`. To set `username`, the server must allow integrations to override usernames.

## Reference

### Send a Mattermost message: `mattermost_send_message`

**Sends** POST to the incoming webhook URL with `{"text": …}`. **Output** for the next step: The text `ok`.

| Field | Type | Notes |
| --- | --- | --- |
| `webhook_url` | string, required | An incoming webhook, `https://<your server>/hooks/<id>`. |
| `text` | string, required | Markdown, up to 16,383 characters. Placeholders allowed. |
| `username` | string | Overrides the webhook’s name, if the server allows it. |

## More ideas

- A weekly on-call handoff note from [PagerDuty](/integrations/pagerduty).
- A daily reminder to review open merge requests.
- A monthly security patch reminder on the second Tuesday: `0 9 * * TUE#2`.
