// Copyright (C) 2025 wangyusong // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . package channel import ( "bytes" "context" "encoding/json" "net/http" "github.com/pkg/errors" "github.com/glidea/zenfeed/pkg/model" "github.com/glidea/zenfeed/pkg/notify/route" runtimeutil "github.com/glidea/zenfeed/pkg/util/runtime" ) type WebhookReceiver struct { URL string `json:"url"` } func (r *WebhookReceiver) Validate() error { if r.URL == "" { return errors.New("webhook.url is required") } return nil } type webhookBody struct { Group string `json:"group"` Labels model.Labels `json:"labels"` Feeds []*route.Feed `json:"feeds"` } func newWebhook() sender { return &webhook{ httpClient: &http.Client{}, } } type webhook struct { httpClient *http.Client } func (w *webhook) Send(ctx context.Context, receiver Receiver, group *route.FeedGroup) error { // Prepare request. body := &webhookBody{ Group: group.Name, Labels: group.Labels, Feeds: group.Feeds, } b := runtimeutil.Must1(json.Marshal(body)) req, err := http.NewRequestWithContext(ctx, http.MethodPost, receiver.Webhook.URL, bytes.NewReader(b)) if err != nil { return errors.Wrap(err, "create request") } req.Header.Set("Content-Type", "application/json") // Send request. resp, err := w.httpClient.Do(req) if err != nil { return errors.Wrap(err, "send request") } defer func() { _ = resp.Body.Close() }() // Handle response. if resp.StatusCode != http.StatusOK { return errors.New("send request") } return nil }