go-nativenotify

Native notifications in Go
Log | Files | Refs | README | LICENSE

notify_linux.go (1664B)


      1 package nativenotify
      2 
      3 import (
      4 	"fmt"
      5 	"strconv"
      6 	"sync/atomic"
      7 
      8 	"git.sr.ht/~whereswaldon/shout"
      9 	"github.com/godbus/dbus/v5"
     10 )
     11 
     12 var notifier atomic.Pointer[shout.Notifier]
     13 
     14 func setup(cfg Config) error {
     15 	conn, err := dbus.SessionBus()
     16 	if err != nil {
     17 		return fmt.Errorf("getting dbus session: %w", err)
     18 	}
     19 
     20 	n, err := shout.NewNotifier(
     21 		conn,
     22 		cfg.Linux.AppName,
     23 		cfg.Linux.AppIcon,
     24 		func(id, action string, platformData map[string]dbus.Variant, target, response dbus.Variant, err error) {
     25 			fn, ok := callbacksTake(&callbacks, id)
     26 			if !ok || fn == nil {
     27 				return
     28 			}
     29 			fn(action, target.String())
     30 		},
     31 	)
     32 	if err != nil {
     33 		return fmt.Errorf("building notifier: %w", err)
     34 	}
     35 
     36 	notifier.Store(&n)
     37 
     38 	return nil
     39 }
     40 
     41 func push(n Notification) (err error) {
     42 	notifier := notifier.Load()
     43 
     44 	if notifier == nil {
     45 		return fmt.Errorf("notifier is nil, call setup to initialize")
     46 	}
     47 
     48 	id := nextID.Add(1)
     49 
     50 	buttons := []shout.Button{}
     51 
     52 	for _, a := range n.ButtonActions {
     53 		buttons = append(buttons, shout.Button{
     54 			Action: a.ID,
     55 			Label:  a.LabelText,
     56 			Target: a.Value,
     57 		})
     58 	}
     59 
     60 	if err := (*notifier).Send(fmt.Sprintf("%d", id), shout.Notification{
     61 		Title:               n.Title,
     62 		Body:                n.Body,
     63 		ReplaceID:           "",
     64 		Markup:              false,
     65 		IconPath:            n.Icon,
     66 		Priority:            shout.Normal,
     67 		DefaultAction:       "default",
     68 		DefaultActionLabel:  "",
     69 		DefaultActionTarget: dbus.Variant{},
     70 		Buttons:             buttons,
     71 		ExpirationTimeout:   0,
     72 	}); err != nil {
     73 		return fmt.Errorf("sending notification: %w", err)
     74 	}
     75 
     76 	callbacksPut(&callbacks, strconv.FormatInt(id, 10), n.Callback)
     77 
     78 	return nil
     79 }