0

New or Updated Incident

by
Published 4 days ago

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).

Scriptยท trigger pagerduty
  • Submitted by hugo989 Typescript (fetch-only)
    Created 5 days ago
    1
    //native
    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
      // First run: record the watermark and don't emit a backlog.
    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