(ctx context.Context, in *testWebhookInput)
| 265 | } |
| 266 | |
| 267 | func (s *Server) handleTestWebhook(ctx context.Context, in *testWebhookInput) (*testWebhookOutput, error) { |
| 268 | user, err := s.requireAccountUser(ctx) |
| 269 | if err != nil { |
| 270 | return nil, err |
| 271 | } |
| 272 | if s.deps.TestWebhookInsert == nil { |
| 273 | return nil, NewError(http.StatusNotFound, "not_found", "test endpoint not configured") |
| 274 | } |
| 275 | wh, err := s.deps.GetWebhook(ctx, in.ID, user.ID) |
| 276 | if err != nil || wh == nil { |
| 277 | return nil, NewError(http.StatusNotFound, "not_found", "webhook not found") |
| 278 | } |
| 279 | if !wh.Enabled { |
| 280 | return nil, NewError(http.StatusConflict, "webhook_disabled", "webhook is disabled") |
| 281 | } |
| 282 | event := in.Body.Event |
| 283 | if event == "" { |
| 284 | event = webhookpub.EventEmailReceived |
| 285 | } |
| 286 | if !webhookpub.IsValidEventType(event) { |
| 287 | return nil, NewError(http.StatusBadRequest, "invalid_event_type", fmt.Sprintf("unknown event type %q", event)) |
| 288 | } |
| 289 | data := in.Body.Data |
| 290 | if data == nil { |
| 291 | data = map[string]any{"test": true} |
| 292 | } |
| 293 | envelope, err := json.Marshal(webhookpub.NewEvent(event, user.ID, data).AsEnvelope()) |
| 294 | if err != nil { |
| 295 | return nil, NewError(http.StatusInternalServerError, "internal_error", "failed to marshal test event") |
| 296 | } |
| 297 | deliveryID, err := s.deps.TestWebhookInsert(ctx, wh.ID, event, envelope) |
| 298 | if err != nil { |
| 299 | return nil, NewError(http.StatusInternalServerError, "internal_error", "failed to schedule test delivery") |
| 300 | } |
| 301 | out := &testWebhookOutput{} |
| 302 | out.Body.DeliveryID = deliveryID |
| 303 | return out, nil |
| 304 | } |
| 305 | |
| 306 | // WebhookDeliveryView mirrors the legacy per-delivery wire shape. |
| 307 | type WebhookDeliveryView struct { |
nothing calls this directly
no test coverage detected