From 0be63a404c71b457523cf079a57ddbe922b45ad3 Mon Sep 17 00:00:00 2001 From: Casey Primozic Date: Tue, 22 Oct 2019 12:42:11 -0700 Subject: [PATCH] Implement Twitter API fetching for twitterstats * Create Oauth2 client configured for Twitter and create a HTTP client out of that * Fetch user stats for each of the users, parse out of JSON, and return stats as stats structs --- modules/twitterstats/client.go | 80 ++++++++++++++++++++++++++-------- modules/twitterstats/widget.go | 7 ++- 2 files changed, 66 insertions(+), 21 deletions(-) diff --git a/modules/twitterstats/client.go b/modules/twitterstats/client.go index 353d3e54..247017ac 100644 --- a/modules/twitterstats/client.go +++ b/modules/twitterstats/client.go @@ -1,18 +1,31 @@ package twitterstats import ( + "encoding/json" + "fmt" + "io/ioutil" "log" + "net/http" + + "golang.org/x/oauth2" + "golang.org/x/oauth2/clientcredentials" ) type Client struct { - apiBase string - consumerKey string - consumerSecret string - accessToken string - accessTokenSecret string - screenNames []string + apiBase string + httpClient *http.Client + screenNames []string } +type TwitterStats struct { + followerCount int64 + tweetCount int64 +} + +const ( + userTimelineUrl = "https://api.twitter.com/1.1/users/show.json" +) + func NewClient(settings *Settings) *Client { usernames := make([]string, len(settings.screenNames)) for i, username := range settings.screenNames { @@ -27,22 +40,55 @@ func NewClient(settings *Settings) *Client { } + conf := &clientcredentials.Config{ + ClientID: settings.consumerKey, + ClientSecret: settings.consumerSecret, + TokenURL: "https://api.twitter.com/oauth2/token", + } + + // token, err := conf.Token(oauth2.NoContext) + httpClient := conf.Client(oauth2.NoContext) + client := Client{ - apiBase: "https://api.twitter.com/1.1/", - consumerKey: settings.consumerKey, - consumerSecret: settings.consumerSecret, - accessToken: settings.accessToken, - accessTokenSecret: settings.accessTokenSecret, - screenNames: usernames, + apiBase: "https://api.twitter.com/1.1/", + httpClient: httpClient, + screenNames: usernames, } return &client } -func (client *Client) GetFollowerCounts() []int64 { - return []int64{0, 0, 0, 0, 0} // TODO -} +func (client *Client) GetStats() []TwitterStats { + stats := make([]TwitterStats, len(client.screenNames)) -func (client *Client) GetTweetCounts() []int64 { - return []int64{0, 0, 0, 0, 0} // TODO + for i, username := range client.screenNames { + stats[i] = TwitterStats{ + followerCount: 0, + tweetCount: 0, + } + + res, err := client.httpClient.Get(fmt.Sprintf("%s?screen_name=%s", userTimelineUrl, username)) + if err != nil { + continue + } + defer res.Body.Close() + + body, err := ioutil.ReadAll(res.Body) + if err != nil { + continue + } + + var parsed map[string]interface{} + err = json.Unmarshal(body, &parsed) + if err != nil { + continue + } + + stats[i] = TwitterStats{ + followerCount: int64(parsed["followers_count"].(float64)), + tweetCount: int64(parsed["statuses_count"].(float64)), + } + } + + return stats } diff --git a/modules/twitterstats/widget.go b/modules/twitterstats/widget.go index eb12f87b..26f65a7f 100644 --- a/modules/twitterstats/widget.go +++ b/modules/twitterstats/widget.go @@ -40,16 +40,15 @@ func (widget *Widget) Refresh() { func (widget *Widget) content() (string, string, bool) { usernames := widget.client.screenNames - followerCounts := widget.client.GetFollowerCounts() - tweetCounts := widget.client.GetTweetCounts() + stats := widget.client.GetStats() // Add header row str := fmt.Sprintf("%-16s %-8s %-8s\n", "Username", "Followers", "# Tweets") // Add rows for each of the followed usernames for i, username := range usernames { - followerCount := followerCounts[i] - tweetCount := tweetCounts[i] + followerCount := stats[i].followerCount + tweetCount := stats[i].tweetCount str += fmt.Sprintf("%-16s %8d %8d\n", username, followerCount, tweetCount) }