You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
75 lines
1.9 KiB
75 lines
1.9 KiB
package server |
|
|
|
import ( |
|
"context" |
|
"embed" |
|
"html/template" |
|
"net/http" |
|
|
|
"github.com/gin-gonic/gin" |
|
|
|
"git/palnet/slack-notifier/internal/config" |
|
"git/palnet/slack-notifier/internal/logging" |
|
"git/palnet/slack-notifier/internal/mapping" |
|
"git/palnet/slack-notifier/internal/notify" |
|
"git/palnet/slack-notifier/internal/notion" |
|
"git/palnet/slack-notifier/internal/slack" |
|
) |
|
|
|
//go:embed templates/*.html |
|
var templatesFS embed.FS |
|
|
|
// Server wires together config, the Slack client, the mapping store and Notion client. |
|
type Server struct { |
|
cfg config.Config |
|
slack *slack.Client |
|
mappings *mapping.Store |
|
notion *notion.Client |
|
} |
|
|
|
func New(cfg config.Config, sl *slack.Client, m *mapping.Store, nt *notion.Client) *Server { |
|
return &Server{cfg: cfg, slack: sl, mappings: m, notion: nt} |
|
} |
|
|
|
// Router builds the Gin engine with all routes registered. |
|
func (s *Server) Router() *gin.Engine { |
|
if s.cfg.IsProduction() { |
|
gin.SetMode(gin.ReleaseMode) |
|
} |
|
|
|
r := gin.New() |
|
r.Use(logging.GinMiddleware(), gin.Recovery()) |
|
_ = r.SetTrustedProxies(nil) // we don't sit behind a trusted proxy by default |
|
|
|
tmpl := template.Must(template.ParseFS(templatesFS, "templates/*.html")) |
|
r.SetHTMLTemplate(tmpl) |
|
|
|
r.GET("/health", func(c *gin.Context) { |
|
c.JSON(http.StatusOK, gin.H{"status": "ok"}) |
|
}) |
|
|
|
r.POST("/webhooks/gitea", s.handleGitea) |
|
r.POST("/webhooks/notion", s.handleNotion) |
|
|
|
admin := r.Group("/admin") |
|
{ |
|
admin.GET("/mappings", s.adminMappings) |
|
admin.POST("/mappings", s.adminAddMapping) |
|
admin.DELETE("/mappings/:source", s.adminDeleteMapping) |
|
} |
|
|
|
return r |
|
} |
|
|
|
// deliver resolves each notification's recipient via the mapping store and DMs them. |
|
// Returns how many were sent successfully. |
|
func (s *Server) deliver(ctx context.Context, notes []notify.Notification) int { |
|
sent := 0 |
|
for _, n := range notes { |
|
email := s.mappings.Resolve(n.Email, n.Login) |
|
if s.slack.SendDM(ctx, email, n.Text, n.Blocks) { |
|
sent++ |
|
} |
|
} |
|
return sent |
|
}
|
|
|