BareRTC/pkg/webhooks.go
Noah Petherbridge 859e9dee5b Send admin reports on /nsfw command + Fixes
* On the /nsfw command, BareRTC will issue an admin report to your main website
  so you have visibility into when this command is used.
* On the server side, fix the "Open" command so it will prevent webcams from
  connecting if the offerer had been Booted by the answerer, in addition to the
  previous blocks about Mute and Block. Admin users can still connect always.
* Add a debug command `/watch username` to manually open somebody's camera on
  chat. Note: the chat server enforces the permission to actually do so.
* Remove the /debug-dangerous-force-deadlock admin command.
2025-02-17 12:50:06 -08:00

94 lines
2.2 KiB
Go

package barertc
import (
"bytes"
"encoding/json"
"errors"
"io"
"net/http"
"time"
"git.kirsle.net/apps/barertc/pkg/config"
"git.kirsle.net/apps/barertc/pkg/log"
)
// The available and supported webhook event names.
const (
WebhookReport = "report"
)
// WebhookEnabled checks if the named webhook is enabled.
func WebhookEnabled(name string) bool {
for _, webhook := range config.Current.WebhookURLs {
if webhook.Name == name && webhook.Enabled {
return true
}
}
return false
}
// GetWebhook gets a configured webhook.
func GetWebhook(name string) (config.WebhookURL, bool) {
for _, webhook := range config.Current.WebhookURLs {
if webhook.Name == name {
return webhook, true
}
}
return config.WebhookURL{}, false
}
// PostWebhook submits a JSON body to one of the app's configured webhooks.
//
// Returns the bytes of the response body (hopefully, JSON data) and any errors.
func PostWebhook(name string, payload any) ([]byte, error) {
webhook, ok := GetWebhook(name)
if !ok {
return nil, errors.New("PostWebhook(%s): webhook name %s is not configured")
} else if !webhook.Enabled {
return nil, errors.New("PostWebhook(%s): webhook is not enabled")
}
// JSON request body.
jsonStr, err := json.Marshal(payload)
if err != nil {
return nil, err
}
// Make the API request to BareRTC.
var url = webhook.URL
log.Debug("PostWebhook(%s): to %s we send: %s", name, url, jsonStr)
req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonStr))
if err != nil {
return nil, err
}
req.Header.Set("Content-Type", "application/json")
client := &http.Client{
Timeout: 10 * time.Second,
}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
if resp.StatusCode != http.StatusOK {
log.Error("PostWebhook(%s): unexpected response from webhook URL %s (code %d): %s", name, url, resp.StatusCode, body)
return body, errors.New("unexpected error from webhook URL")
}
return body, nil
}
// PostWebhookReport posts a report message via webhook to your website.
func PostWebhookReport(report WebhookRequestReport) error {
_, err := PostWebhook(WebhookReport, WebhookRequest{
Action: WebhookReport,
APIKey: config.Current.AdminAPIKey,
Report: report,
})
return err
}