package main import ( "errors" "fmt" "github.com/PuerkitoBio/goquery" "log" "net/http" "net/http/cookiejar" "net/url" "strings" ) const BASE_URL = "https://vivaplus.tv/" const SIGN_IN_URL = BASE_URL + "supporters/sign_in" type WebClient struct { csrfToken string cookies *cookiejar.Jar } func NewWebClient() *WebClient { jar, err := cookiejar.New(nil) if err != nil { log.Fatalf("error creating cookiejar: %w", err) } return &WebClient{ cookies: jar, } } func (w *WebClient) RegisterCookies(rawUrl string, resp *http.Response) { u, err := url.Parse(rawUrl) if err != nil { log.Fatalf("error parsing url: %v", err) } w.cookies.SetCookies(u, resp.Cookies()) } func (w *WebClient) UseCookies(rawUrl string, req *http.Request) { u, err := url.Parse(rawUrl) if err != nil { log.Fatalf("error parsing url: %v", err) } for _, c := range w.cookies.Cookies(u) { req.AddCookie(c) } } func (w *WebClient) FetchCsrfToken() error { resp, err := http.Get(SIGN_IN_URL) if err != nil { return fmt.Errorf("error getting sign in page: %w", err) } defer resp.Body.Close() doc, err := goquery.NewDocumentFromReader(resp.Body) if err != nil { return fmt.Errorf("error parsing sign in page: %w", err) } w.RegisterCookies(SIGN_IN_URL, resp) csrfTokenElement := doc.Find("meta[name='csrf-token']").First() if csrfTokenElement == nil { return errors.New("error getting csrf token element") } var exists bool w.csrfToken, exists = csrfTokenElement.Attr("content") if !exists { return errors.New("error content attribute does not exist") } return nil } func (w *WebClient) VivaLogin(username, password string) error { err := w.FetchCsrfToken() if err != nil { return err } form := url.Values{} form.Set("email", username) form.Set("password", password) println("Encoded form:", form.Encode()) println("CSRF token:", w.csrfToken) req, err := http.NewRequest("POST", SIGN_IN_URL, strings.NewReader(form.Encode())) w.UseCookies(SIGN_IN_URL, req) for _, c := range req.Cookies() { println("Cookie:", c.Name, "=", c.Value) } if err != nil { return fmt.Errorf("error creating login request: %w", err) } req.Header.Add("x-csrf-token", w.csrfToken) req.Header.Add("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8") resp, err := http.DefaultClient.Do(req) if err != nil { return fmt.Errorf("error logging in: %w", err) } log.Printf("Status code: %d", resp.StatusCode) return nil }