1
0
Fork 0
golang-github-nicholas-fedo.../pkg/services/join/join.go
Daniel Baumann c0c4addb85
Adding upstream version 0.8.9.
Signed-off-by: Daniel Baumann <daniel@debian.org>
2025-05-22 10:16:14 +02:00

119 lines
2.6 KiB
Go

package join
import (
"context"
"errors"
"fmt"
"net/http"
"net/url"
"strings"
"github.com/nicholas-fedor/shoutrrr/pkg/format"
"github.com/nicholas-fedor/shoutrrr/pkg/services/standard"
"github.com/nicholas-fedor/shoutrrr/pkg/types"
)
const (
// hookURL defines the Join API endpoint for sending push notifications.
hookURL = "https://joinjoaomgcd.appspot.com/_ah/api/messaging/v1/sendPush"
contentType = "text/plain"
)
// ErrSendFailed indicates a failure to send a notification to Join devices.
var ErrSendFailed = errors.New("failed to send notification to join devices")
// Service sends notifications to Join devices.
type Service struct {
standard.Standard
Config *Config
pkr format.PropKeyResolver
}
// Send delivers a notification message to Join devices.
func (service *Service) Send(message string, params *types.Params) error {
config := service.Config
if params == nil {
params = &types.Params{}
}
title, found := (*params)["title"]
if !found {
title = config.Title
}
icon, found := (*params)["icon"]
if !found {
icon = config.Icon
}
devices := strings.Join(config.Devices, ",")
return service.sendToDevices(devices, message, title, icon)
}
func (service *Service) sendToDevices(devices, message, title, icon string) error {
config := service.Config
apiURL, err := url.Parse(hookURL)
if err != nil {
return fmt.Errorf("parsing Join API URL: %w", err)
}
data := url.Values{}
data.Set("deviceIds", devices)
data.Set("apikey", config.APIKey)
data.Set("text", message)
if len(title) > 0 {
data.Set("title", title)
}
if len(icon) > 0 {
data.Set("icon", icon)
}
apiURL.RawQuery = data.Encode()
req, err := http.NewRequestWithContext(
context.Background(),
http.MethodPost,
apiURL.String(),
nil,
)
if err != nil {
return fmt.Errorf("creating HTTP request: %w", err)
}
req.Header.Set("Content-Type", contentType)
res, err := http.DefaultClient.Do(req)
if err != nil {
return fmt.Errorf("sending HTTP request to Join: %w", err)
}
defer res.Body.Close()
if res.StatusCode != http.StatusOK {
return fmt.Errorf("%w: %q, response status %q", ErrSendFailed, devices, res.Status)
}
return nil
}
// Initialize configures the service with a URL and logger.
func (service *Service) Initialize(configURL *url.URL, logger types.StdLogger) error {
service.SetLogger(logger)
service.Config = &Config{}
service.pkr = format.NewPropKeyResolver(service.Config)
if err := service.Config.setURL(&service.pkr, configURL); err != nil {
return err
}
return nil
}
// GetID returns the identifier for this service.
func (service *Service) GetID() string {
return Scheme
}