[BREAKING] changed notification config format, support multiple notification providers, support webhook and markdown style notification

This commit is contained in:
yusing
2024-11-30 06:44:49 +08:00
parent fb9de4c4ad
commit 25eeabb9f9
12 changed files with 522 additions and 99 deletions

View File

@@ -2,19 +2,78 @@ package notif
import (
"context"
"fmt"
"io"
"net/http"
E "github.com/yusing/go-proxy/internal/error"
gphttp "github.com/yusing/go-proxy/internal/net/http"
U "github.com/yusing/go-proxy/internal/utils"
)
type (
Provider interface {
Name() string
Send(ctx context.Context, logMsg *LogMessage) error
URL() string
Method() string
Token() string
MIMEType() string
MakeBody(logMsg *LogMessage) (io.Reader, error)
makeRespError(resp *http.Response) error
}
ProviderCreateFunc func(map[string]any) (Provider, E.Error)
ProviderConfig map[string]any
)
const (
ProviderGotify = "gotify"
ProviderWebhook = "webhook"
)
var Providers = map[string]ProviderCreateFunc{
"gotify": newGotifyClient,
ProviderGotify: newNotifProvider[*GotifyClient],
ProviderWebhook: newNotifProvider[*Webhook],
}
func newNotifProvider[T Provider](cfg map[string]any) (Provider, E.Error) {
var client T
err := U.Deserialize(cfg, &client)
if err != nil {
return nil, err.Subject(client.Name())
}
return client, nil
}
func notifyProvider(ctx context.Context, provider Provider, msg *LogMessage) error {
body, err := provider.MakeBody(msg)
if err != nil {
return fmt.Errorf("%s error: %w", provider.Name(), err)
}
req, err := http.NewRequestWithContext(
ctx,
http.MethodPost,
provider.URL(),
body,
)
if err != nil {
return fmt.Errorf("%s error: %w", provider.Name(), err)
}
req.Header.Set("Content-Type", provider.MIMEType())
if provider.Token() != "" {
req.Header.Set("Authorization", "Bearer "+provider.Token())
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
return fmt.Errorf("%s error: %w", provider.Name(), err)
}
defer resp.Body.Close()
if !gphttp.IsSuccess(resp.StatusCode) {
return provider.makeRespError(resp)
}
return nil
}