Files
CalendarApi/internal/service/task_webhook.go
Michilis bd24545b7b Fix BASE_URL config loading, add tasks/projects; robust .env path resolution
- Config: try ENV_FILE, .env, ../.env for loading; trim trailing slash from BaseURL
- Log BASE_URL at server startup for verification
- .env.example: document BASE_URL
- Tasks, projects, tags, migrations and related API/handlers

Made-with: Cursor
2026-03-09 18:57:51 +00:00

74 lines
1.7 KiB
Go

package service
import (
"bytes"
"context"
"encoding/json"
"net/http"
"time"
"github.com/calendarapi/internal/models"
"github.com/calendarapi/internal/repository"
"github.com/calendarapi/internal/utils"
"github.com/google/uuid"
)
type TaskWebhookService struct {
queries *repository.Queries
}
func NewTaskWebhookService(queries *repository.Queries) *TaskWebhookService {
return &TaskWebhookService{queries: queries}
}
func (s *TaskWebhookService) Deliver(ctx context.Context, ownerID uuid.UUID, event string, task *models.Task) {
webhooks, err := s.queries.ListTaskWebhooksByOwner(ctx, utils.ToPgUUID(ownerID))
if err != nil {
return
}
payload := map[string]interface{}{
"event": event,
"task": task,
"timestamp": time.Now().UTC().Format(time.RFC3339),
}
body, _ := json.Marshal(payload)
for _, wh := range webhooks {
if !s.webhookSubscribedTo(wh.Events, event) {
continue
}
secret := ""
if wh.Secret.Valid {
secret = wh.Secret.String
}
go s.postWebhook(wh.Url, body, []byte(secret))
}
}
func (s *TaskWebhookService) webhookSubscribedTo(eventsJSON []byte, event string) bool {
var events []string
if err := json.Unmarshal(eventsJSON, &events); err != nil {
return false
}
for _, e := range events {
if e == event {
return true
}
}
return false
}
func (s *TaskWebhookService) postWebhook(url string, body []byte, secret []byte) {
req, err := http.NewRequest("POST", url, bytes.NewReader(body))
if err != nil {
return
}
req.Header.Set("Content-Type", "application/json")
if len(secret) > 0 {
req.Header.Set("X-Webhook-Signature", string(secret))
}
client := &http.Client{Timeout: 10 * time.Second}
_, _ = client.Do(req)
}