1
0
Fork 0
mirror of https://github.com/miniflux/v2.git synced 2025-08-11 17:51:01 +00:00

feat(apprise): update SendNotification to handle multiple entries and add logging

This commit is contained in:
mrchi 2024-12-04 01:02:10 +08:00 committed by Frédéric Guillot
parent 3a18e5d205
commit 7bc0bffd85
2 changed files with 63 additions and 58 deletions

View file

@ -7,6 +7,7 @@ import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"fmt" "fmt"
"log/slog"
"net/http" "net/http"
"time" "time"
@ -26,43 +27,53 @@ func NewClient(serviceURL, baseURL string) *Client {
return &Client{serviceURL, baseURL} return &Client{serviceURL, baseURL}
} }
func (c *Client) SendNotification(entry *model.Entry) error { func (c *Client) SendNotification(feed *model.Feed, entries model.Entries) error {
if c.baseURL == "" || c.servicesURL == "" { if c.baseURL == "" || c.servicesURL == "" {
return fmt.Errorf("apprise: missing base URL or services URL") return fmt.Errorf("apprise: missing base URL or services URL")
} }
message := "[" + entry.Title + "]" + "(" + entry.URL + ")" + "\n\n" for _, entry := range entries {
apiEndpoint, err := urllib.JoinBaseURLAndPath(c.baseURL, "/notify") message := "[" + entry.Title + "]" + "(" + entry.URL + ")" + "\n\n"
if err != nil { apiEndpoint, err := urllib.JoinBaseURLAndPath(c.baseURL, "/notify")
return fmt.Errorf(`apprise: invalid API endpoint: %v`, err) if err != nil {
} return fmt.Errorf(`apprise: invalid API endpoint: %v`, err)
}
requestBody, err := json.Marshal(map[string]any{ requestBody, err := json.Marshal(map[string]any{
"urls": c.servicesURL, "urls": c.servicesURL,
"body": message, "body": message,
"title": entry.Feed.Title, "title": feed.Title,
}) })
if err != nil { if err != nil {
return fmt.Errorf("apprise: unable to encode request body: %v", err) return fmt.Errorf("apprise: unable to encode request body: %v", err)
} }
request, err := http.NewRequest(http.MethodPost, apiEndpoint, bytes.NewReader(requestBody)) request, err := http.NewRequest(http.MethodPost, apiEndpoint, bytes.NewReader(requestBody))
if err != nil { if err != nil {
return fmt.Errorf("apprise: unable to create request: %v", err) return fmt.Errorf("apprise: unable to create request: %v", err)
} }
request.Header.Set("Content-Type", "application/json") request.Header.Set("Content-Type", "application/json")
request.Header.Set("User-Agent", "Miniflux/"+version.Version) request.Header.Set("User-Agent", "Miniflux/"+version.Version)
httpClient := &http.Client{Timeout: defaultClientTimeout} slog.Debug("Sending Apprise notification",
response, err := httpClient.Do(request) slog.String("apprise_url", c.baseURL),
if err != nil { slog.String("services_url", c.servicesURL),
return fmt.Errorf("apprise: unable to send request: %v", err) slog.String("title", feed.Title),
} slog.String("body", message),
defer response.Body.Close() slog.String("entry_url", entry.URL),
)
if response.StatusCode >= 400 { httpClient := &http.Client{Timeout: defaultClientTimeout}
return fmt.Errorf("apprise: unable to send a notification: url=%s status=%d", apiEndpoint, response.StatusCode) response, err := httpClient.Do(request)
if err != nil {
return fmt.Errorf("apprise: unable to send request: %v", err)
}
defer response.Body.Close()
if response.StatusCode >= 400 {
return fmt.Errorf("apprise: unable to send a notification: url=%s status=%d", apiEndpoint, response.StatusCode)
}
} }
return nil return nil

View file

@ -513,8 +513,30 @@ func PushEntries(feed *model.Feed, entries model.Entries, userIntegrations *mode
} }
} }
if userIntegrations.AppriseEnabled {
slog.Debug("Sending new entries to Apprise",
slog.Int64("user_id", userIntegrations.UserID),
slog.Int("nb_entries", len(entries)),
slog.Int64("feed_id", feed.ID),
)
appriseServiceURLs := userIntegrations.AppriseServicesURL
if feed.AppriseServiceURLs != "" {
appriseServiceURLs = feed.AppriseServiceURLs
}
client := apprise.NewClient(
appriseServiceURLs,
userIntegrations.AppriseURL,
)
if err := client.SendNotification(feed, entries); err != nil {
slog.Warn("Unable to send new entries to Apprise", slog.Any("error", err))
}
}
// Integrations that only support sending individual entries // Integrations that only support sending individual entries
if userIntegrations.TelegramBotEnabled || userIntegrations.AppriseEnabled { if userIntegrations.TelegramBotEnabled {
for _, entry := range entries { for _, entry := range entries {
if userIntegrations.TelegramBotEnabled { if userIntegrations.TelegramBotEnabled {
slog.Debug("Sending a new entry to Telegram", slog.Debug("Sending a new entry to Telegram",
@ -541,35 +563,7 @@ func PushEntries(feed *model.Feed, entries model.Entries, userIntegrations *mode
) )
} }
} }
if userIntegrations.AppriseEnabled {
slog.Debug("Sending a new entry to Apprise",
slog.Int64("user_id", userIntegrations.UserID),
slog.Int64("entry_id", entry.ID),
slog.String("entry_url", entry.URL),
slog.String("apprise_url", userIntegrations.AppriseURL),
)
appriseServiceURLs := userIntegrations.AppriseServicesURL
if feed.AppriseServiceURLs != "" {
appriseServiceURLs = feed.AppriseServiceURLs
}
client := apprise.NewClient(
appriseServiceURLs,
userIntegrations.AppriseURL,
)
if err := client.SendNotification(entry); err != nil {
slog.Error("Unable to send entry to Apprise",
slog.Int64("user_id", userIntegrations.UserID),
slog.Int64("entry_id", entry.ID),
slog.String("entry_url", entry.URL),
slog.String("apprise_url", userIntegrations.AppriseURL),
slog.Any("error", err),
)
}
}
} }
} }
} }