package websearch import ( "context" "fmt" "net/http" "net/url" "strings" ) func (c *Client) searchCustom(ctx context.Context, provider Provider, query string, count int) ([]Result, error) { endpoint := strings.TrimSpace(provider.BaseURL) if endpoint == "" { return nil, fmt.Errorf("custom search base url is required") } endpoint = strings.NewReplacer( "{query}", url.QueryEscape(query), "{count}", fmt.Sprintf("%d", count), ).Replace(endpoint) reqURL, err := url.Parse(endpoint) if err != nil { return nil, err } if !strings.Contains(provider.BaseURL, "{query}") { q := reqURL.Query() q.Set(queryParamName(provider), query) if !strings.Contains(provider.BaseURL, "{count}") { q.Set("count", fmt.Sprintf("%d", count)) } reqURL.RawQuery = q.Encode() } req, err := http.NewRequestWithContext(ctx, http.MethodGet, reqURL.String(), nil) if err != nil { return nil, err } req.Header.Set("Accept", "application/json") if apiKey := strings.TrimSpace(provider.APIKey); apiKey != "" { header := strings.TrimSpace(provider.AuthHeader) switch { case header != "": if strings.EqualFold(header, "Authorization") { req.Header.Set(header, "Bearer "+apiKey) } else { req.Header.Set(header, apiKey) } case strings.Contains(reqURL.RawQuery, "api_key="): // key already in URL default: q := reqURL.Query() q.Set("api_key", apiKey) reqURL.RawQuery = q.Encode() req.URL = reqURL } } body, status, err := c.doRequest(req) if err != nil { return nil, err } if status >= 400 { return nil, fmt.Errorf("custom search failed (%d): %s", status, string(body)) } root, err := decodeJSONBody(body) if err != nil { return nil, err } items, ok := resultsArray(root, provider.ResultsPath) if !ok { return []Result{}, nil } descField := strings.TrimSpace(provider.DescField) if descField == "" { descField = "description" } limit := count if len(items) < limit { limit = len(items) } results := make([]Result, 0, limit) for _, item := range items[:limit] { title := jsonFieldString(item, provider.TitleField) link := jsonFieldString(item, provider.URLField) desc := jsonFieldString(item, descField) if title == "" && link == "" { continue } results = append(results, Result{ Title: title, URL: link, Description: desc, }) } return results, nil }