Skip to content

Commit 9735362

Browse files
committed
adding auto purge of alerts database based on num days and linked incidents
1 parent 9b28079 commit 9735362

File tree

4 files changed

+91
-4
lines changed

4 files changed

+91
-4
lines changed

.env

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
NIMS_ASSETS_DATABASE_ID=
22
NIMS_ALERTS_DATABASE_ID=
3-
NOTION_AUTH_TOKEN=
3+
NOTION_AUTH_TOKEN=
4+
NOTION_ALERT_AGE=30
5+
AUTO_PURGE_ALERTS=false

NOTION.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ You need both the `Asset Database` ID and the `Alert Database` ID to use this to
1313
* Link: `https://www.notion.so/184cdc5a1ef3710badc2d2b1271aeb81?v=174cdc3a1ef181719981000cab12bf54&pvs=4`
1414
* ID: `184cdc5a1ef3710badc2d2b1271aeb81`
1515
4. Copy the ID
16-
5. Repeat the above for the other database
16+
5. Repeat the above for the `Alert Database`
1717

1818
## Auth Token and Access
1919

@@ -50,4 +50,4 @@ This will walk you through creating a Notion integration, getting the auth token
5050
8. Click `Confirm`
5151
![connection](./screenshots/confirm.png)
5252

53-
9. Repeat steps 7 and 8 for the `Asset Database`
53+
9. Repeat steps 7 and 8 for the `Incident Database` and `Asset Database`

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,14 @@ Either build the binary (steps above) if you wish to make modifications, or down
2222
First, replace Notion auth token and database IDs with yours in `.env`.
2323

2424
You can generate and configure your auth token by following the steps in [NOTION.md](./NOTION.md).
25+
26+
This binary will purge alerts not associated with an incident and older than `NOTION_ALERT_AGE` (in days) automatically if `AUTO_PURGE_ALERTS` is set to `true`.
2527
```bash
2628
NIMS_ASSETS_DATABASE_ID=
2729
NIMS_ALERTS_DATABASE_ID=
2830
NOTION_AUTH_TOKEN=
31+
NOTION_ALERT_AGE=30
32+
AUTO_PURGE_ALERTS=false
2933
```
3034
Run the binary
3135
```bash

nims-webhook.go

Lines changed: 82 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ var (
1919
assetsDatabaseID string
2020
alertsDatabaseID string
2121
authToken string
22+
alertAge int
23+
autoPurge bool
2224
)
2325

2426
func init() {
@@ -32,11 +34,79 @@ func init() {
3234
assetsDatabaseID = os.Getenv("NIMS_ASSETS_DATABASE_ID")
3335
alertsDatabaseID = os.Getenv("NIMS_ALERTS_DATABASE_ID")
3436
authToken = os.Getenv("NOTION_AUTH_TOKEN")
37+
autoPurgeStr := os.Getenv("AUTO_PURGE_ALERTS")
38+
autoPurge, err = strconv.ParseBool(autoPurgeStr)
39+
if err != nil {
40+
log.Fatalf("Invalid boolean value for AUTO_PURGE_ALERTS: %v\n", err)
41+
autoPurge = false
42+
}
43+
alertAge, err = strconv.Atoi(os.Getenv("NOTION_ALERT_AGE"))
44+
if err != nil {
45+
log.Fatalf("invalid value for NOTION_ALERT_AGE: %v\n", err)
46+
}
3547

3648
// initialize notion client
3749
client = notionapi.NewClient(notionapi.Token(authToken))
3850
}
3951

52+
func deleteRecord(recordID string) error {
53+
pageID := notionapi.PageID(recordID)
54+
55+
// set archived to true
56+
_, err := client.Page.Update(context.Background(), pageID, &notionapi.PageUpdateRequest{
57+
Archived: true,
58+
})
59+
if err != nil {
60+
return fmt.Errorf("unable to delete record: %v", err)
61+
}
62+
63+
return nil
64+
}
65+
66+
func deleteOldAlerts(databaseID string, days int) error {
67+
68+
// define the filter for "Created Time" older than $days and "Related Incident" is empty
69+
daysAgo := time.Now().AddDate(0, 0, -days)
70+
timeObj, _ := time.Parse(time.RFC3339, daysAgo.Format(time.RFC3339))
71+
dateObj := notionapi.Date(timeObj)
72+
73+
filter := &notionapi.DatabaseQueryRequest{
74+
Filter: notionapi.AndCompoundFilter{
75+
notionapi.TimestampFilter{
76+
Timestamp: notionapi.TimestampCreated,
77+
CreatedTime: &notionapi.DateFilterCondition{
78+
Before: &dateObj,
79+
},
80+
},
81+
notionapi.PropertyFilter{
82+
Property: "Related Incident",
83+
Relation: &notionapi.RelationFilterCondition{
84+
IsEmpty: true,
85+
},
86+
},
87+
},
88+
}
89+
90+
// Query the database
91+
response, err := client.Database.Query(context.Background(), notionapi.DatabaseID(databaseID), filter)
92+
if err != nil {
93+
return fmt.Errorf("failed to query the database: %v", err)
94+
}
95+
96+
// Iterate through the results and delete matching alerts
97+
for _, result := range response.Results {
98+
fmt.Printf("%s - deleting alert with ID %s - %s\n", time.Now().UTC().Format(time.RFC3339), result.ID, result.Properties["Name"].(*notionapi.TitleProperty).Title[0].Text.Content)
99+
100+
if err := deleteRecord(string(result.ID)); err != nil {
101+
fmt.Printf("%s - failed to delete alert with ID %s: %v\n", time.Now().UTC().Format(time.RFC3339), result.ID, err)
102+
} else {
103+
fmt.Printf("%s - successfully deleted alert with ID %s\n", time.Now().UTC().Format(time.RFC3339), result.ID)
104+
}
105+
}
106+
107+
return nil
108+
}
109+
40110
func checkRelatedAssetExists(name string) (notionapi.ObjectID, error) {
41111
// search for the asset by title (name)
42112
filter := notionapi.PropertyFilter{
@@ -281,8 +351,19 @@ func webhookHandler(w http.ResponseWriter, r *http.Request) {
281351
}
282352

283353
func main() {
354+
355+
if autoPurge {
356+
// start a goroutine for the 24-hour cron job to purge unassociated alerts
357+
go func() {
358+
for {
359+
deleteOldAlerts(alertsDatabaseID, alertAge)
360+
time.Sleep(24 * time.Hour)
361+
}
362+
}()
363+
}
364+
284365
// listen on port 9000 for webhook POST requests
285366
http.HandleFunc("/hooks/alert", webhookHandler)
286-
log.Println("Listening for webhooks on port 9000")
367+
fmt.Printf("%s - listening for webhooks on port 9000\n", time.Now().UTC().Format(time.RFC3339))
287368
log.Fatal(http.ListenAndServe(":9000", nil))
288369
}

0 commit comments

Comments
 (0)