70 lines
1.7 KiB
Go
70 lines
1.7 KiB
Go
package push
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"net/url"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
const defaultBarkServer = "https://api.day.app"
|
|
|
|
// BarkConfig 是 iOS Bark 推送的配置。
|
|
type BarkConfig struct {
|
|
DeviceKey string
|
|
Server string // 可选,默认 https://api.day.app
|
|
}
|
|
|
|
// BarkProvider 实现了通过 Bark 发送 iOS 推送。
|
|
type BarkProvider struct {
|
|
deviceKey string
|
|
server string
|
|
client *http.Client
|
|
}
|
|
|
|
// NewBarkProvider 创建 Bark 推送 Provider。
|
|
// DeviceKey 为空时返回 ErrProviderConfigInvalid。
|
|
func NewBarkProvider(cfg BarkConfig) (*BarkProvider, error) {
|
|
if strings.TrimSpace(cfg.DeviceKey) == "" {
|
|
return nil, ErrProviderConfigInvalid
|
|
}
|
|
server := strings.TrimSpace(cfg.Server)
|
|
if server == "" {
|
|
server = defaultBarkServer
|
|
}
|
|
server = strings.TrimRight(server, "/")
|
|
return &BarkProvider{
|
|
deviceKey: strings.TrimSpace(cfg.DeviceKey),
|
|
server: server,
|
|
client: &http.Client{Timeout: 10 * time.Second},
|
|
}, nil
|
|
}
|
|
|
|
func (p *BarkProvider) Name() string { return "bark" }
|
|
|
|
func (p *BarkProvider) Send(ctx context.Context, msg Message) error {
|
|
title := url.PathEscape(msg.Title)
|
|
body := url.PathEscape(msg.Content)
|
|
reqURL := fmt.Sprintf("%s/%s/%s/%s", p.server, p.deviceKey, title, body)
|
|
|
|
req, err := http.NewRequestWithContext(ctx, http.MethodPost, reqURL, nil)
|
|
if err != nil {
|
|
return fmt.Errorf("bark: create request: %w", err)
|
|
}
|
|
|
|
resp, err := p.client.Do(req)
|
|
if err != nil {
|
|
return fmt.Errorf("bark: send failed: %w", err)
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode >= 400 {
|
|
bodyBytes, _ := io.ReadAll(resp.Body)
|
|
return fmt.Errorf("bark: http %d: %s", resp.StatusCode, string(bodyBytes))
|
|
}
|
|
return nil
|
|
}
|