2023-10-13 14:37:41 +03:00

90 lines
2.1 KiB
Go

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
}