diff --git a/README b/README index d1e365d..2cc31a5 100644 --- a/README +++ b/README @@ -17,9 +17,7 @@ Examples If you already have the access token (and secret) for your user (Twitter provides this for your own account on the developer portal), creating the client is simple: ````go -anaconda.SetConsumerKey("your-consumer-key") -anaconda.SetConsumerSecret("your-consumer-secret") -api := anaconda.NewTwitterApi("your-access-token", "your-access-token-secret") +api := anaconda.NewTwitterApi("your-access-token", "your-access-token-secret", "your-consumer-key", "your-consumer-secret") ```` ### Queries diff --git a/example_test.go b/example_test.go index 89476b7..8de4ed4 100644 --- a/example_test.go +++ b/example_test.go @@ -10,17 +10,12 @@ import ( // Initialize an client library for a given user. // This only needs to be done *once* per user func ExampleTwitterApi_InitializeClient() { - anaconda.SetConsumerKey("your-consumer-key") - anaconda.SetConsumerSecret("your-consumer-secret") - api := anaconda.NewTwitterApi(ACCESS_TOKEN, ACCESS_TOKEN_SECRET) + api := anaconda.NewTwitterApi(ACCESS_TOKEN, ACCESS_TOKEN_SECRET, "your-consumer-key", "your-consumer-secret") fmt.Println(*api.Credentials) } func ExampleTwitterApi_GetSearch() { - - anaconda.SetConsumerKey("your-consumer-key") - anaconda.SetConsumerSecret("your-consumer-secret") - api := anaconda.NewTwitterApi("your-access-token", "your-access-token-secret") + api := anaconda.NewTwitterApi("your-access-token", "your-access-token-secret", "your-consumer-key", "your-consumer-secret") search_result, err := api.GetSearch("golang", nil) if err != nil { panic(err) @@ -32,7 +27,7 @@ func ExampleTwitterApi_GetSearch() { // Throttling queries can easily be handled in the background, automatically func ExampleTwitterApi_Throttling() { - api := anaconda.NewTwitterApi("your-access-token", "your-access-token-secret") + api := anaconda.NewTwitterApi("your-access-token", "your-access-token-secret", "your-consumer-key", "your-consumer-secret") api.EnableThrottling(10*time.Second, 5) // These queries will execute in order diff --git a/oembed_test.go b/oembed_test.go index c426a81..b24b55e 100644 --- a/oembed_test.go +++ b/oembed_test.go @@ -11,7 +11,7 @@ import ( func TestOEmbed(t *testing.T) { // It is the only one that can be tested without auth // However, it is still rate-limited - api := anaconda.NewTwitterApi("", "") + api := anaconda.NewTwitterApi("", "", "", "") api.SetBaseUrl(testBase) o, err := api.GetOEmbed(url.Values{"id": []string{"99530515043983360"}}) if err != nil { diff --git a/streaming.go b/streaming.go index ae62649..c4cf6c8 100644 --- a/streaming.go +++ b/streaming.go @@ -203,9 +203,9 @@ func jsonToKnownType(j []byte) interface{} { func (s *Stream) requestStream(urlStr string, v url.Values, method int) (resp *http.Response, err error) { switch method { case _GET: - return oauthClient.Get(s.api.HttpClient, s.api.Credentials, urlStr, v) + return s.api.oauthClient.Get(s.api.HttpClient, s.api.Credentials, urlStr, v) case _POST: - return oauthClient.Post(s.api.HttpClient, s.api.Credentials, urlStr, v) + return s.api.oauthClient.Post(s.api.HttpClient, s.api.Credentials, urlStr, v) default: } return nil, fmt.Errorf("HTTP method not yet supported") diff --git a/twitter.go b/twitter.go index 0cd72ea..c22976b 100644 --- a/twitter.go +++ b/twitter.go @@ -8,10 +8,7 @@ // //If you already have the access token (and secret) for your user (Twitter provides this for your own account on the developer portal), creating the client is simple: // -// anaconda.SetConsumerKey("your-consumer-key") -// anaconda.SetConsumerSecret("your-consumer-secret") -// api := anaconda.NewTwitterApi("your-access-token", "your-access-token-secret") -// +// api := anaconda.NewTwitterApi("your-access-token", "your-access-token-secret", "your-consumer-key", "your-consumer-secret") // //Queries // @@ -60,13 +57,8 @@ const ( UploadBaseUrl = "https://upload.twitter.com/1.1" ) -var oauthClient = oauth.Client{ - TemporaryCredentialRequestURI: "https://api.twitter.com/oauth/request_token", - ResourceOwnerAuthorizationURI: "https://api.twitter.com/oauth/authenticate", - TokenRequestURI: "https://api.twitter.com/oauth/access_token", -} - type TwitterApi struct { + oauthClient oauth.Client Credentials *oauth.Credentials queryQueue chan query bucket *tokenbucket.Bucket @@ -101,11 +93,20 @@ const DEFAULT_CAPACITY = 5 //NewTwitterApi takes an user-specific access token and secret and returns a TwitterApi struct for that user. //The TwitterApi struct can be used for accessing any of the endpoints available. -func NewTwitterApi(access_token string, access_token_secret string) *TwitterApi { +func NewTwitterApi(access_token, access_token_secret, consumer_key, consumer_secret string) *TwitterApi { //TODO figure out how much to buffer this channel //A non-buffered channel will cause blocking when multiple queries are made at the same time queue := make(chan query) c := &TwitterApi{ + oauthClient: oauth.Client{ + TemporaryCredentialRequestURI: "https://api.twitter.com/oauth/request_token", + ResourceOwnerAuthorizationURI: "https://api.twitter.com/oauth/authenticate", + TokenRequestURI: "https://api.twitter.com/oauth/access_token", + Credentials: oauth.Credentials{ + Token: consumer_key, + Secret: consumer_secret, + }, + }, Credentials: &oauth.Credentials{ Token: access_token, Secret: access_token_secret, @@ -121,18 +122,6 @@ func NewTwitterApi(access_token string, access_token_secret string) *TwitterApi return c } -//SetConsumerKey will set the application-specific consumer_key used in the initial OAuth process -//This key is listed on https://dev.twitter.com/apps/YOUR_APP_ID/show -func SetConsumerKey(consumer_key string) { - oauthClient.Credentials.Token = consumer_key -} - -//SetConsumerSecret will set the application-specific secret used in the initial OAuth process -//This secret is listed on https://dev.twitter.com/apps/YOUR_APP_ID/show -func SetConsumerSecret(consumer_secret string) { - oauthClient.Credentials.Secret = consumer_secret -} - // ReturnRateLimitError specifies behavior when the Twitter API returns a rate-limit error. // If set to true, the query will fail and return the error instead of automatically queuing and // retrying the query when the rate limit expires @@ -167,17 +156,16 @@ func (c *TwitterApi) SetBaseUrl(baseUrl string) { //AuthorizationURL generates the authorization URL for the first part of the OAuth handshake. //Redirect the user to this URL. -//This assumes that the consumer key has already been set (using SetConsumerKey). -func AuthorizationURL(callback string) (string, *oauth.Credentials, error) { - tempCred, err := oauthClient.RequestTemporaryCredentials(http.DefaultClient, callback, nil) +func (c *TwitterApi) AuthorizationURL(callback string) (string, *oauth.Credentials, error) { + tempCred, err := c.oauthClient.RequestTemporaryCredentials(http.DefaultClient, callback, nil) if err != nil { return "", nil, err } - return oauthClient.AuthorizationURL(tempCred, nil), tempCred, nil + return c.oauthClient.AuthorizationURL(tempCred, nil), tempCred, nil } -func GetCredentials(tempCred *oauth.Credentials, verifier string) (*oauth.Credentials, url.Values, error) { - return oauthClient.RequestToken(http.DefaultClient, tempCred, verifier) +func (c *TwitterApi) GetCredentials(tempCred *oauth.Credentials, verifier string) (*oauth.Credentials, url.Values, error) { + return c.oauthClient.RequestToken(http.DefaultClient, tempCred, verifier) } func cleanValues(v url.Values) url.Values { @@ -189,7 +177,7 @@ func cleanValues(v url.Values) url.Values { // apiGet issues a GET request to the Twitter API and decodes the response JSON to data. func (c TwitterApi) apiGet(urlStr string, form url.Values, data interface{}) error { - resp, err := oauthClient.Get(c.HttpClient, c.Credentials, urlStr, form) + resp, err := c.oauthClient.Get(c.HttpClient, c.Credentials, urlStr, form) if err != nil { return err } @@ -199,7 +187,7 @@ func (c TwitterApi) apiGet(urlStr string, form url.Values, data interface{}) err // apiPost issues a POST request to the Twitter API and decodes the response JSON to data. func (c TwitterApi) apiPost(urlStr string, form url.Values, data interface{}) error { - resp, err := oauthClient.Post(c.HttpClient, c.Credentials, urlStr, form) + resp, err := c.oauthClient.Post(c.HttpClient, c.Credentials, urlStr, form) if err != nil { return err } diff --git a/twitter_test.go b/twitter_test.go index a9422db..0737ad9 100644 --- a/twitter_test.go +++ b/twitter_test.go @@ -30,9 +30,7 @@ var testBase string func init() { // Initialize api so it can be used even when invidual tests are run in isolation - anaconda.SetConsumerKey(CONSUMER_KEY) - anaconda.SetConsumerSecret(CONSUMER_SECRET) - api = anaconda.NewTwitterApi(ACCESS_TOKEN, ACCESS_TOKEN_SECRET) + api = anaconda.NewTwitterApi(ACCESS_TOKEN, ACCESS_TOKEN_SECRET, CONSUMER_KEY, CONSUMER_SECRET) if CONSUMER_KEY != "" && CONSUMER_SECRET != "" && ACCESS_TOKEN != "" && ACCESS_TOKEN_SECRET != "" { return @@ -115,9 +113,7 @@ func Test_TwitterCredentials(t *testing.T) { // Test that creating a TwitterApi client creates a client with non-empty OAuth credentials func Test_TwitterApi_NewTwitterApi(t *testing.T) { - anaconda.SetConsumerKey(CONSUMER_KEY) - anaconda.SetConsumerSecret(CONSUMER_SECRET) - apiLocal := anaconda.NewTwitterApi(ACCESS_TOKEN, ACCESS_TOKEN_SECRET) + apiLocal := anaconda.NewTwitterApi(ACCESS_TOKEN, ACCESS_TOKEN_SECRET, CONSUMER_KEY, CONSUMER_SECRET) if apiLocal.Credentials == nil { t.Fatalf("Twitter Api client has empty (nil) credentials")