Skip to content

Commit 2215466

Browse files
feat: add notification command with list and info subcommands
Add a read-only `notification` (alias `n`) top-level command to view notification channels configured in the workspace. Supports all 12 provider types: discord, email, google_chat, grafana_oncall, ntfy, pagerduty, opsgenie, slack, sms, telegram, webhook, and whatsapp. - `notification list` shows ID, name, provider, and monitor count - `notification info <id>` shows full provider config, linked monitors, and timestamps with nested provider-specific data in JSON output - Follows the same patterns as status-page (dual client factory, interceptor test helpers, JSON/table output branching)
1 parent cddeb9b commit 2215466

File tree

11 files changed

+913
-5
lines changed

11 files changed

+913
-5
lines changed

docs/openstatus-docs.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,55 @@ The following flags are supported:
491491
|-----------------------------|-----------------------------|:-------------:|:----------------------:|
492492
| `--access-token="…"` (`-t`) | OpenStatus API Access Token | | `OPENSTATUS_API_TOKEN` |
493493

494+
### `notification` command (aliases: `n`)
495+
496+
Manage notifications.
497+
498+
Usage:
499+
500+
```bash
501+
$ openstatus [GLOBAL FLAGS] notification [ARGUMENTS...]
502+
```
503+
504+
### `notification list` subcommand
505+
506+
List all notifications.
507+
508+
> openstatus notification list
509+
> openstatus notification list --limit 10
510+
511+
Usage:
512+
513+
```bash
514+
$ openstatus [GLOBAL FLAGS] notification list [COMMAND FLAGS] [ARGUMENTS...]
515+
```
516+
517+
The following flags are supported:
518+
519+
| Name | Description | Default value | Environment variables |
520+
|-----------------------------|---------------------------------------------------|:-------------:|:----------------------:|
521+
| `--access-token="…"` (`-t`) | OpenStatus API Access Token | | `OPENSTATUS_API_TOKEN` |
522+
| `--limit="…"` | Maximum number of notifications to return (1-100) | `0` | *none* |
523+
524+
### `notification info` subcommand
525+
526+
Get notification details.
527+
528+
> openstatus notification info <NotificationID>
529+
> openstatus notification info 12345
530+
531+
Usage:
532+
533+
```bash
534+
$ openstatus [GLOBAL FLAGS] notification info [COMMAND FLAGS] [ARGUMENTS...]
535+
```
536+
537+
The following flags are supported:
538+
539+
| Name | Description | Default value | Environment variables |
540+
|-----------------------------|-----------------------------|:-------------:|:----------------------:|
541+
| `--access-token="…"` (`-t`) | OpenStatus API Access Token | | `OPENSTATUS_API_TOKEN` |
542+
494543
### `run` command (aliases: `r`)
495544

496545
Run your uptime tests.

docs/openstatus.1

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1229,6 +1229,97 @@ T}@T{
12291229
\f[CR]OPENSTATUS_API_TOKEN\f[R]
12301230
T}
12311231
.TE
1232+
.SS \f[CR]notification\f[R] command (aliases: \f[CR]n\f[R])
1233+
Manage notifications.
1234+
.PP
1235+
Usage:
1236+
.IP
1237+
.EX
1238+
$ openstatus [GLOBAL FLAGS] notification [ARGUMENTS...]
1239+
.EE
1240+
.SS \f[CR]notification list\f[R] subcommand
1241+
List all notifications.
1242+
.RS
1243+
.PP
1244+
openstatus notification list openstatus notification list \(enlimit 10
1245+
.RE
1246+
.PP
1247+
Usage:
1248+
.IP
1249+
.EX
1250+
$ openstatus [GLOBAL FLAGS] notification list [COMMAND FLAGS] [ARGUMENTS...]
1251+
.EE
1252+
.PP
1253+
The following flags are supported:
1254+
.PP
1255+
.TS
1256+
tab(@);
1257+
lw(17.1n) lw(30.0n) cw(8.8n) cw(14.1n).
1258+
T{
1259+
Name
1260+
T}@T{
1261+
Description
1262+
T}@T{
1263+
Default value
1264+
T}@T{
1265+
Environment variables
1266+
T}
1267+
_
1268+
T{
1269+
\f[CR]\-\-access\-token=\(dq\&...\(dq\f[R] (\f[CR]\-t\f[R])
1270+
T}@T{
1271+
OpenStatus API Access Token
1272+
T}@T{
1273+
T}@T{
1274+
\f[CR]OPENSTATUS_API_TOKEN\f[R]
1275+
T}
1276+
T{
1277+
\f[CR]\-\-limit=\(dq\&...\(dq\f[R]
1278+
T}@T{
1279+
Maximum number of notifications to return (1\-100)
1280+
T}@T{
1281+
\f[CR]0\f[R]
1282+
T}@T{
1283+
\f[I]none\f[R]
1284+
T}
1285+
.TE
1286+
.SS \f[CR]notification info\f[R] subcommand
1287+
Get notification details.
1288+
.RS
1289+
.PP
1290+
openstatus notification info openstatus notification info 12345
1291+
.RE
1292+
.PP
1293+
Usage:
1294+
.IP
1295+
.EX
1296+
$ openstatus [GLOBAL FLAGS] notification info [COMMAND FLAGS] [ARGUMENTS...]
1297+
.EE
1298+
.PP
1299+
The following flags are supported:
1300+
.PP
1301+
.TS
1302+
tab(@);
1303+
lw(20.9n) lw(20.9n) cw(10.8n) cw(17.3n).
1304+
T{
1305+
Name
1306+
T}@T{
1307+
Description
1308+
T}@T{
1309+
Default value
1310+
T}@T{
1311+
Environment variables
1312+
T}
1313+
_
1314+
T{
1315+
\f[CR]\-\-access\-token=\(dq\&...\(dq\f[R] (\f[CR]\-t\f[R])
1316+
T}@T{
1317+
OpenStatus API Access Token
1318+
T}@T{
1319+
T}@T{
1320+
\f[CR]OPENSTATUS_API_TOKEN\f[R]
1321+
T}
1322+
.TE
12321323
.SS \f[CR]run\f[R] command (aliases: \f[CR]r\f[R])
12331324
Run your uptime tests.
12341325
.RS

internal/cmd/app.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"github.com/openstatusHQ/cli/internal/login"
1111
"github.com/openstatusHQ/cli/internal/maintenance"
1212
"github.com/openstatusHQ/cli/internal/monitors"
13+
"github.com/openstatusHQ/cli/internal/notification"
1314
"github.com/openstatusHQ/cli/internal/run"
1415
"github.com/openstatusHQ/cli/internal/statuspage"
1516
"github.com/openstatusHQ/cli/internal/statusreport"
@@ -71,6 +72,7 @@ https://docs.openstatus.dev | https://github.com/openstatusHQ/cli/issues/new`,
7172
statusreport.StatusReportCmd(),
7273
maintenance.MaintenanceCmd(),
7374
statuspage.StatusPageCmd(),
75+
notification.NotificationCmd(),
7476
run.RunCmd(),
7577
whoami.WhoamiCmd(),
7678
login.LoginCmd(),

internal/cmd/app_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,16 @@ func Test_NewApp(t *testing.T) {
3232
t.Run("Has expected commands", func(t *testing.T) {
3333
app := cmd.NewApp()
3434

35-
if len(app.Commands) != 9 {
36-
t.Errorf("Expected 9 commands, got %d", len(app.Commands))
35+
if len(app.Commands) != 10 {
36+
t.Errorf("Expected 10 commands, got %d", len(app.Commands))
3737
}
3838

3939
expectedCommands := map[string]bool{
4040
"monitors": false,
4141
"status-report": false,
4242
"maintenance": false,
4343
"status-page": false,
44+
"notification": false,
4445
"run": false,
4546
"whoami": false,
4647
"login": false,
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package notification
2+
3+
import (
4+
"net/http"
5+
6+
"buf.build/gen/go/openstatus/api/connectrpc/gosimple/openstatus/notification/v1/notificationv1connect"
7+
notificationv1 "buf.build/gen/go/openstatus/api/protocolbuffers/go/openstatus/notification/v1"
8+
"connectrpc.com/connect"
9+
"github.com/openstatusHQ/cli/internal/api"
10+
"github.com/urfave/cli/v3"
11+
)
12+
13+
func NewNotificationClient(apiKey string) notificationv1connect.NotificationServiceClient {
14+
return notificationv1connect.NewNotificationServiceClient(
15+
api.DefaultHTTPClient,
16+
api.ConnectBaseURL,
17+
connect.WithInterceptors(api.NewAuthInterceptor(apiKey)),
18+
connect.WithProtoJSON(),
19+
)
20+
}
21+
22+
func NewNotificationClientWithHTTPClient(httpClient *http.Client, apiKey string) notificationv1connect.NotificationServiceClient {
23+
return notificationv1connect.NewNotificationServiceClient(
24+
httpClient,
25+
api.ConnectBaseURL,
26+
connect.WithInterceptors(api.NewAuthInterceptor(apiKey)),
27+
connect.WithProtoJSON(),
28+
)
29+
}
30+
31+
func providerToString(p notificationv1.NotificationProvider) string {
32+
switch p {
33+
case notificationv1.NotificationProvider_NOTIFICATION_PROVIDER_DISCORD:
34+
return "discord"
35+
case notificationv1.NotificationProvider_NOTIFICATION_PROVIDER_EMAIL:
36+
return "email"
37+
case notificationv1.NotificationProvider_NOTIFICATION_PROVIDER_GOOGLE_CHAT:
38+
return "google_chat"
39+
case notificationv1.NotificationProvider_NOTIFICATION_PROVIDER_GRAFANA_ONCALL:
40+
return "grafana_oncall"
41+
case notificationv1.NotificationProvider_NOTIFICATION_PROVIDER_NTFY:
42+
return "ntfy"
43+
case notificationv1.NotificationProvider_NOTIFICATION_PROVIDER_PAGERDUTY:
44+
return "pagerduty"
45+
case notificationv1.NotificationProvider_NOTIFICATION_PROVIDER_OPSGENIE:
46+
return "opsgenie"
47+
case notificationv1.NotificationProvider_NOTIFICATION_PROVIDER_SLACK:
48+
return "slack"
49+
case notificationv1.NotificationProvider_NOTIFICATION_PROVIDER_SMS:
50+
return "sms"
51+
case notificationv1.NotificationProvider_NOTIFICATION_PROVIDER_TELEGRAM:
52+
return "telegram"
53+
case notificationv1.NotificationProvider_NOTIFICATION_PROVIDER_WEBHOOK:
54+
return "webhook"
55+
case notificationv1.NotificationProvider_NOTIFICATION_PROVIDER_WHATSAPP:
56+
return "whatsapp"
57+
default:
58+
return "unknown"
59+
}
60+
}
61+
62+
func opsgenieRegionToString(r notificationv1.OpsgenieRegion) string {
63+
switch r {
64+
case notificationv1.OpsgenieRegion_OPSGENIE_REGION_US:
65+
return "us"
66+
case notificationv1.OpsgenieRegion_OPSGENIE_REGION_EU:
67+
return "eu"
68+
default:
69+
return "unknown"
70+
}
71+
}
72+
73+
func NotificationCmd() *cli.Command {
74+
return &cli.Command{
75+
Name: "notification",
76+
Aliases: []string{"n"},
77+
Usage: "Manage notifications",
78+
Commands: []*cli.Command{
79+
GetNotificationListCmd(),
80+
GetNotificationInfoCmd(),
81+
},
82+
}
83+
}

0 commit comments

Comments
 (0)