package main
import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"fmt"
"io"
"net/http"
"time"
)
// PushEvent represents a webhook event from the health data provider
const hmacKey = "HMAC_KEY_FROM_ADMIN_CONSOLE"
type PushEvent struct {
ApplicationUserID string `json:"application_user_id"` // ID of the application user
Timestamp time.Time `json:"timestamp"` // Event timestamp
EventType string `json:"event_type"` // Type of event
Metrics []string `json:"metrics"` // List of metrics
ActivityTypes []string `json:"activity_types"` // List of activity types
ProviderSlug string `json:"provider_slug"` // Provider identifier
EarliestRecordStartAt time.Time `json:"earliest_record_start_at"` // Start of data range
LatestRecordEndAt time.Time `json:"latest_record_end_at"` // End of data range
}
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
// Verify HMAC signature
signature := r.Header.Get("X-Body-Signature")
if signature == "" {
http.Error(w, "Missing signature", http.StatusBadRequest)
return
}
// Read and verify the request body
body, err := io.ReadAll(r.Body)
if err != nil {
http.Error(w, "Failed to read body", http.StatusInternalServerError)
return
}
// Calculate HMAC
hm := hmac.New(sha256.New, []byte(hmacKey))
hm.Write(body)
if signature != hex.EncodeToString(hm.Sum(nil)) {
http.Error(w, "Invalid signature", http.StatusUnauthorized)
return
}
// Parse events
var events []PushEvent
if err := json.Unmarshal(body, &events); err != nil {
http.Error(w, "Invalid JSON", http.StatusBadRequest)
return
}
// Process events
for _, event := range events {
fmt.Printf("Received event: %+v\n", event)
}
w.WriteHeader(http.StatusOK)
w.Write([]byte("OK"))
})
fmt.Println("Starting server on port 8000")
http.ListenAndServe(":8000", nil)
}