yoake/internal/comm/gotify/send.go

104 lines
2.6 KiB
Go

package gotify
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"time"
"github.com/eternal-flame-AD/yoake/config"
"github.com/eternal-flame-AD/yoake/internal/comm/model"
"github.com/eternal-flame-AD/yoake/internal/echoerror"
)
type Client struct {
conf *config.CommGotify
httpClient *http.Client
baseURL url.URL
serverVersion Version
}
func NewClient() (*Client, error) {
conf := config.Config().Comm.Gotify
baseURL, err := url.Parse(conf.BaseURL)
if err != nil {
return nil, err
}
httpClient := &http.Client{
Timeout: 10 * time.Second,
}
resp, err := httpClient.Get(baseURL.ResolveReference(urlVersion).String())
if err != nil {
return nil, fmt.Errorf("failed to obtain gotify version: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("gotify returned with %d", resp.StatusCode)
}
var version Version
if err := json.NewDecoder(resp.Body).Decode(&version); err != nil {
return nil, fmt.Errorf("failed to decode gotify version: %w", err)
}
resp, err = httpClient.Get(baseURL.ResolveReference(urlHealth).String())
if err != nil {
return nil, fmt.Errorf("failed to obtain gotify health: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("gotify returned with %d", resp.StatusCode)
}
var health Health
if err := json.NewDecoder(resp.Body).Decode(&health); err != nil {
return nil, fmt.Errorf("failed to decode gotify health: %w", err)
}
return &Client{
conf: &conf,
httpClient: httpClient,
baseURL: *baseURL,
serverVersion: version,
}, nil
}
func (c *Client) SendGenericMessage(gmsg *model.GenericMessage) error {
msg := Message{
Message: gmsg.Body,
Title: gmsg.Subject,
Priority: gmsg.Priority + 5,
}
msg.Extras.ClientDisplay.ContentType = gmsg.MIME
return c.SendMessage(msg)
}
func (c *Client) SupportedMIME() []string {
return []string{"text/plain", "text/markdown"}
}
func (c *Client) SendMessage(msg Message) error {
reader, writer := io.Pipe()
e := json.NewEncoder(writer)
req, err := http.NewRequest("POST", c.baseURL.ResolveReference(urlMessage).String(), reader)
if err != nil {
return err
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("X-Gotify-Key", c.conf.AppToken)
go func() {
defer writer.Close()
e.Encode(msg)
}()
resp, err := c.httpClient.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return echoerror.NewHttp(resp.StatusCode, fmt.Errorf("gotify returned with %d", resp.StatusCode))
}
return nil
}