LoginSignup
1
0

More than 3 years have passed since last update.

Go-twitter で GET friendships/lookup

Last updated at Posted at 2020-04-06

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 を呼べないことに注意してください。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0