arikawa/api/api.go

61 lines
1.4 KiB
Go
Raw Normal View History

2020-01-15 04:56:50 +00:00
// Package api provides an interface to interact with the Discord REST API. It
// handles rate limiting, as well as authorizing and more.
2020-01-02 05:39:52 +00:00
package api
import (
"net/http"
2020-01-08 18:43:15 +00:00
"github.com/diamondburned/arikawa/api/rate"
"github.com/diamondburned/arikawa/utils/httputil"
2020-01-02 05:39:52 +00:00
)
var (
BaseEndpoint = "https://discordapp.com"
2020-01-02 05:39:52 +00:00
APIVersion = "6"
APIPath = "/api/v" + APIVersion
2020-01-02 05:39:52 +00:00
Endpoint = BaseEndpoint + APIPath + "/"
2020-01-02 05:39:52 +00:00
EndpointGateway = Endpoint + "gateway"
EndpointGatewayBot = EndpointGateway + "/bot"
)
var UserAgent = "DiscordBot (https://github.com/diamondburned/arikawa, v0.0.1)"
type Client struct {
httputil.Client
2020-01-08 18:43:15 +00:00
Limiter *rate.Limiter
2020-01-02 05:39:52 +00:00
Token string
}
func NewClient(token string) *Client {
cli := &Client{
2020-01-15 04:43:34 +00:00
Client: httputil.DefaultClient,
Limiter: rate.NewLimiter(APIPath),
2020-01-08 18:43:15 +00:00
Token: token,
2020-01-02 05:39:52 +00:00
}
tw := httputil.NewTransportWrapper()
tw.Pre = func(r *http.Request) error {
if cli.Token != "" {
r.Header.Set("Authorization", cli.Token)
}
2020-01-15 04:43:34 +00:00
r.Header.Set("User-Agent", UserAgent)
2020-01-08 07:10:37 +00:00
r.Header.Set("X-RateLimit-Precision", "millisecond")
2020-01-08 18:43:15 +00:00
// Rate limit stuff
return cli.Limiter.Acquire(r.Context(), r.URL.Path)
}
tw.Post = func(r *http.Request, resp *http.Response) error {
if resp == nil {
return cli.Limiter.Release(r.URL.Path, nil)
}
return cli.Limiter.Release(r.URL.Path, resp.Header)
2020-01-02 05:39:52 +00:00
}
cli.Client.Transport = tw
return cli
}