gitea, notion webhook
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.
 
 
 
 
 

73 lines
2.2 KiB

package server
import (
"encoding/json"
"io"
"log/slog"
"net/http"
"github.com/gin-gonic/gin"
"git/palnet/slack-notifier/internal/gitea"
"git/palnet/slack-notifier/internal/security"
)
func (s *Server) handleGitea(c *gin.Context) {
raw, err := io.ReadAll(c.Request.Body)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "cannot read body"})
return
}
if !security.VerifyHMACSHA256(s.cfg.GiteaWebhookSecret, raw, c.GetHeader("X-Gitea-Signature")) {
slog.Warn("gitea signature verification failed")
c.JSON(http.StatusUnauthorized, gin.H{"error": "invalid signature"})
return
}
event := c.GetHeader("X-Gitea-Event")
notes, err := gitea.BuildNotifications(event, raw)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid payload"})
return
}
sent := s.deliver(c.Request.Context(), notes)
c.JSON(http.StatusOK, gin.H{"event": event, "matched": len(notes), "sent": sent})
}
func (s *Server) handleNotion(c *gin.Context) {
raw, err := io.ReadAll(c.Request.Body)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "cannot read body"})
return
}
// 1) Subscription verification handshake: Notion POSTs a verification_token once.
// Capture it from logs and paste into NOTION_VERIFICATION_TOKEN.
var probe struct {
VerificationToken string `json:"verification_token"`
}
_ = json.Unmarshal(raw, &probe)
if probe.VerificationToken != "" {
slog.Warn("notion verification_token received — set this in NOTION_VERIFICATION_TOKEN", "verification_token", probe.VerificationToken)
c.JSON(http.StatusOK, gin.H{"verification_token": probe.VerificationToken})
return
}
// 2) Normal events: verify signature against the verification token.
if !security.VerifyHMACSHA256(s.cfg.NotionVerificationToken, raw, c.GetHeader("X-Notion-Signature")) {
slog.Warn("notion signature verification failed")
c.JSON(http.StatusUnauthorized, gin.H{"error": "invalid signature"})
return
}
notes, err := s.notion.BuildNotifications(c.Request.Context(), raw)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid payload"})
return
}
sent := s.deliver(c.Request.Context(), notes)
c.JSON(http.StatusOK, gin.H{"matched": len(notes), "sent": sent})
}