Skip to content
This repository was archived by the owner on Nov 7, 2022. It is now read-only.

Commit bd5f167

Browse files
committed
Add support for rate_limit_status endpoint
1 parent 2277311 commit bd5f167

3 files changed

Lines changed: 111 additions & 0 deletions

File tree

twitter/rate_limits.go

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package twitter
2+
3+
import (
4+
"net/http"
5+
6+
"github.com/dghubble/sling"
7+
)
8+
9+
// RateLimitService provides methods for accessing Twitter rate limits
10+
// API endpoints.
11+
type RateLimitService struct {
12+
sling *sling.Sling
13+
}
14+
15+
// newRateLimitService returns a new RateLimitService.
16+
func newRateLimitService(sling *sling.Sling) *RateLimitService {
17+
return &RateLimitService{
18+
sling: sling.Path("application/"),
19+
}
20+
}
21+
22+
// RateLimitStatusResponse response of rate limit status
23+
type RateLimitStatusResponse struct {
24+
RateLimitContext *RateLimitContext `json:"rate_limit_context,omitempty"`
25+
Resources *RateLimitResources `json:"resources,omitempty"`
26+
}
27+
28+
// RateLimitContext contains auth context
29+
type RateLimitContext struct {
30+
AccessToken string `json:"access_token,omitempty"`
31+
}
32+
33+
// RateLimitResources contains all limit status data for endpoints group by resources
34+
type RateLimitResources struct {
35+
Users map[string]*RateLimitResource `json:"users,omitempty"`
36+
Statuses map[string]*RateLimitResource `json:"statuses,omitempty"`
37+
Help map[string]*RateLimitResource `json:"help,omitempty"`
38+
Search map[string]*RateLimitResource `json:"search,omitempty"`
39+
}
40+
41+
// RateLimitResource contains limit status data for a single endpoint
42+
type RateLimitResource struct {
43+
Limit int `json:"limit,omitempty"`
44+
Remaining int `json:"remaining,omitempty"`
45+
Reset int `json:"reset,omitempty"`
46+
}
47+
48+
// RateLimitStatusParams are the parameters for RateLimitService.Status.
49+
type RateLimitStatusParams struct {
50+
Resources string `url:"resources,omitempty"`
51+
}
52+
53+
// Status returns rate limits.
54+
// https://developer.twitter.com/en/docs/developer-utilities/rate-limit-status/api-reference/get-application-rate_limit_status
55+
func (s *RateLimitService) Status(params *RateLimitStatusParams) (RateLimitStatusResponse, *http.Response, error) {
56+
rateLimitStatusResponse := new(RateLimitStatusResponse)
57+
apiError := new(APIError)
58+
resp, err := s.sling.New().Get("rate_limit_status.json").QueryStruct(params).Receive(rateLimitStatusResponse, apiError)
59+
return *rateLimitStatusResponse, resp, relevantError(err, *apiError)
60+
}

twitter/rate_limits_test.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package twitter
2+
3+
import (
4+
"fmt"
5+
"net/http"
6+
"testing"
7+
8+
"github.com/stretchr/testify/assert"
9+
)
10+
11+
func TestRateLimitService_Status(t *testing.T) {
12+
httpClient, mux, server := testServer()
13+
defer server.Close()
14+
15+
mux.HandleFunc("/1.1/application/rate_limit_status.json", func(w http.ResponseWriter, r *http.Request) {
16+
assertMethod(t, "GET", r)
17+
assertQuery(t, map[string]string{"resources": "statuses,users,help"}, r)
18+
w.Header().Set("Content-Type", "application/json")
19+
fmt.Fprintf(w, `{"rate_limit_context":{"access_token":"786491-24zE39NUezJ8UTmOGOtLhgyLgCkPyY4dAcx6NA6sDKw"},"resources":{"users":{"/users/profile_banner":{"limit":180,"remaining":180,"reset":1403602426}},"statuses":{"/statuses/mentions_timeline":{"limit":75,"remaining":75,"reset":1403602426},"/statuses/lookup":{"limit":900,"remaining":900,"reset":1403602426}},"help":{"/help/privacy":{"limit":15,"remaining":15,"reset":1403602426}}}}`)
20+
})
21+
22+
client := NewClient(httpClient)
23+
tweets, _, err := client.RateLimits.Status(&RateLimitStatusParams{Resources: "statuses,users,help"})
24+
expected := RateLimitStatusResponse{
25+
RateLimitContext: &RateLimitContext{AccessToken: "786491-24zE39NUezJ8UTmOGOtLhgyLgCkPyY4dAcx6NA6sDKw"},
26+
Resources: &RateLimitResources{
27+
Users: map[string]*RateLimitResource{
28+
"/users/profile_banner": &RateLimitResource{
29+
Limit: 180,
30+
Remaining: 180,
31+
Reset: 1403602426}},
32+
Statuses: map[string]*RateLimitResource{
33+
"/statuses/mentions_timeline": &RateLimitResource{
34+
Limit: 75,
35+
Remaining: 75,
36+
Reset: 1403602426},
37+
"/statuses/lookup": &RateLimitResource{
38+
Limit: 900,
39+
Remaining: 900,
40+
Reset: 1403602426}},
41+
Help: map[string]*RateLimitResource{
42+
"/help/privacy": &RateLimitResource{
43+
Limit: 15,
44+
Remaining: 15,
45+
Reset: 1403602426}}}}
46+
47+
assert.Nil(t, err)
48+
assert.Equal(t, expected, tweets)
49+
}

twitter/twitter.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ type Client struct {
1818
Followers *FollowerService
1919
Friends *FriendService
2020
Friendships *FriendshipService
21+
RateLimits *RateLimitService
2122
Search *SearchService
2223
Statuses *StatusService
2324
Streams *StreamService
@@ -37,6 +38,7 @@ func NewClient(httpClient *http.Client) *Client {
3738
Followers: newFollowerService(base.New()),
3839
Friends: newFriendService(base.New()),
3940
Friendships: newFriendshipService(base.New()),
41+
RateLimits: newRateLimitService(base.New()),
4042
Search: newSearchService(base.New()),
4143
Statuses: newStatusService(base.New()),
4244
Streams: newStreamService(httpClient, base.New()),

0 commit comments

Comments
 (0)