Skip to content

Commit 0b4542b

Browse files
committed
feat: add Pushover notification support
Add Pushover alert integration to enable task status notifications through the Pushover service. This includes configuration options in the interactive setup, alert sending functionality, and template support for customized alert messages. The implementation follows the existing pattern used for other notification providers like Gotify and Microsoft Teams
1 parent be38176 commit 0b4542b

6 files changed

Lines changed: 88 additions & 1 deletion

File tree

cli/setup/setup.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,12 @@ func InteractiveSetup(conf *util.ConfigType) {
170170
askValue("Microsoft Teams Webhook URL", "", &conf.MicrosoftTeamsUrl)
171171
}
172172

173+
askConfirmation("Enable Pushover alerts?", false, &conf.PushoverAlert)
174+
if conf.PushoverAlert {
175+
askValue("Pushover User KEY", "", &conf.PushoverUserKey)
176+
askValue("Pushover Token", "", &conf.PushoverToken)
177+
}
178+
173179
askConfirmation("Enable LDAP authentication?", false, &conf.LdapEnable)
174180
if conf.LdapEnable {
175181
conf.LdapMappings = &util.LdapMappings{}

services/tasks/TaskRunner_logging.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ func (t *TaskRunner) SetStatus(status task_logger.TaskStatus) {
128128
t.sendMicrosoftTeamsAlert()
129129
t.sendDingTalkAlert()
130130
t.sendGotifyAlert()
131+
t.sendPushoverAlert()
131132
}
132133

133134
for _, l := range t.statusListeners {

services/tasks/alert.go

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ type alertTask struct {
3232
Result string
3333
Desc string
3434
Version string
35+
Status string
3536
}
3637

3738
type alertChat struct {
@@ -504,6 +505,73 @@ func (t *TaskRunner) sendGotifyAlert() {
504505
}
505506
}
506507

508+
func (t *TaskRunner) sendPushoverAlert() {
509+
if !util.Config.PushoverAlert || !t.alert {
510+
return
511+
}
512+
513+
if t.Template.SuppressSuccessAlerts && t.Task.Status == task_logger.TaskSuccessStatus {
514+
return
515+
}
516+
517+
body := bytes.NewBufferString("")
518+
author, version := t.alertInfos()
519+
520+
alert := Alert{
521+
Name: t.Template.Name,
522+
Author: author,
523+
Color: t.alertColor("pushover"),
524+
Task: alertTask{
525+
ID: strconv.Itoa(t.Task.ID),
526+
URL: t.taskLink(),
527+
Result: t.Task.Status.Format(),
528+
Version: version,
529+
Desc: t.Task.Message,
530+
Status: string(t.Task.Status),
531+
},
532+
}
533+
534+
tpl, err := template.ParseFS(templates, "templates/pushover.tmpl")
535+
536+
if err != nil {
537+
t.Log("Can't parse pushover alert template!")
538+
panic(err)
539+
}
540+
541+
if err := tpl.Execute(body, alert); err != nil {
542+
t.Log("Can't generate pushover alert template!")
543+
panic(err)
544+
}
545+
546+
if body.Len() == 0 {
547+
t.Log("Buffer for pushover alert is empty")
548+
return
549+
}
550+
551+
t.Log("Attempting to send pushover alert")
552+
553+
resp, err := http.Post(
554+
fmt.Sprintf(
555+
"https://api.pushover.net/1/messages.json?user=%s&token=%s",
556+
util.Config.PushoverUserKey,
557+
util.Config.PushoverToken),
558+
"application/json",
559+
body,
560+
)
561+
562+
if err != nil {
563+
t.Log("Can't send pushover alert! Error: " + err.Error())
564+
} else if resp.StatusCode != 200 {
565+
t.Log("Can't send pushover alert! Response code: " + strconv.Itoa(resp.StatusCode))
566+
} else {
567+
t.Log("Sent successfully pushover alert")
568+
}
569+
570+
if resp != nil {
571+
defer resp.Body.Close() //nolint:errcheck
572+
}
573+
}
574+
507575
func (t *TaskRunner) alertInfos() (string, string) {
508576
version := ""
509577

@@ -552,7 +620,7 @@ func (t *TaskRunner) alertColor(kind string) string {
552620
case task_logger.TaskStoppedStatus:
553621
return "#5B5B5B"
554622
}
555-
case "rocketchat":
623+
case "rocketchat", "pushover":
556624
switch t.Task.Status {
557625
case task_logger.TaskSuccessStatus:
558626
return "#00EE00"

services/tasks/alert_test_sender.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ func SendProjectTestAlerts(project db.Project, store db.Store) (err error) {
4646
tr.sendMicrosoftTeamsAlert()
4747
tr.sendDingTalkAlert()
4848
tr.sendGotifyAlert()
49+
tr.sendPushoverAlert()
4950
tr.sendMailAlert()
5051

5152
return
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"html": 1,
3+
"priority": {{ if eq .Task.Status "error" }}1{{ else }}0{{ end }},
4+
"title": "Task: {{ .Name }}",
5+
"message": "Execution #: {{ .Task.ID }}\n<font color=\"{{ .Color }}\"><b>{{ .Task.Result }}</b></font>\n{{ if .Task.Version }}Version: {{ .Task.Version }}\n{{ end }}\nDescription: {{ .Task.Desc }}\nAuthor: {{ .Author }}",
6+
"url": "{{ .Task.URL }}",
7+
"url_title": "Task URL"
8+
}

util/config.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,9 @@ type ConfigType struct {
287287
GotifyAlert bool `json:"gotify_alert,omitempty" env:"SEMAPHORE_GOTIFY_ALERT"`
288288
GotifyUrl string `json:"gotify_url,omitempty" env:"SEMAPHORE_GOTIFY_URL"`
289289
GotifyToken string `json:"gotify_token,omitempty" env:"SEMAPHORE_GOTIFY_TOKEN"`
290+
PushoverAlert bool `json:"pushover_alert,omitempty" env:"SEMAPHORE_PUSHOVER_ALERT"`
291+
PushoverUserKey string `json:"pushover_user_key,omitempty" env:"SEMAPHORE_PUSHOVER_USER_KEY"`
292+
PushoverToken string `json:"pushover_token,omitempty" env:"SEMAPHORE_PUSHOVER_TOKEN"`
290293

291294
// oidc settings
292295
OidcProviders map[string]OidcProvider `json:"oidc_providers,omitempty" env:"SEMAPHORE_OIDC_PROVIDERS"`

0 commit comments

Comments
 (0)