# Schedule Microsoft Teams messages

Post to a Microsoft Teams channel on a schedule: weekly reminders, daily numbers, and alerts filled in from any API. cronservices sends the message as an Adaptive Card through a Teams Workflows webhook.

## Example: a Monday kickoff reminder

```json
{
  "name": "Weekly kickoff",
  "cron": { "expression": "45 8 * * MON", "time_zone": "Europe/London" },
  "nodes": [
    { "id": "post", "teams_post_message": {
        "webhook_url": "https://prod-12.westeurope.logic.azure.com:443/workflows/abc123/triggers/manual/paths/invoke?api-version=2016-06-01&sig=XYZ",
        "text": "**Weekly kickoff in 15 minutes.** Agenda: {{ format(now:Europe/London, \"dddd DD MMMM\") }} priorities and blockers." } }
  ]
}
```

## Example: who's on call, every morning

```json
{
  "name": "On-call to Teams",
  "cron": { "expression": "0 9 * * 1-5", "time_zone": "America/Chicago" },
  "nodes": [
    { "id": "oncall", "pagerduty_list_on_calls": { "credential_id": "YOUR_PAGERDUTY_API_KEY_ID", "escalation_policy": "PABC123", "limit": 1 } },
    { "id": "post", "teams_post_message": {
        "webhook_url": "https://prod-12.westeurope.logic.azure.com:443/workflows/abc123/triggers/manual/paths/invoke?api-version=2016-06-01&sig=XYZ",
        "text": "On call today: **{{ $.oncalls[0].user.summary }}**" } }
  ]
}
```

## Set up

In Teams, open the channel's **Workflows** and choose **Post to a channel when a webhook request is received**. Copy the URL it gives you into `webhook_url`. Older `webhook.office.com` connector URLs work too, while Microsoft still accepts them.

## Reference

### Post a Microsoft Teams message: `teams_post_message`

**Sends** POST to the Workflows webhook URL with an Adaptive Card holding the text. **Output** for the next step: The webhook’s response.

| Field | Type | Notes |
| --- | --- | --- |
| `webhook_url` | string, required | A Teams Workflows ("Post to a channel when a webhook request is received") URL on `logic.azure.com`, or a legacy `webhook.office.com` connector URL. |
| `text` | string, required | Up to 4,000 characters. Adaptive Card text supports simple markdown. Placeholders allowed. |

## More ideas

- Post the sprint's open bug count from your tracker's API every morning.
- Remind the team to submit expenses on the last weekday of the month: `0 10 LW * *`.
- Post a release freeze notice once, at an exact time, with `run_at`.
