Schedule Slack messages and daily digests
Post to any Slack channel on a schedule: a standup digest, a reminder, a daily number, or an announcement. cronservices sends the message through an incoming webhook, so there's no bot to host, and it can fill the message in from any API first.
Example: a daily Slack reminder
The simplest job: a message every weekday at 09:30 in your time zone.
{
"name": "Standup reminder",
"cron": { "expression": "30 9 * * 1-5", "time_zone": "America/New_York" },
"nodes": [
{ "id": "post", "slack_send_message": {
"webhook_url": "https://hooks.slack.com/services/T000/B000/XXXX",
"text": ":wave: Standup in 15 minutes. Post your update in the thread." } }
]
}Example: open pull requests before standup
Fetch data, turn it into lines, and post it. The join function writes a list as text, one item per line:
{
"name": "Open PRs to #eng",
"cron": { "expression": "0 9 * * 1-5", "time_zone": "Europe/Berlin" },
"nodes": [
{ "id": "prs", "github_list_pull_requests": { "credential_id": "YOUR_GITHUB_CREDENTIAL_ID", "owner": "acme", "repo": "web", "state": "open" } },
{ "id": "lines", "transform": { "template": "{ \"count\": \"{{ $.length }}\", \"lines\": { \"{{#each $}}\": \"• <{{ $.html_url }}|#{{ $.number }}> {{ $.title }}\" } }" } },
{ "id": "post", "slack_send_message": {
"webhook_url": "https://hooks.slack.com/services/T000/B000/XXXX",
"text": "*{{ $.count }} open pull requests*\n{{ join($.lines, \"\\n\") }}" } }
]
}Set up
- Create a Slack app at api.slack.com/apps, turn on Incoming Webhooks, and add a webhook to the channel.
- Copy the
https://hooks.slack.com/services/…URL intowebhook_url. Treat it as a secret: anyone with it can post to the channel. - To read messages with
slack_channel_history, give the app a bot token withchannels:historyand save it as abearer_tokencredential.
To send Slack's richer Block Kit layouts, use a request step that posts your own blocks JSON to the same webhook.
Reference
Send a Slack message: slack_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 URL, https://hooks.slack.com/services/…, from a Slack app with Incoming Webhooks turned on. |
text |
string, required | Slack mrkdwn: *bold*, _italic_, <https://example.com|a link>. Up to 40,000 characters. Placeholders allowed. |
Read a Slack channel: slack_channel_history
Sends GET https://slack.com/api/conversations.history. Output for the next step: Slack's response: messages (newest first), each with text, user and ts.
| Field | Type | Notes |
|---|---|---|
credential_id |
string, required | The id of a bearer_token credential holding a bot token (xoxb-…) with channels:history, groups:history or im:history. |
channel |
string, required | A channel, private group or DM id, such as C0123456789. |
limit |
integer | 1 to 100. Omit for Slack’s default of 100. |
More ideas
- Post yesterday's signups from your analytics API every morning:
0 8 * * *. - Announce who's on call from PagerDuty:
0 9 * * MON. - Post past-due Stripe subscriptions each weekday.
- Remind the team about timesheets on the last weekday of the month:
0 15 LW * *. - Post a weather brief for a field crew at 05:30 local time.