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"
|
2020-01-15 18:32:54 +00:00
|
|
|
"github.com/diamondburned/arikawa/internal/httputil"
|
2020-01-02 05:39:52 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
BaseEndpoint = "https://discordapp.com/api"
|
|
|
|
APIVersion = "6"
|
|
|
|
|
|
|
|
Endpoint = BaseEndpoint + "/v" + APIVersion + "/"
|
|
|
|
EndpointGateway = Endpoint + "gateway"
|
|
|
|
EndpointGatewayBot = EndpointGateway + "/bot"
|
|
|
|
EndpointWebhooks = Endpoint + "webhooks/"
|
|
|
|
)
|
|
|
|
|
|
|
|
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,
|
2020-01-08 18:43:15 +00:00
|
|
|
Limiter: rate.NewLimiter(),
|
|
|
|
Token: token,
|
2020-01-02 05:39:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
tw := httputil.NewTransportWrapper()
|
|
|
|
tw.Pre = func(r *http.Request) error {
|
2020-01-15 04:43:34 +00:00
|
|
|
r.Header.Set("Authorization", cli.Token)
|
|
|
|
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.Response) error {
|
|
|
|
return cli.Limiter.Release(r.Request.URL.Path, r.Header)
|
2020-01-02 05:39:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
cli.Client.Transport = tw
|
|
|
|
|
|
|
|
return cli
|
|
|
|
}
|