package embed import ( "context" "database/sql" "fmt" "io" "net/http" "regexp" "strings" "time" ) var urlRegex = regexp.MustCompile(`https?://[^\s<>"{}|\^\[\]]+`) // Embed represents a stored link preview. type Embed struct { ID string `json:"id"` MessageID string `json:"message_id"` URL string `json:"url"` Title string `json:"title"` Description string `json:"description"` ImageURL string `json:"image_url"` SiteName string `json:"site_name"` } // ExtractURLs returns all HTTP/HTTPS URLs found in text. func ExtractURLs(text string) []string { matches := urlRegex.FindAllString(text, -1) seen := make(map[string]struct{}) var out []string for _, u := range matches { if _, ok := seen[u]; ok { continue } seen[u] = struct{}{} out = append(out, u) } if len(out) > 5 { out = out[:5] } return out } // FetchEmbed retrieves OpenGraph meta tags for a URL. func FetchEmbed(url string) *Embed { client := &http.Client{Timeout: 2 * time.Second} req, err := http.NewRequest("GET", url, nil) if err != nil { return nil } req.Header.Set("User-Agent", "Mozilla/5.0 (compatible; DumpsterBot/1.0)") resp, err := client.Do(req) if err != nil { return nil } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { return nil } body, err := io.ReadAll(io.LimitReader(resp.Body, 256*1024)) if err != nil { return nil } html := string(body) return &Embed{ URL: url, Title: ogTag(html, "og:title"), Description: ogTag(html, "og:description"), ImageURL: ogTag(html, "og:image"), SiteName: ogTag(html, "og:site_name"), } } func ogTag(html, property string) string { // Try property re := regexp.MustCompile(`]+property=["']` + regexp.QuoteMeta(property) + `["'][^>]+content=["']([^"']*)["']`) m := re.FindStringSubmatch(html) if len(m) > 1 && m[1] != "" { return strings.TrimSpace(m[1]) } // Try name re = regexp.MustCompile(`]+name=["']` + regexp.QuoteMeta(property) + `["'][^>]+content=["']([^"']*)["']`) m = re.FindStringSubmatch(html) if len(m) > 1 && m[1] != "" { return strings.TrimSpace(m[1]) } // Fallback for title if property == "og:title" { re = regexp.MustCompile(`