1 | |
2 |
|
3 | import * as wmill from "windmill-client" |
4 |
|
5 | |
6 | * New or Updated Incident |
7 | * Polls incidents and emits those whose status changed since the last run (created, acknowledged, or resolved), tracked via Windmill state on last_status_change_at. Optionally filter by statuses and service IDs. First run sets the watermark and emits nothing. Detects changes within the most recently created incidents window (up to 100). |
8 | */ |
9 | export async function main( |
10 | auth: RT.Pagerduty, |
11 | statuses: ("triggered" | "acknowledged" | "resolved")[] | undefined, |
12 | service_ids: string[] | undefined, |
13 | ) { |
14 | const lastChecked: string | undefined = await wmill.getState() |
15 |
|
16 | const url = new URL("https://api.pagerduty.com/incidents") |
17 | url.searchParams.append("sort_by", "created_at:desc") |
18 | url.searchParams.append("limit", "100") |
19 | if (statuses) for (const s of statuses) url.searchParams.append("statuses[]", s) |
20 | if (service_ids) |
21 | for (const s of service_ids) url.searchParams.append("service_ids[]", s) |
22 |
|
23 | const response = await fetch(url, { |
24 | method: "GET", |
25 | headers: { |
26 | Authorization: `Token token=${auth.token}`, |
27 | Accept: "application/vnd.pagerduty+json;version=2", |
28 | }, |
29 | }) |
30 |
|
31 | if (!response.ok) { |
32 | throw new Error(`${response.status} ${await response.text()}`) |
33 | } |
34 |
|
35 | const data = await response.json() |
36 | const incidents: Array<{ last_status_change_at: string }> = |
37 | data.incidents ?? [] |
38 |
|
39 | const maxWatermark = incidents.reduce( |
40 | (max, i) => (i.last_status_change_at > max ? i.last_status_change_at : max), |
41 | lastChecked ?? "", |
42 | ) |
43 |
|
44 | |
45 | if (lastChecked === undefined) { |
46 | await wmill.setState(maxWatermark) |
47 | return [] |
48 | } |
49 |
|
50 | const fresh = incidents |
51 | .filter((i) => i.last_status_change_at > lastChecked) |
52 | .sort((a, b) => |
53 | a.last_status_change_at.localeCompare(b.last_status_change_at), |
54 | ) |
55 |
|
56 | if (maxWatermark > lastChecked) { |
57 | await wmill.setState(maxWatermark) |
58 | } |
59 |
|
60 | return fresh |
61 | } |
62 |
|