MCPcopy Create free account
hub / github.com/devaccuracy/ledgerforge / executeHook

Method executeHook

internal/hooks/client.go:52–211  ·  view source on GitHub ↗

executeHook performs the actual HTTP request for the webhook. It handles marshalling the payload, creating the request, and processing the response. Retries are handled by the queue system, so this function only performs a single attempt.

(ctx context.Context, hook *Hook, payload HookPayload)

Source from the content-addressed store, hash-verified

50// It handles marshalling the payload, creating the request, and processing the response.
51// Retries are handled by the queue system, so this function only performs a single attempt.
52func (m *redisHookManager) executeHook(ctx context.Context, hook *Hook, payload HookPayload) error {
53 // Create HTTP client with timeout
54 client := &http.Client{
55 Timeout: time.Duration(hook.Timeout) * time.Second,
56 }
57
58 // Marshal payload with explicit handling
59 payloadBytes, err := json.Marshal(payload)
60 if err != nil {
61 return fmt.Errorf("failed to marshal payload: %w", err)
62 }
63
64 // Validate JSON before sending
65 if !json.Valid(payloadBytes) {
66 return fmt.Errorf("invalid JSON payload generated")
67 }
68
69 logrus.WithFields(logrus.Fields{
70 "hook_id": hook.ID,
71 "hook_name": hook.Name,
72 "hook_url": hook.URL,
73 "hook_type": hook.Type,
74 }).Info("Executing webhook")
75
76 timestamp := strconv.FormatInt(time.Now().Unix(), 10)
77
78 if m.config == nil {
79 return fmt.Errorf("config is not initialized")
80 }
81 secret := m.config.Server.SecretKey
82 // Create signature: HMAC-SHA256(timestamp + "." + payload)
83 signatureData := timestamp + "." + string(payloadBytes)
84 mac := hmac.New(sha256.New, []byte(secret))
85 mac.Write([]byte(signatureData))
86 signature := hex.EncodeToString(mac.Sum(nil))
87
88 req, err := http.NewRequestWithContext(ctx, "POST", hook.URL, bytes.NewBuffer(payloadBytes))
89 if err != nil {
90 return fmt.Errorf("failed to create request: %w", err)
91 }
92
93 req.Header.Set("Content-Type", "application/json")
94 req.Header.Set("X-LedgerForge-Signature", signature)
95 req.Header.Set("X-LedgerForge-Timestamp", timestamp)
96 req.Header.Set("X-Hook-ID", hook.ID)
97 req.Header.Set("X-Hook-Type", string(hook.Type))
98
99 resp, err := client.Do(req)
100 if err != nil {
101 // Update hook execution status on failure
102 _ = m.updateHookStatus(ctx, hook, false)
103 if ctx.Err() != nil {
104 logrus.WithFields(logrus.Fields{
105 "hook_id": hook.ID,
106 "hook_type": hook.Type,
107 "error": err,
108 }).Error("Hook execution cancelled due to context timeout")
109 return ctx.Err()

Callers 2

ProcessHookTaskMethod · 0.95
ExecuteHookMethod · 0.95

Calls 7

updateHookStatusMethod · 0.95
SetMethod · 0.65
InfoMethod · 0.45
ErrorMethod · 0.45
CloseMethod · 0.45
DebugMethod · 0.45
WarnMethod · 0.45

Tested by

no test coverage detected