package main
import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"fmt"
"io"
"net/http"
"time"
)
const webhookSignatureKey = "YOUR_WEBHOOK_SECRET_FROM_ADMIN_CONSOLE"
// NutritionRecord represents the webhook payload structure
type NutritionRecord struct {
ApplicationID int64 `json:"application_id"`
UID string `json:"uid"`
RecordID string `json:"record_id"`
Status string `json:"status"`
DishName string `json:"dish_name"`
NutriScore string `json:"nutri_score"`
UploadedAt time.Time `json:"uploaded_at"`
ModifiedAt time.Time `json:"modified_at"`
// Add other fields as needed
}
func main() {
http.HandleFunc("/nutrition-webhook", 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 request body
body, err := io.ReadAll(r.Body)
if err != nil {
http.Error(w, "Failed to read body", http.StatusInternalServerError)
return
}
// Calculate and verify HMAC
hm := hmac.New(sha256.New, []byte(webhookSignatureKey))
hm.Write(body)
expectedSignature := hex.EncodeToString(hm.Sum(nil))
if signature != expectedSignature {
http.Error(w, "Invalid signature", http.StatusUnauthorized)
return
}
// Parse nutrition record
var record NutritionRecord
if err := json.Unmarshal(body, &record); err != nil {
http.Error(w, "Invalid JSON", http.StatusBadRequest)
return
}
// Process the nutrition record
fmt.Printf("Received nutrition analysis: %s for user %s\n", record.Status, record.UID)
if record.Status == "completed" {
fmt.Printf("Dish: %s, Nutri-Score: %s\n", record.DishName, record.NutriScore)
// Update your application with the results
} else if record.Status == "failed" {
fmt.Printf("Analysis failed for record %s\n", record.RecordID)
// Handle failure case
}
// Respond with success
w.WriteHeader(http.StatusOK)
w.Write([]byte("OK"))
})
fmt.Println("Starting nutrition webhook server on port 8000")
http.ListenAndServe(":8000", nil)
}