package main import ( "context" "encoding/json" "fmt" "net/http" "time" ) type gtsClient struct { authentication Authentication httpClient http.Client userAgent string timeout time.Duration } func newGtsClient(authentication Authentication) *gtsClient { httpClient := http.Client{} client := gtsClient{ authentication: authentication, httpClient: httpClient, userAgent: userAgent, timeout: 5 * time.Second, } return &client } func (g *gtsClient) verifyCredentials() (Account, error) { path := "/api/v1/accounts/verify_credentials" url := g.authentication.Instance + path ctx, cancel := context.WithTimeout(context.Background(), g.timeout) defer cancel() request, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) if err != nil { return Account{}, fmt.Errorf("unable to create the HTTP request; %w", err) } var account Account if err := g.sendRequest(request, &account); err != nil { return Account{}, fmt.Errorf("received an error after sending the request to verify the credentials; %w", err) } return account, nil } func (g *gtsClient) sendRequest(request *http.Request, object any) error { request.Header.Set("Content-Type", "application/json; charset=utf-8") request.Header.Set("Accept", "application/json; charset=utf-8") request.Header.Set("User-Agent", g.userAgent) if len(g.authentication.AccessToken) > 0 { request.Header.Set("Authorization", fmt.Sprintf("Bearer %s", g.authentication.AccessToken)) } response, err := g.httpClient.Do(request) if err != nil { return fmt.Errorf("received an error after sending the request; %w", err) } defer response.Body.Close() if response.StatusCode < http.StatusOK || response.StatusCode >= http.StatusBadRequest { return fmt.Errorf( "did not receive an OK response from the GoToSocial server; got %d", response.StatusCode, ) } if err := json.NewDecoder(response.Body).Decode(object); err != nil { return fmt.Errorf( "unable to decode the response from the GoToSocial server; %w", err, ) } return nil }