feat: add discord_embed handler

This commit is contained in:
Bastien Riviere 2023-09-03 16:46:02 +02:00
parent 64e91cb2d4
commit c832ea4645
Signed by: babariviere
GPG key ID: 4E5F0839249F162E
5 changed files with 95 additions and 0 deletions

74
bridge/discord.go Normal file
View file

@ -0,0 +1,74 @@
package bridge
import (
"encoding/json"
"log/slog"
"net/http"
"strings"
)
type DiscordMessage struct {
Content string `json:"content"`
Embeds []struct {
Title string `json:"title"`
Description string `json:"description"`
URL string `json:"url"`
Footer struct {
Text string `json:"text"`
} `json:"footer"`
Author struct {
Name string `json:"name"`
URL string `json:"url"`
} `json:"author"`
} `json:"embeds"`
}
type DiscordEmbedHandler struct{}
func NewDiscordEmbedHandler() DiscordEmbedHandler {
return DiscordEmbedHandler{}
}
func (d DiscordEmbedHandler) ProduceNotifications(r *http.Request) ([]Notification, error) {
l := slog.With(slog.String("handler", "discord_embed"))
dec := json.NewDecoder(r.Body)
defer r.Body.Close()
var not DiscordMessage
if err := dec.Decode(&not); err != nil {
l.Error("invalid message format", "error", err)
return nil, err
}
notifications := make([]Notification, len(not.Embeds))
for i, embed := range not.Embeds {
not := notifications[i]
not.Title = embed.Title
not.IsMarkdown = true
if embed.URL != "" {
not.Actions = []NotificationAction{NewViewAction("Open in Browser", embed.URL)}
}
var body strings.Builder
body.WriteString(embed.Description)
if embed.Author.Name != "" {
body.WriteString("\n\n**Author**\n")
body.WriteString(embed.Author.Name)
if embed.Author.URL != "" {
body.WriteString(" (" + embed.Author.URL + ")")
}
}
if embed.Footer.Text != "" {
body.WriteString("\n\n" + embed.Footer.Text)
}
not.Body = body.String()
notifications[i] = not
}
return notifications, nil
}

View file

@ -23,3 +23,12 @@ handler "/flux" {
# type "alertmanager"
# topic "/infra"
# }
# Handle discord type messages. This is meant for
# webhook that doesn't support generic one's.
# Instead, we convert discord messages to ntfy message.
# See: https://discord.com/developers/docs/resources/channel#message-object
handler "/discord-like" {
type "discord_embed" # handle message with `embeds` content
topic "discord-like"
}

View file

@ -11,12 +11,15 @@ type HandlerType int
const (
HandlerFlux HandlerType = iota + 1
HandlerDiscordEmbed
)
func (h HandlerType) String() string {
switch h {
case HandlerFlux:
return "flux"
case HandlerDiscordEmbed:
return "discord_embed"
}
panic("unreachable")
}
@ -148,6 +151,8 @@ func readHandlerType(d *scfg.Directive) (HandlerType, error) {
switch ty {
case "flux":
return HandlerFlux, nil
case "discord_embed":
return HandlerDiscordEmbed, nil
default:
return 0, fmt.Errorf("invalid handler type %q", ty)
}

View file

@ -17,6 +17,11 @@ data:
type "flux"
topic "flux"
}
handler "/forgejo" {
type "discord_embed"
topic "forgejo"
}
---
apiVersion: apps/v1
kind: Deployment

View file

@ -74,6 +74,8 @@ func main() {
switch handler.Type {
case config.HandlerFlux:
h = bridge.NewFluxHandler()
case config.HandlerDiscordEmbed:
h = bridge.NewDiscordEmbedHandler()
}
slog.Debug("Registering bridge", "route", route, "handler", handler.Type)