mirror of
https://github.com/nikoksr/notify.git
synced 2025-02-09 13:13:44 +02:00
refactor(service): normalize and clean-up bark service
This commit is contained in:
parent
8fdd3c24dc
commit
db2e5884c2
@ -5,18 +5,24 @@
|
||||
## Usage
|
||||
|
||||
```go
|
||||
// Create a bark service. `device key` is generated when you install the application
|
||||
barkService := bark.New("your bark device key", bark.DefaultServer)
|
||||
// Create a bark service. `device key` is generated when you install the application. You can use the
|
||||
// `bark.NewWithServers()` function to create a service with a custom server.
|
||||
barkService := bark.NewWithServers("your bark device key", bark.DefaultServerURL)
|
||||
|
||||
// Tell our notifier to use the bark service. You can repeat the above process
|
||||
// for as many services as you like and just tell the notifier to use them.
|
||||
// Or use `bark.New()` to create a service with the default server.
|
||||
barkService = bark.New("your bark device key")
|
||||
|
||||
// Add more servers
|
||||
barkService.AddReceivers("https://your-bark-server.com")
|
||||
|
||||
// Tell our notifier to use the bark service.
|
||||
notify.UseServices(barkService)
|
||||
|
||||
// Send a test message.
|
||||
_ = notify.Send(
|
||||
context.Background(),
|
||||
"Subject/Title",
|
||||
"The actual message - Hello, you awesome gophers! :)",
|
||||
context.Background(),
|
||||
"Subject/Title",
|
||||
"The actual message - Hello, you awesome gophers! :)",
|
||||
)
|
||||
```
|
||||
|
||||
|
@ -7,6 +7,8 @@ import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
@ -14,80 +16,150 @@ import (
|
||||
|
||||
// Service allow you to configure Bark service.
|
||||
type Service struct {
|
||||
Server string
|
||||
DeviceKey string
|
||||
url string
|
||||
deviceKey string
|
||||
client *http.Client
|
||||
serverURLs []string
|
||||
}
|
||||
|
||||
// DefaultServer is the default server to use for the bark service.
|
||||
const DefaultServer = "api.day.app"
|
||||
func defaultHTTPClient() *http.Client {
|
||||
return &http.Client{
|
||||
Timeout: 5 * time.Second,
|
||||
}
|
||||
}
|
||||
|
||||
// New returns a new instance of Bark service.
|
||||
func New(deviceKey, server string) *Service {
|
||||
p := &Service{
|
||||
Server: server,
|
||||
DeviceKey: deviceKey,
|
||||
// DefaultServerURL is the default server to use for the bark service.
|
||||
const DefaultServerURL = "https://api.day.app/"
|
||||
|
||||
// normalizeServerURL normalizes the server URL. It prefixes it with https:// if it's not already and appends a slash
|
||||
// if it's not already there. If the serverURL is empty, the DefaultServerURL is used. We're not validating the url here
|
||||
// on purpose, we leave that to the http client.
|
||||
func normalizeServerURL(serverURL string) string {
|
||||
if serverURL == "" {
|
||||
return DefaultServerURL
|
||||
}
|
||||
if server != "" {
|
||||
p.url = fmt.Sprintf("https://%s/push", server)
|
||||
} else {
|
||||
p.url = fmt.Sprintf("https://%s/push", "api.day.app")
|
||||
|
||||
// Normalize the url
|
||||
if !strings.HasPrefix(serverURL, "http") {
|
||||
serverURL = "https://" + serverURL
|
||||
}
|
||||
return p
|
||||
if !strings.HasSuffix(serverURL, "/") {
|
||||
serverURL = serverURL + "/"
|
||||
}
|
||||
|
||||
return serverURL
|
||||
}
|
||||
|
||||
// AddReceivers adds server URLs to the list of servers to use for sending messages. We call it Receivers and not
|
||||
// servers because strictly speaking, the server is still receiving the message, and additionally we're following the
|
||||
// naming convention of the other services.
|
||||
func (s *Service) AddReceivers(serverURLs ...string) {
|
||||
for _, serverURL := range serverURLs {
|
||||
serverURL = normalizeServerURL(serverURL)
|
||||
s.serverURLs = append(s.serverURLs, serverURL)
|
||||
}
|
||||
}
|
||||
|
||||
// NewWithServers returns a new instance of Bark service. You can use this service to send messages to bark. You can
|
||||
// specify the servers to send the messages to. By default, the service will use the default server
|
||||
// (https://api.day.app/) if you don't specify any servers.
|
||||
func NewWithServers(deviceKey string, serverURLs ...string) *Service {
|
||||
s := &Service{
|
||||
deviceKey: deviceKey,
|
||||
client: defaultHTTPClient(),
|
||||
}
|
||||
|
||||
if len(serverURLs) > 0 {
|
||||
serverURLs = append(serverURLs, DefaultServerURL)
|
||||
}
|
||||
|
||||
// Calling service.AddReceivers() instead of directly setting the serverURLs because we want to normalize the URLs.
|
||||
s.AddReceivers(serverURLs...)
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
// New returns a new instance of Bark service. You can use this service to send messages to bark. By default, the
|
||||
// service will use the default server (https://api.day.app/).
|
||||
func New(deviceKey string) *Service {
|
||||
return NewWithServers(deviceKey)
|
||||
}
|
||||
|
||||
// postData is the data to send to the bark server.
|
||||
type postData struct {
|
||||
DeviceKey string `json:"device_key"`
|
||||
Title string `json:"title"`
|
||||
Body string `json:"body,omitempty"`
|
||||
Badge int `json:"badge,omitempty"`
|
||||
Sound string `json:"sound,omitempty"`
|
||||
Icon string `json:"icon,omitempty"`
|
||||
Group string `json:"group,omitempty"`
|
||||
URL string `json:"pushURL,omitempty"`
|
||||
}
|
||||
|
||||
func (s *Service) send(ctx context.Context, serverURL, subject, content string) (err error) {
|
||||
if serverURL == "" {
|
||||
return errors.New("server url is empty")
|
||||
}
|
||||
|
||||
// Marshal the message to post
|
||||
message := &postData{
|
||||
DeviceKey: s.deviceKey,
|
||||
Title: subject,
|
||||
Body: content,
|
||||
Sound: "alarm.caf",
|
||||
}
|
||||
|
||||
messageJSON, err := json.Marshal(message)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "marshal message")
|
||||
}
|
||||
|
||||
// Create new request
|
||||
pushURL := filepath.Join(serverURL, "push")
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodPost, pushURL, bytes.NewBuffer(messageJSON))
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "create request")
|
||||
}
|
||||
|
||||
req.Header.Set("Content-Type", "application/json; charset=utf-8")
|
||||
|
||||
// Send request
|
||||
resp, err := s.client.Do(req)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "send request")
|
||||
}
|
||||
defer func() { _ = resp.Body.Close() }()
|
||||
|
||||
// Read response and verify success
|
||||
result, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "read response")
|
||||
}
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return fmt.Errorf("bark returned status code %d: %s", resp.StatusCode, string(result))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Send takes a message subject and a message content and sends them to bark application.
|
||||
func (p *Service) Send(ctx context.Context, subject, content string) error {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
default:
|
||||
type postData struct {
|
||||
DeviceKey string `json:"device_key"`
|
||||
Title string `json:"title"`
|
||||
Body string `json:"body,omitempty"`
|
||||
Badge int `json:"badge,omitempty"`
|
||||
Sound string `json:"sound,omitempty"`
|
||||
Icon string `json:"icon,omitempty"`
|
||||
Group string `json:"group,omitempty"`
|
||||
URL string `json:"url,omitempty"`
|
||||
}
|
||||
pd := &postData{
|
||||
DeviceKey: p.DeviceKey,
|
||||
Title: subject,
|
||||
Body: content,
|
||||
Sound: "alarm.caf",
|
||||
}
|
||||
data, err := json.Marshal(pd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req, err := http.NewRequestWithContext(ctx, "POST", p.url, bytes.NewBuffer(data))
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to create bark request")
|
||||
}
|
||||
|
||||
req.Header.Set("Content-Type", "application/json; charset=utf-8")
|
||||
httpClient := &http.Client{
|
||||
Timeout: time.Second * 5,
|
||||
}
|
||||
resp, err := httpClient.Do(req)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "send bark request failed")
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
result, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
err = fmt.Errorf("statusCode: %d, body: %v", resp.StatusCode, string(result))
|
||||
return errors.Wrap(err, "send bark message failed")
|
||||
}
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to send message")
|
||||
}
|
||||
return nil
|
||||
func (s *Service) Send(ctx context.Context, subject, content string) error {
|
||||
if s.client == nil {
|
||||
return errors.New("client is nil")
|
||||
}
|
||||
|
||||
for _, serverURL := range s.serverURLs {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
default:
|
||||
err := s.send(ctx, serverURL, subject, content)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to send message to bark server %q", serverURL)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
34
service/bark/doc.go
Normal file
34
service/bark/doc.go
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
Package bark provides a service for sending messages to bark.
|
||||
|
||||
Usage:
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
|
||||
"github.com/nikoksr/notify"
|
||||
"github.com/nikoksr/notify/service/bark"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Create a bark service. `device key` is generated when you install the application. You can use the
|
||||
// `bark.NewWithServers` function to create a service with a custom server.
|
||||
barkService := bark.NewWithServers("your bark device key", bark.DefaultServerURL)
|
||||
|
||||
// Or use `bark.New` to create a service with the default server.
|
||||
barkService = bark.New("your bark device key")
|
||||
|
||||
// Tell our notifier to use the bark service.
|
||||
notify.UseServices(barkService)
|
||||
|
||||
// Send a test message.
|
||||
_ = notify.Send(
|
||||
context.Background(),
|
||||
"Subject/Title",
|
||||
"The actual message - Hello, you awesome gophers! :)",
|
||||
)
|
||||
}
|
||||
*/
|
||||
package bark
|
Loading…
x
Reference in New Issue
Block a user