-
Notifications
You must be signed in to change notification settings - Fork 63
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* added the basic client * added basic unit test * added example * added to the readme * added the comments
- Loading branch information
1 parent
199451c
commit 0dcb24d
Showing
7 changed files
with
310 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
package main | ||
|
||
import ( | ||
"context" | ||
"encoding/json" | ||
"flag" | ||
"fmt" | ||
"log" | ||
"net/http" | ||
|
||
twitter "github.com/g8rswimmer/go-twitter/v2" | ||
) | ||
|
||
type authorize struct { | ||
Token string | ||
} | ||
|
||
func (a authorize) Add(req *http.Request) { | ||
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", a.Token)) | ||
} | ||
|
||
/** | ||
In order to run, the user will need to provide the bearer token and the list of tweet ids. | ||
**/ | ||
func main() { | ||
token := flag.String("token", "", "twitter API token") | ||
id := flag.String("id", "", "twitter id") | ||
flag.Parse() | ||
|
||
client := &twitter.Client{ | ||
Authorizer: authorize{ | ||
Token: *token, | ||
}, | ||
Client: http.DefaultClient, | ||
Host: "https://api.twitter.com", | ||
} | ||
opts := twitter.QuoteTweetsLookupOpts{ | ||
Expansions: []twitter.Expansion{twitter.ExpansionAuthorID}, | ||
TweetFields: []twitter.TweetField{twitter.TweetFieldCreatedAt, twitter.TweetFieldConversationID, twitter.TweetFieldAttachments, twitter.TweetFieldAuthorID, twitter.TweetFieldPublicMetrics}, | ||
UserFields: []twitter.UserField{twitter.UserFieldUserName}, | ||
} | ||
|
||
fmt.Println("Callout to quote tweet lookup callout") | ||
|
||
tweetResponse, err := client.QuoteTweetsLookup(context.Background(), *id, opts) | ||
if err != nil { | ||
log.Panicf("tweet quote lookup error: %v", err) | ||
} | ||
|
||
dictionaries := tweetResponse.Raw.TweetDictionaries() | ||
|
||
enc, err := json.MarshalIndent(dictionaries, "", " ") | ||
if err != nil { | ||
log.Panic(err) | ||
} | ||
fmt.Println(string(enc)) | ||
|
||
enc, err = json.MarshalIndent(tweetResponse.Meta, "", " ") | ||
if err != nil { | ||
log.Panic(err) | ||
} | ||
fmt.Println(string(enc)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
package twitter | ||
|
||
import ( | ||
"context" | ||
"io" | ||
"log" | ||
"net/http" | ||
"reflect" | ||
"strings" | ||
"testing" | ||
) | ||
|
||
func TestClient_QuoteTweetsLookup(t *testing.T) { | ||
type fields struct { | ||
Authorizer Authorizer | ||
Client *http.Client | ||
Host string | ||
} | ||
type args struct { | ||
tweetID string | ||
opts QuoteTweetsLookupOpts | ||
} | ||
tests := []struct { | ||
name string | ||
fields fields | ||
args args | ||
want *QuoteTweetsLookupResponse | ||
wantErr bool | ||
}{ | ||
{ | ||
name: "success", | ||
fields: fields{ | ||
Authorizer: &mockAuth{}, | ||
Host: "https://www.test.com", | ||
Client: mockHTTPClient(func(req *http.Request) *http.Response { | ||
if req.Method != http.MethodGet { | ||
log.Panicf("the method is not correct %s %s", req.Method, http.MethodGet) | ||
} | ||
if strings.Contains(req.URL.String(), quoteTweetLookupEndpoint.urlID("", "tweet-1234")) == false { | ||
log.Panicf("the url is not correct %s %s", req.URL.String(), listLookupEndpoint) | ||
} | ||
body := `{ | ||
"data": [ | ||
{ | ||
"id": "1503982413004914689", | ||
"text": "RT @suhemparack: Super excited to share our course on Getting started with the #TwitterAPI v2 for academic research\n\nIf you know students w…" | ||
} | ||
], | ||
"meta": { | ||
"result_count": 1, | ||
"next_token": "axdnchiqasch" | ||
} | ||
}` | ||
return &http.Response{ | ||
StatusCode: http.StatusOK, | ||
Body: io.NopCloser(strings.NewReader(body)), | ||
Header: func() http.Header { | ||
h := http.Header{} | ||
h.Add(rateLimit, "15") | ||
h.Add(rateRemaining, "12") | ||
h.Add(rateReset, "1644461060") | ||
return h | ||
}(), | ||
} | ||
}), | ||
}, | ||
args: args{ | ||
tweetID: "tweet-1234", | ||
}, | ||
want: &QuoteTweetsLookupResponse{ | ||
Raw: &TweetRaw{ | ||
Tweets: []*TweetObj{ | ||
{ | ||
ID: "1503982413004914689", | ||
Text: "RT @suhemparack: Super excited to share our course on Getting started with the #TwitterAPI v2 for academic research\n\nIf you know students w…", | ||
}, | ||
}, | ||
}, | ||
Meta: &QuoteTweetsLookupMeta{ | ||
ResultCount: 1, | ||
NextToken: "axdnchiqasch", | ||
}, | ||
RateLimit: &RateLimit{ | ||
Limit: 15, | ||
Remaining: 12, | ||
Reset: Epoch(1644461060), | ||
}, | ||
}, | ||
}, | ||
} | ||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
c := &Client{ | ||
Authorizer: tt.fields.Authorizer, | ||
Client: tt.fields.Client, | ||
Host: tt.fields.Host, | ||
} | ||
got, err := c.QuoteTweetsLookup(context.Background(), tt.args.tweetID, tt.args.opts) | ||
if (err != nil) != tt.wantErr { | ||
t.Errorf("Client.QuoteTweetsLookup() error = %v, wantErr %v", err, tt.wantErr) | ||
return | ||
} | ||
if !reflect.DeepEqual(got, tt.want) { | ||
t.Errorf("Client.QuoteTweetsLookup() = %v, want %v", got, tt.want) | ||
} | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
package twitter | ||
|
||
import ( | ||
"net/http" | ||
"strconv" | ||
"strings" | ||
) | ||
|
||
// QuoteTweetsLookupOpts are the options for the quote tweets | ||
type QuoteTweetsLookupOpts struct { | ||
MaxResults int | ||
PaginationToken string | ||
Expansions []Expansion | ||
MediaFields []MediaField | ||
PlaceFields []PlaceField | ||
PollFields []PollField | ||
TweetFields []TweetField | ||
UserFields []UserField | ||
} | ||
|
||
func (qt QuoteTweetsLookupOpts) addQuery(req *http.Request) { | ||
q := req.URL.Query() | ||
if len(qt.Expansions) > 0 { | ||
q.Add("expansions", strings.Join(expansionStringArray(qt.Expansions), ",")) | ||
} | ||
if len(qt.MediaFields) > 0 { | ||
q.Add("media.fields", strings.Join(mediaFieldStringArray(qt.MediaFields), ",")) | ||
} | ||
if len(qt.PlaceFields) > 0 { | ||
q.Add("place.fields", strings.Join(placeFieldStringArray(qt.PlaceFields), ",")) | ||
} | ||
if len(qt.PollFields) > 0 { | ||
q.Add("poll.fields", strings.Join(pollFieldStringArray(qt.PollFields), ",")) | ||
} | ||
if len(qt.TweetFields) > 0 { | ||
q.Add("tweet.fields", strings.Join(tweetFieldStringArray(qt.TweetFields), ",")) | ||
} | ||
if len(qt.UserFields) > 0 { | ||
q.Add("user.fields", strings.Join(userFieldStringArray(qt.UserFields), ",")) | ||
} | ||
if qt.MaxResults > 0 { | ||
q.Add("max_results", strconv.Itoa(qt.MaxResults)) | ||
} | ||
if len(qt.PaginationToken) > 0 { | ||
q.Add("pagination_token", qt.PaginationToken) | ||
} | ||
if len(q) > 0 { | ||
req.URL.RawQuery = q.Encode() | ||
} | ||
} | ||
|
||
// QuoteTweetsLookupResponse is the response from the quote tweet | ||
type QuoteTweetsLookupResponse struct { | ||
Raw *TweetRaw | ||
Meta *QuoteTweetsLookupMeta | ||
RateLimit *RateLimit | ||
} | ||
|
||
// QuoteTweetsLookupMeta is the meta data from the response | ||
type QuoteTweetsLookupMeta struct { | ||
ResultCount int `json:"result_count"` | ||
NextToken string `json:"next_token"` | ||
} |