Files
tell-me/tools/search.go
Pavel Pivovarov 50a439a499 Initial commit
2025-12-12 11:15:02 +11:00

82 lines
2.0 KiB
Go

package tools
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"strings"
)
// SearchResult represents a single search result
type SearchResult struct {
Title string `json:"title"`
URL string `json:"url"`
Content string `json:"content"`
}
// SearchResponse represents the SearXNG API response
type SearchResponse struct {
Results []SearchResult `json:"results"`
}
// WebSearch performs a web search using SearXNG
func WebSearch(searxngURL, query string) (string, error) {
// Build the search URL
searchURL := fmt.Sprintf("%s/search", strings.TrimSuffix(searxngURL, "/"))
// Create URL with query parameters
params := url.Values{}
params.Add("q", query)
params.Add("format", "json")
params.Add("language", "en")
fullURL := fmt.Sprintf("%s?%s", searchURL, params.Encode())
// Make the request
resp, err := http.Get(fullURL)
if err != nil {
return "", fmt.Errorf("failed to perform search: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
body, _ := io.ReadAll(resp.Body)
return "", fmt.Errorf("search request failed with status %d: %s", resp.StatusCode, string(body))
}
// Parse the response
body, err := io.ReadAll(resp.Body)
if err != nil {
return "", fmt.Errorf("failed to read response: %w", err)
}
var searchResp SearchResponse
if err := json.Unmarshal(body, &searchResp); err != nil {
return "", fmt.Errorf("failed to parse search results: %w", err)
}
// Format results as text
if len(searchResp.Results) == 0 {
return "No results found.", nil
}
var results strings.Builder
results.WriteString(fmt.Sprintf("Found %d results:\n\n", len(searchResp.Results)))
for i, result := range searchResp.Results {
if i >= 10 { // Limit to top 10 results
break
}
results.WriteString(fmt.Sprintf("%d. %s\n", i+1, result.Title))
results.WriteString(fmt.Sprintf(" URL: %s\n", result.URL))
if result.Content != "" {
results.WriteString(fmt.Sprintf(" %s\n", result.Content))
}
results.WriteString("\n")
}
return results.String(), nil
}