package discord import ( "errors" "fmt" "net/http" "net/url" "time" "github.com/goccy/go-json" ) const DiscordBaseUrl = "https://discord.com/api/v10" var ( ErrUnauthorized = errors.New("discord: got a 401 from discord") ) type IDiscordClient interface { Do(req *http.Request) (*http.Response, error) BotAuth(req *http.Request) ClientAuth(req *http.Request, accessToken string) GetClientID() string } type DiscordClient struct { Client *http.Client BotToken string ClientID string ClientSecret string } func NewDiscordClient(clientID, clientSecret, botToken string) *DiscordClient { return &DiscordClient{ ClientID: clientID, ClientSecret: clientSecret, BotToken: botToken, Client: &http.Client{ Timeout: time.Second * 10, }, } } func (d *DiscordClient) Do(req *http.Request) (*http.Response, error) { return d.Client.Do(req) } func (d *DiscordClient) BotAuth(req *http.Request) { req.Header.Set("Authorization", fmt.Sprintf("Bot %s", d.BotToken)) } func (d *DiscordClient) ClientAuth(req *http.Request, accessToken string) { req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", d.BotToken)) } func NewRequest(method string, path string) *http.Request { url, err := url.Parse(fmt.Sprintf("%s%s", DiscordBaseUrl, path)) if err != nil { panic("discord/api: wtf couldnt join a string??") } req := &http.Request{ Method: method, URL: url, Header: http.Header{}, } req.Header.Set("User-Agent", "Roleypoly (https://roleypoly.com, v4)") return req } func OutputResponse(resp *http.Response, dst any) error { if resp.StatusCode == 401 { return ErrUnauthorized } // TODO: more checks? return json.NewDecoder(resp.Body).Decode(dst) } func (d *DiscordClient) GetClientID() string { return d.ClientID }