// Package detector provides music link detection in text. package detector import ( "regexp" "musiclink/internal/services" ) // pattern matches music service URLs. // We use a combined pattern since the idonthavespotify API handles all services. var pattern = regexp.MustCompile( `https?://(?:` + `(?:open\.)?spotify\.com/(?:track|album|artist|playlist)/[a-zA-Z0-9]+|` + `spoti\.fi/[a-zA-Z0-9]+|` + `(?:www\.)?(?:youtube\.com/watch\?v=|youtu\.be/|music\.youtube\.com/watch\?v=)[a-zA-Z0-9_-]{11}|` + `(?:music\.)?apple\.com/[a-z]{2}/(?:album|artist|playlist|song)/[^\s]+|` + `(?:www\.)?deezer\.com/(?:[a-z]{2}/)?(?:track|album|artist|playlist)/\d+|` + `(?:www\.)?soundcloud\.com/[a-zA-Z0-9_-]+/[a-zA-Z0-9_-]+|` + `(?:www\.)?tidal\.com/(?:browse/)?(?:track|album|artist|playlist)/\d+|` + `[a-zA-Z0-9_-]+\.bandcamp\.com/(?:track|album)/[a-zA-Z0-9_-]+` + `)`, ) // Detector finds music links in text. type Detector struct{} // New creates a new Detector. func New() *Detector { return &Detector{} } // Detect finds all music links in the given text. func (d *Detector) Detect(text string) []services.DetectedLink { matches := pattern.FindAllString(text, -1) if len(matches) == 0 { return nil } links := make([]services.DetectedLink, len(matches)) for i, match := range matches { links[i] = services.DetectedLink{ URL: match, RawMatch: match, } } return links }