From 51ad0afadbb339e777f90f2cbb85a62f8ab5f2ce Mon Sep 17 00:00:00 2001 From: andefined Date: Mon, 28 Nov 2022 19:49:09 +0200 Subject: [PATCH] fix: various fields --- .gitignore | 3 ++- examples/followers/main.go | 10 +++---- tweets.go | 6 ++--- twitter.go | 54 ++++++++++++++++++++++++++++++++++++++ twitter_test.go | 26 +++++++++++++----- users.go | 4 +-- 6 files changed, 83 insertions(+), 20 deletions(-) diff --git a/.gitignore b/.gitignore index 737ff07..b73c672 100644 --- a/.gitignore +++ b/.gitignore @@ -44,4 +44,5 @@ targets/ bot.yaml *.jsondist/ .env -examples/the-follower \ No newline at end of file +examples/the-follower +examples/mediawatch \ No newline at end of file diff --git a/examples/followers/main.go b/examples/followers/main.go index ec52051..fe402ed 100644 --- a/examples/followers/main.go +++ b/examples/followers/main.go @@ -4,6 +4,7 @@ import ( "encoding/json" "flag" "fmt" + "log" "net/url" "strconv" "time" @@ -19,8 +20,6 @@ func main() { flag.Parse() - start := time.Now() - api, err := twitter.NewTwitter(*consumerKey, *consumerSecret) if err != nil { panic(err) @@ -30,7 +29,7 @@ func main() { v := url.Values{} // set size of response ids to 1000 - v.Add("max_results", "250") + v.Add("max_results", "1000") // set user fields to return v.Add("user.fields", "created_at,description,id,location,name,pinned_tweet_id,profile_image_url,protected,public_metrics,url,username,verified") // set tweet fields to return @@ -69,9 +68,6 @@ func main() { ) } - fmt.Printf("Result Count: %d Next Token: %s\n", r.Meta.ResultCount, r.Meta.NextToken) + log.Printf("Result Count: %d Next Token: %s\n", r.Meta.ResultCount, r.Meta.NextToken) } - - end := time.Now() - fmt.Printf("Done in %s", end.Sub(start)) } diff --git a/tweets.go b/tweets.go index 3358b1a..6c29ba9 100644 --- a/tweets.go +++ b/tweets.go @@ -49,7 +49,7 @@ func (api *Twitter) GetUserMentions(id string, v url.Values, options ...QueueOpt } // if there is a next page, transform the original request object // by setting the `pagination_token` parameter to get the next page - if res.Results.Meta.NextToken != "" && q.auto { + if res.Results.Meta != nil && res.Results.Meta.NextToken != "" && q.auto { // create new url values and add the pagination token nv := url.Values{} nv.Add("pagination_token", res.Results.Meta.NextToken) @@ -117,7 +117,7 @@ func (api *Twitter) GetUserTweets(id string, v url.Values, options ...QueueOptio } // if there is a next page, transform the original request object // by setting the `pagination_token` parameter to get the next page - if res.Results.Meta.NextToken != "" && q.auto { + if res.Results.Meta != nil && res.Results.Meta.NextToken != "" && q.auto { // create new url values and add the pagination token nv := url.Values{} nv.Add("pagination_token", res.Results.Meta.NextToken) @@ -185,7 +185,7 @@ func (api *Twitter) GetTweets(v url.Values, options ...QueueOption) (chan *Data, } // if there is a next page, transform the original request object // by setting the `pagination_token` parameter to get the next page - if res.Results.Meta.NextToken != "" && q.auto { + if res.Results.Meta != nil && res.Results.Meta.NextToken != "" && q.auto { // create new url values and add the pagination token nv := url.Values{} nv.Add("pagination_token", res.Results.Meta.NextToken) diff --git a/twitter.go b/twitter.go index f85123e..41bcf65 100644 --- a/twitter.go +++ b/twitter.go @@ -59,6 +59,60 @@ func NewTwitter(consumerKey, consumerSecret string) (*Twitter, error) { return api, nil } +// NewTwitter returns a new Twitter API v2 Client using OAuth 2.0 based authentication. +// This method is usufull when you only need to make Application-Only requests. +// Official Documentation: https://developer.twitter.com/en/docs/authentication/oauth-2-0 +// Scopes: https://developer.twitter.com/en/docs/authentication/oauth-2-0/authorization-code +// func NewTwitterWithPKCE(consumerKey, consumerSecret, accessToken, accessTokenSecret string) (*Twitter, error) { +// // create new context +// ctx := context.Background() + +// // init new Twitter client +// api := &Twitter{ +// baseURL: BaseURL, +// } + +// // oauth2 configures a client that uses app credentials to keep a fresh token +// config := &oauth2.Config{ +// ClientID: consumerKey, +// ClientSecret: consumerSecret, +// Scopes: []string{ +// "tweet.read", +// "users.read", +// "offline.access", +// }, +// Endpoint: oauth2.Endpoint{ +// AuthURL: AuthorizeTokenURL, +// TokenURL: TokenURL, +// }, +// } + +// // Redirect user to consent page to ask for permission +// // for the scopes specified above. +// url := config.AuthCodeURL("state", oauth2.AccessTypeOffline, +// oauth2.SetAuthURLParam("code_challenge", "challenge"), +// oauth2.SetAuthURLParam("code_challenge_method", "plain"), +// oauth2.SetAuthURLParam("response_type", "code"), +// ) +// fmt.Printf("Visit the URL for the auth dialog: %v", url) + +// // Use the authorization code that is pushed to the redirect +// // URL. Exchange will do the handshake to retrieve the +// // initial access token. The HTTP Client returned by +// // conf.Client will refresh the token as necessary. +// var code string +// if _, err := fmt.Scan(&code); err != nil { +// return nil, err +// } +// tok, err := config.Exchange(ctx, code) +// if err != nil { +// return nil, err +// } + +// api.client = config.Client(ctx, tok) +// return api, nil +// } + // NewTwitterWithContext returns a new Twitter API v2 Client using OAuth 1.0 based authentication. // This method is useful when you need to make API requests, on behalf of a Twitter account. // Official Documentation: https://developer.twitter.com/en/docs/authentication/oauth-1-0a diff --git a/twitter_test.go b/twitter_test.go index 4cb20fe..6adbf18 100644 --- a/twitter_test.go +++ b/twitter_test.go @@ -18,6 +18,17 @@ var ( accessTokenSecret = os.Getenv("TEST_TWITTER_ACCESS_TOKEN_SECRET") ) +// Test_API_NewAPI_Client Test New Twitter API Client +// func Test_NewTwitter_PKCE(t *testing.T) { +// api, err := twitter.NewTwitterWithPKCE(consumerKey, consumerSecret, accessToken, accessTokenSecret) +// if err != nil { +// t.Fatalf("Couldn't create Twitter API HTTP Client") +// } +// if api.GetClient() == nil { +// t.Fatalf("Twitter API HTTP Client returned nil") +// } +// } + // Test_API_NewAPI_Client Test New Twitter API Client func Test_NewTwitter_Client(t *testing.T) { api, err := twitter.NewTwitter(consumerKey, consumerSecret) @@ -531,16 +542,17 @@ func Test_GetFilterStream(t *testing.T) { var f twitter.StreamData s, serr := api.GetFilterStream(v) if serr != nil { - t.Fatalf("Twitter API GetSampleStream Error: %s", serr.Error()) + t.Fatalf("Twitter API GetFilterStream Error: %s", serr.Error()) } - for t := range s.C { - f, _ = t.(twitter.StreamData) + for x := range s.C { + f, _ = x.(twitter.StreamData) + t.Log(f) break } s.Stop() - if f.Tweet.ID == "" { - t.Fatalf("Twitter API GetSampleStream Error. Should have return a valid tweet struct, got %v", f.Tweet) + if f.Data.ID == "" { + t.Fatalf("Twitter API GetFilterStream Error. Should have return a valid tweet struct, got %v", f.Data) } } @@ -566,8 +578,8 @@ func Test_GetSampleStream(t *testing.T) { } s.Stop() - if f.Tweet.ID == "" { - t.Fatalf("Twitter API GetSampleStream Error. Should have return a valid tweet struct, got %v", f.Tweet) + if f.Data.ID == "" { + t.Fatalf("Twitter API GetSampleStream Error. Should have return a valid tweet struct, got %v", f.Data) } } diff --git a/users.go b/users.go index fa91a52..766437c 100644 --- a/users.go +++ b/users.go @@ -50,7 +50,7 @@ func (api *Twitter) GetUserFollowers(id string, v url.Values, options ...QueueOp // if there is a next page, transform the original request object // by setting the `pagination_token` parameter to get the next page - if res.Results.Meta.NextToken != "" && q.auto { + if res.Results.Meta != nil && res.Results.Meta.NextToken != "" && q.auto { // create new url values and add the pagination token nv := url.Values{} nv.Add("pagination_token", res.Results.Meta.NextToken) @@ -119,7 +119,7 @@ func (api *Twitter) GetUserFollowing(id string, v url.Values, options ...QueueOp // if there is a next page, transform the original request object // by setting the `pagination_token` parameter to get the next page - if res.Results.Meta.NextToken != "" && q.auto { + if res.Results.Meta != nil && res.Results.Meta.NextToken != "" && q.auto { // create new url values and add the pagination token nv := url.Values{} nv.Add("pagination_token", res.Results.Meta.NextToken)