go-twitter で GET friendships/lookup.json を呼び出す際のサンプルです。
go-twitter は現在 GET friendships/show をサポートしていますが GET friendships/lookup はサポートされていないようです。
show だと
Requests / 15-min window (user auth) 180
Requests / 15-min window (app auth) 15
つまり最大 180 ユーザ
lookup だと
Requests / 15-min window (user auth) 15
up to 100 are allowed in a single request.
つまり最大 15*100=1500 ユーザ
と一回の API コールで取得できるユーザ数が全然違うため、なるべくなら lookup を使いたいため頑張って実装してみました。
twitterut.go
package twitterut
import (
"bytes"
"context"
"fmt"
"net/http"
"strings"
"github.com/dghubble/go-twitter/twitter"
"github.com/dghubble/oauth1"
"github.com/dghubble/sling"
)
type Client struct {
HTTPClient *http.Client
*twitter.Client
}
func NewClient() *Client {
config := oauth1.NewConfig("FIXME", "FIXME")
token := oauth1.NewToken("FIXME", "FIXME")
httpClient := config.Client(oauth1.NoContext, token)
client := twitter.NewClient(httpClient)
return &Client{
httpClient,
client,
}
}
type FriendshipLookupStatus struct {
Name string `json:"name"`
ScreenName string `json:"screen_name"`
ID int64 `json:"id"`
IDStr string `json:"id_str"`
Connections []string `json:"connections"`
}
type FriendshipLookupParams struct {
UserID string `url:"user_id,omitempty"`
ScreenName string `url:"screen_name,omitempty"`
}
func relevantError(httpError error, apiError twitter.APIError) error {
if httpError != nil {
return httpError
}
if apiError.Empty() {
return nil
}
return apiError
}
func Lookup(ctx context.Context, client *Client, params *FriendshipLookupParams) ([]FriendshipLookupStatus, *http.Response, error) {
s := sling.New().Client(client.HTTPClient).Base("https://api.twitter.com/1.1/").Path("friendships/")
friendships := new([]FriendshipLookupStatus)
apiError := new(twitter.APIError)
resp, err := s.New().Get("lookup.json").QueryStruct(params).Receive(friendships, apiError)
return *friendships, resp, relevantError(err, *apiError)
}
func Friendships(ctx context.Context, client *Client, users []twitter.User) ([]FriendshipLookupStatus, error) {
result := make([]FriendshipLookupStatus, 0, len(users))
for i := 0; i < len(users); i += 100 { // GET friendships/lookup は一度のリクエストで 100 ユーザまで
var buf bytes.Buffer
unit := users[i:mathut.MinInt(i+100, len(users))]
for _, user := range unit {
stringut.AppendSplit(&buf, user.IDStr, ",")
}
friendships, _, err := Lookup(ctx, client, &FriendshipLookupParams{
UserID: buf.String(),
})
if err != nil {
return nil, err
}
result = append(result, friendships...)
}
return result, nil
}
自分が試してたところ、このように twitter.NewClient する際の httpClient を取っておくことで、特にカスタマイズしなくとも lookup を呼び出せることを確認しました。
一回で 100 ユーザまで取れますが 15 分で 15 回までしか API を呼べないことに注意してください。