Send a weekly digest to Slack
POST /api/v1/weekly-report collects everything published in the last seven days, groups it by project and posts one message. dry=1 returns the message instead of sending it, no publications means no message, a missing webhook answers 501 instead of failing quietly. scripts/cron.mjs runs the due publishing first, then the digest.
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
import type { SlackMessage } from './weekly-report'
|
||||
|
||||
export type SlackResult =
|
||||
| { ok: true }
|
||||
| { ok: false, reason: 'not_configured' | 'rejected', detail?: string }
|
||||
|
||||
export function slackWebhook(): string | undefined {
|
||||
const url = process.env.SLACK_WEBHOOK_URL?.trim()
|
||||
|
||||
return url === '' ? undefined : url
|
||||
}
|
||||
|
||||
export async function sendToSlack(message: SlackMessage, webhook = slackWebhook()): Promise<SlackResult> {
|
||||
if (!webhook) {
|
||||
return { ok: false, reason: 'not_configured' }
|
||||
}
|
||||
|
||||
const response = await fetch(webhook, {
|
||||
method: 'POST',
|
||||
headers: { 'content-type': 'application/json' },
|
||||
body: JSON.stringify(message),
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
return { ok: false, reason: 'rejected', detail: `${response.status} ${await response.text()}` }
|
||||
}
|
||||
|
||||
return { ok: true }
|
||||
}
|
||||
Reference in New Issue
Block a user