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
This commit is contained in:
73
internal/service/task_webhook.go
Normal file
73
internal/service/task_webhook.go
Normal file
@@ -0,0 +1,73 @@
|
||||
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)
|
||||
}
|
||||
Reference in New Issue
Block a user