package services import ( "bytes" "encoding/json" "io" "net/http" "os" ) // The structs to map OpenRouter's response type OpenRouterResponse struct { Choices []struct { Message struct { Content string `json:"content"` } `json:"message"` } `json:"choices"` } func GetAIResponse(input string) (string, error) { apiKey := os.Getenv("OPENROUTER_API_KEY") payload := map[string]interface{}{ "model": "google/gemini-2.0-flash-001", "messages": []map[string]string{ {"role": "system", "content": "You are a Chilean business assistant. Be brief."}, {"role": "user", "content": input}, }, "tools": []map[string]interface{}{ { "type": "function", "function": map[string]interface{}{ "name": "create_appointment", "description": "Schedules a new appointment in the database", "parameters": map[string]interface{}{ "type": "object", "properties": map[string]interface{}{ "customer_phone": map[string]string{"type": "string"}, "date": map[string]string{"type": "string", "description": "ISO format date and time"}, }, "required": []string{"customer_phone", "date"}, }, }, }, }, } data, _ := json.Marshal(payload) req, _ := http.NewRequest("POST", "https://openrouter.ai/api/v1/chat/completions", bytes.NewBuffer(data)) req.Header.Set("Authorization", "Bearer "+apiKey) req.Header.Set("Content-Type", "application/json") resp, err := http.DefaultClient.Do(req) if err != nil { return "", err } defer resp.Body.Close() bodyBytes, _ := io.ReadAll(resp.Body) // If it's not a 200, return the error body so you can see why it failed if resp.StatusCode != http.StatusOK { return "API Error: " + string(bodyBytes), nil } var result OpenRouterResponse if err := json.Unmarshal(bodyBytes, &result); err != nil { return "", err } if len(result.Choices) > 0 { return result.Choices[0].Message.Content, nil } return "No response from AI.", nil }