Skip to content

Commit 259650c

Browse files
cornyshoce
andcommitted
Add x-goog-visitor-id (#360)
Co-authored-by: shoce <yogze@icloud.com>
1 parent 4a6e6c2 commit 259650c

File tree

1 file changed

+58
-0
lines changed

1 file changed

+58
-0
lines changed

client.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -605,6 +605,12 @@ func (c *Client) httpPost(ctx context.Context, url string, body interface{}) (*h
605605
req.Header.Set("Content-Type", "application/json")
606606
req.Header.Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8")
607607

608+
if xgoogvisitorid, err := getVisitorId(); err != nil {
609+
return nil, err
610+
} else {
611+
req.Header.Set("x-goog-visitor-id", xgoogvisitorid)
612+
}
613+
608614
resp, err := c.httpDo(req)
609615
if err != nil {
610616
return nil, err
@@ -618,6 +624,58 @@ func (c *Client) httpPost(ctx context.Context, url string, body interface{}) (*h
618624
return resp, nil
619625
}
620626

627+
var VisitorIdMaxAge = 10 * time.Hour
628+
var VisitorId struct {
629+
Id string
630+
Ctime time.Time
631+
}
632+
633+
func getVisitorId() (string, error) {
634+
if VisitorId.Id != "" && time.Since(VisitorId.Ctime) < VisitorIdMaxAge {
635+
return VisitorId.Id, nil
636+
}
637+
638+
const sep = "\nytcfg.set("
639+
640+
var req http.Request
641+
req.Header = http.Header{}
642+
req.Header.Set("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.4 Safari/605.1.15")
643+
req.URL = &url.URL{}
644+
req.URL.Host = "www.youtube.com"
645+
req.URL.Scheme = "https"
646+
resp, err := http.DefaultClient.Do(&req)
647+
if err != nil {
648+
return "", err
649+
}
650+
defer resp.Body.Close()
651+
data, err := io.ReadAll(resp.Body)
652+
if err != nil {
653+
return "", err
654+
}
655+
_, data1, found := strings.Cut(string(data), sep)
656+
if !found {
657+
return "", err
658+
}
659+
var value struct {
660+
InnertubeContext struct {
661+
Client struct {
662+
VisitorData string
663+
}
664+
} `json:"INNERTUBE_CONTEXT"`
665+
}
666+
if err := json.NewDecoder(strings.NewReader(data1)).Decode(&value); err != nil {
667+
return "", err
668+
}
669+
670+
if VisitorId.Id, err = url.PathUnescape(value.InnertubeContext.Client.VisitorData); err != nil {
671+
return "", err
672+
}
673+
674+
VisitorId.Ctime = time.Now()
675+
676+
return VisitorId.Id, nil
677+
}
678+
621679
// httpPostBodyBytes reads the whole HTTP body and returns it
622680
func (c *Client) httpPostBodyBytes(ctx context.Context, url string, body interface{}) ([]byte, error) {
623681
resp, err := c.httpPost(ctx, url, body)

0 commit comments

Comments
 (0)