diff --git a/README.md b/README.md index 282e6e2f..955bc5c9 100644 --- a/README.md +++ b/README.md @@ -1229,17 +1229,18 @@ endpoints: #### Configuring Pushover alerts -| Parameter | Description | Default | -|:--------------------------------------|:------------------------------------------------------------------------------------------------|:-----------------------------| -| `alerting.pushover` | Configuration for alerts of type `pushover` | `{}` | -| `alerting.pushover.application-token` | Pushover application token | `""` | -| `alerting.pushover.user-key` | User or group key | `""` | -| `alerting.pushover.title` | Fixed title for all messages sent via Pushover | `"Gatus: "` | -| `alerting.pushover.priority` | Priority of all messages, ranging from -2 (very low) to 2 (emergency) | `0` | -| `alerting.pushover.resolved-priority` | Override the priority of messages on resolved, ranging from -2 (very low) to 2 (emergency) | `0` | -| `alerting.pushover.sound` | Sound of all messages
See [sounds](https://pushover.net/api#sounds) for all valid choices. | `""` | -| `alerting.pushover.ttl` | Set the Time-to-live of the message to be automatically deleted from pushover notifications | `0` | -| `alerting.pushover.default-alert` | Default alert configuration.
See [Setting a default alert](#setting-a-default-alert) | N/A | +| Parameter | Description | Default | +|:--------------------------------------|:---------------------------------------------------------------------------------------------------------|:----------------------------| +| `alerting.pushover` | Configuration for alerts of type `pushover` | `{}` | +| `alerting.pushover.application-token` | Pushover application token | `""` | +| `alerting.pushover.user-key` | User or group key | `""` | +| `alerting.pushover.title` | Fixed title for all messages sent via Pushover | `"Gatus: "` | +| `alerting.pushover.priority` | Priority of all messages, ranging from -2 (very low) to 2 (emergency) | `0` | +| `alerting.pushover.resolved-priority` | Override the priority of messages on resolved, ranging from -2 (very low) to 2 (emergency) | `0` | +| `alerting.pushover.sound` | Sound of all messages
See [sounds](https://pushover.net/api#sounds) for all valid choices. | `""` | +| `alerting.pushover.ttl` | Set the Time-to-live of the message to be automatically deleted from pushover notifications | `0` | +| `alerting.pushover.device` | Device to send the message to (optional)
See [devices](https://pushover.net/api#identifiers) for details | `""` (all devices)| +| `alerting.pushover.default-alert` | Default alert configuration.
See [Setting a default alert](#setting-a-default-alert) | N/A | ```yaml alerting: diff --git a/alerting/provider/pushover/pushover.go b/alerting/provider/pushover/pushover.go index a3935d77..efa3be6d 100644 --- a/alerting/provider/pushover/pushover.go +++ b/alerting/provider/pushover/pushover.go @@ -23,6 +23,7 @@ var ( ErrInvalidApplicationToken = errors.New("application-token must be 30 characters long") ErrInvalidUserKey = errors.New("user-key must be 30 characters long") ErrInvalidPriority = errors.New("priority and resolved-priority must be between -2 and 2") + ErrInvalidDevice = errors.New("device name must have 25 characters or less") ) type Config struct { @@ -53,6 +54,10 @@ type Config struct { // If priority is 2 then this parameter is ignored // default: 0 TTL int `yaml:"ttl,omitempty"` + + // Device to send the message to (see: https://pushover.net/api#devices) + // default: "" (all devices) + Device string `yaml:"device,omitempty"` } func (cfg *Config) Validate() error { @@ -71,6 +76,9 @@ func (cfg *Config) Validate() error { if cfg.Priority < -2 || cfg.Priority > 2 || cfg.ResolvedPriority < -2 || cfg.ResolvedPriority > 2 { return ErrInvalidPriority } + if len(cfg.Device) > 25 { + return ErrInvalidDevice + } return nil } @@ -96,6 +104,9 @@ func (cfg *Config) Merge(override *Config) { if override.TTL > 0 { cfg.TTL = override.TTL } + if len(override.Device) > 0 { + cfg.Device = override.Device + } } // AlertProvider is the configuration necessary for sending an alert using Pushover @@ -145,6 +156,7 @@ type Body struct { Html int `json:"html"` Sound string `json:"sound,omitempty"` TTL int `json:"ttl,omitempty"` + Device string `json:"device,omitempty"` } // buildRequestBody builds the request body for the provider @@ -183,6 +195,7 @@ func (provider *AlertProvider) buildRequestBody(cfg *Config, ep *endpoint.Endpoi Html: 1, Sound: cfg.Sound, TTL: cfg.TTL, + Device: cfg.Device, }) return body } diff --git a/alerting/provider/pushover/pushover_test.go b/alerting/provider/pushover/pushover_test.go index 7131d91b..4ced2e89 100644 --- a/alerting/provider/pushover/pushover_test.go +++ b/alerting/provider/pushover/pushover_test.go @@ -176,6 +176,13 @@ func TestAlertProvider_buildRequestBody(t *testing.T) { Resolved: true, ExpectedBody: "{\"token\":\"TokenWithLengthOf30Characters2\",\"user\":\"TokenWithLengthOf30Characters5\",\"title\":\"Gatus Notifications\",\"message\":\"An alert for \\u003cb\\u003eendpoint-name\\u003c/b\\u003e has been resolved after passing successfully 5 time(s) in a row with the following description: description-2\\n✅ - [CONNECTED] == true\\n✅ - [STATUS] == 200\",\"priority\":2,\"html\":1,\"ttl\":3600}", }, + { + Name: "with-device", + Provider: AlertProvider{DefaultConfig: Config{ApplicationToken: "TokenWithLengthOf30Characters2", UserKey: "TokenWithLengthOf30Characters5", Title: "Gatus Notifications", Priority: 2, ResolvedPriority: 2, TTL: 3600, Device: "iphone15pro",}}, + Alert: alert.Alert{Description: &secondDescription, SuccessThreshold: 5, FailureThreshold: 3}, + Resolved: true, + ExpectedBody: "{\"token\":\"TokenWithLengthOf30Characters2\",\"user\":\"TokenWithLengthOf30Characters5\",\"title\":\"Gatus Notifications\",\"message\":\"An alert for \\u003cb\\u003eendpoint-name\\u003c/b\\u003e has been resolved after passing successfully 5 time(s) in a row with the following description: description-2\\n✅ - [CONNECTED] == true\\n✅ - [STATUS] == 200\",\"priority\":2,\"html\":1,\"ttl\":3600,\"device\":\"iphone15pro\"}", + }, } for _, scenario := range scenarios { t.Run(scenario.Name, func(t *testing.T) {