Manage the Slack digest in the admin
New settings area: the webhook lives in the database and is only shown shortened afterwards, the environment variable stays as a fallback. A switch decides whether internal entries travel, a button sends the digest right away, and every run is recorded with period, count, projects, result and who triggered it.
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
import { recordAudit } from '~/data/repositories/audit'
|
||||
import { clearSetting, writeSetting } from '~/data/repositories/settings'
|
||||
import { invalid, readField, readFlag, type AdminFormState } from './admin-forms'
|
||||
import { runWeeklyReport } from './report-settings'
|
||||
import type { Viewer } from './auth-access'
|
||||
|
||||
function looksLikeWebhook(value: string): boolean {
|
||||
return value === '' || /^https:\/\/hooks\.slack\.com\/services\/[\w/+-]+$/u.test(value)
|
||||
}
|
||||
|
||||
export async function performSaveSlack(viewer: Viewer, formData: FormData): Promise<AdminFormState> {
|
||||
const webhook = readField(formData, 'webhook')
|
||||
const keep = readFlag(formData, 'keep')
|
||||
const includeInternal = readFlag(formData, 'includeInternal')
|
||||
|
||||
if (!keep && !looksLikeWebhook(webhook)) {
|
||||
return invalid('webhookInvalid', undefined, { webhook: 'webhookInvalid' })
|
||||
}
|
||||
|
||||
if (!keep) {
|
||||
if (webhook === '') {
|
||||
await clearSetting('slack.webhook')
|
||||
} else {
|
||||
await writeSetting('slack.webhook', webhook)
|
||||
}
|
||||
}
|
||||
|
||||
await writeSetting('slack.includeInternal', includeInternal ? 'true' : 'false')
|
||||
|
||||
await recordAudit({
|
||||
actorId: viewer.id,
|
||||
actorLabel: viewer.email,
|
||||
action: 'settings.slack',
|
||||
entity: 'setting',
|
||||
entityId: 'slack',
|
||||
data: { webhookSet: keep ? 'unchanged' : webhook !== '', includeInternal },
|
||||
})
|
||||
|
||||
return { status: 'ok', message: 'slackSaved' }
|
||||
}
|
||||
|
||||
export async function performSendReport(viewer: Viewer, origin: string): Promise<AdminFormState> {
|
||||
const outcome = await runWeeklyReport({ origin, trigger: `admin:${viewer.email}` })
|
||||
|
||||
await recordAudit({
|
||||
actorId: viewer.id,
|
||||
actorLabel: viewer.email,
|
||||
action: 'settings.report',
|
||||
entity: 'setting',
|
||||
entityId: 'slack',
|
||||
data: { reason: outcome.reason, total: outcome.run.total },
|
||||
})
|
||||
|
||||
if (outcome.reason === 'sent') {
|
||||
return { status: 'ok', message: 'reportSent' }
|
||||
}
|
||||
|
||||
return invalid(outcome.reason === 'nothing_published' ? 'reportEmpty' : outcome.reason === 'not_configured' ? 'reportNoWebhook' : 'reportRejected')
|
||||
}
|
||||
Reference in New Issue
Block a user