package waapi import ( "fmt" "strings" "sync" "github.com/Neur0toxine/wa-profile-api/internal/dto" "github.com/Neur0toxine/wa-profile-api/internal/log" "github.com/Neur0toxine/wa-profile-api/internal/proxy" "github.com/gocolly/colly" ) const ( ClientKey = "waapi_client" nilImage = "https://static.whatsapp.net/rsrc.php/v3/yR/r/y8-PTBaP90a.png" ) type Client struct { proxy proxy.Provider pool sync.Pool } func NewClient(proxy proxy.Provider) *Client { return &Client{ proxy: proxy, pool: sync.Pool{ New: newColly, }, } } func (c *Client) ProfileByPhone(phone string) (profile dto.WAProfile, err error) { cl := c.colly() RetryProfileByPhone: proxyAddr := c.proxy.Provide() if proxyAddr != "" { _ = cl.SetProxy(proxyAddr) } cl.OnHTML(`meta[property="og:title"]`, func(el *colly.HTMLElement) { profile.Name = el.Attr("content") }) cl.OnHTML(`meta[property="og:image"]`, func(el *colly.HTMLElement) { profile.Avatar = el.Attr("content") if profile.Avatar == nilImage { profile.Name = "" profile.Avatar = "" } }) cl.OnError(func(r *colly.Response, crawlErr error) { err = crawlErr }) cl.Visit(fmt.Sprintf("https://api.whatsapp.com/send/?phone=%s&text&type=phone_number&app_absent=0", phone)) if err != nil { if proxyAddr != "" && (strings.Contains(err.Error(), "connection reset") || strings.Contains(err.Error(), "unexpected EOF") || strings.Contains(err.Error(), "Client.Timeout") || strings.Contains(err.Error(), "Bad Request") || strings.Contains(err.Error(), "Permanent Redirect")) { c.proxy.Bad(proxyAddr) goto RetryProfileByPhone } } c.pool.Put(cl) return } func (c *Client) colly() *colly.Collector { return c.pool.Get().(*colly.Collector) } func newColly() any { c := colly.NewCollector(colly.AllowURLRevisit()) c.OnRequest(func(r *colly.Request) { r.Headers.Set("User-Agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36") log.Debug("crawler: visiting", r.URL) }) if log.IsDebug { c.OnResponse(func(r *colly.Response) { log.Debug("crawler: got a response", string(r.Body)) }) } return c }