A Go client library for the Twitter 1.1 API

Anaconda

Build Status Build Status GoDoc

Anaconda is a simple, transparent Go package for accessing version 1.1 of the Twitter API.

Successful API queries return native Go structs that can be used immediately, with no need for type assertions.

Examples

Authentication

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:

api := anaconda.NewTwitterApiWithCredentials("your-access-token", "your-access-token-secret", "your-consumer-key", "your-consumer-secret")

Queries

Queries are conducted using a pointer to an authenticated TwitterApi struct. In v1.1 of Twitter's API, all requests should be authenticated.

searchResult, _ := api.GetSearch("golang", nil)
for _ , tweet := range searchResult.Statuses {
    fmt.Println(tweet.Text)
}

Certain endpoints allow separate optional parameter; if desired, these can be passed as the final parameter.

//Perhaps we want 30 values instead of the default 15
v := url.Values{}
v.Set("count", "30")
result, err := api.GetSearch("golang", v)

(Remember that url.Values is equivalent to a map[string][]string, if you find that more convenient notation when specifying values). Otherwise, nil suffices.

Streaming

Anaconda supports the Streaming APIs. You can use PublicStream* or UserStream API methods. A go loop is started an gives you an stream that sends interface{} objects through it's chan C Objects which you can cast into a tweet, event and more.

v := url.Values{}
s := api.UserStream(v)

for t := range s.C {
  switch v := t.(type) {
  case anaconda.Tweet:
    fmt.Printf("%-15s: %s\n", v.User.ScreenName, v.Text)
  case anaconda.EventTweet:
    switch v.Event.Event {
    case "favorite":
      sn := v.Source.ScreenName
      tw := v.TargetObject.Text
      fmt.Printf("Favorited by %-15s: %s\n", sn, tw)
    case "unfavorite":
      sn := v.Source.ScreenName
      tw := v.TargetObject.Text
      fmt.Printf("UnFavorited by %-15s: %s\n", sn, tw)
    }
  }
}

Endpoints

Anaconda implements most of the endpoints defined in the Twitter API documentation. For clarity, in most cases, the function name is simply the name of the HTTP method and the endpoint (e.g., the endpoint GET /friendships/incoming is provided by the function GetFriendshipsIncoming).

In a few cases, a shortened form has been chosen to make life easier (for example, retweeting is simply the function Retweet)

Error Handling, Rate Limiting, and Throttling

Error Handling

Twitter errors are returned as an ApiError, which satisfies the error interface and can be treated as a vanilla error. However, it also contains the additional information returned by the Twitter API that may be useful in deciding how to proceed after encountering an error.

If you make queries too quickly, you may bump against Twitter's rate limits. If this happens, anaconda automatically retries the query when the rate limit resets, using the X-Rate-Limit-Reset header that Twitter provides to determine how long to wait.

In other words, users of the anaconda library should not need to handle rate limiting errors themselves; this is handled seamlessly behind-the-scenes. If an error is returned by a function, another form of error must have occurred (which can be checked by using the fields provided by the ApiError struct).

(If desired, this feature can be turned off by calling ReturnRateLimitError(true).)

Throttling

Anaconda now supports automatic client-side throttling of queries to avoid hitting the Twitter rate-limit.

This is currently off by default; however, it may be turned on by default in future versions of the library, as the implementation is improved.

To set a delay between queries, use the SetDelay method:

api.SetDelay(10 * time.Second)

Delays are set specific to each TwitterApi struct, so queries that use different users' access credentials are completely independent.

To turn off automatic throttling, set the delay to 0:

api.SetDelay(0 * time.Second)

Query Queue Persistence

If your code creates a NewTwitterApi in a regularly called function, you'll need to call .Close() on the API struct to clear the queryQueue and allow the goroutine to exit. Otherwise you could see goroutine and therefor heap memory leaks in long-running applications.

Google App Engine

Since Google App Engine doesn't make the standard http.Transport available, it's necessary to tell Anaconda to use a different client context.

api = anaconda.NewTwitterApi("", "")
c := appengine.NewContext(r)
api.HttpClient.Transport = &urlfetch.Transport{Context: c}

License

Anaconda is free software licensed under the MIT/X11 license. Details provided in the LICENSE file.

Comments
  • [streaming] don't fail on EOF errors, use stream as pointer

    [streaming] don't fail on EOF errors, use stream as pointer

    Hi, tldr, what this pr does ?

    • Using *Stream instead of Stream for a stream has a state ! ( runing, it's actually a bool right now)
      • this simplifies greatly the termination of a streaming by just calling stream.Stop()
    • fix when stream socket get's closed, reopen it instead of failing.
    • fix some failing tests ( had to change import path for this ).
    • added twitter timed backoffs
      • twitter defines every backoff scenario and how we should play with them, I made handlers that return them.
      • I applied the too many requests backoff to the stream section
    • add automatic testing using a travis.yml file
      • For it to work on this repo you will need to click a + button on travis' website and set your twitter acces tokens (don't forget to hide them), then it will test all your prs for you ! :D.
      • it's all green : https://travis-ci.org/azr/anaconda

    Thanks :)

  • `GetUserTimeline()` returning `json: cannot unmarshal number into Go value of type anaconda.Contributor`

    `GetUserTimeline()` returning `json: cannot unmarshal number into Go value of type anaconda.Contributor`

    Here is how we call GetUserTimeline():

    v := url.Values{}
    
    v.Set("count", "1000")
    v.Set("screen_name", screenName)
    
    tweets, err := api.GetUserTimeline(v)
    

    We declare api in another function and pass it to the function that gets the users timeline:

    api := newAnacondaAPI(u.AuthtokenVal, u.AuthtokenSecretVal)
    

    This is the error we get:

    json: cannot unmarshal number into Go value of type anaconda.Contributor
    

    Also we cannot typecast it to type *anaconda.ApiError

    This panics:

    err, ok := err.(*anaconda.ApiError)
    if !ok{
      panic("cannot typecast error")
    }
    
    

    We have done thousands of successful Twitter scans and we just encountered this for the first time tonight.

    Any ideas what's causing this? How can I help you guys debug this? This code is running on our production server and we need to fix this ASAP, so no more users are affected.

  • Fix wrong return type of get direct message show function

    Fix wrong return type of get direct message show function

    I found an error when I use function GetDirectMessagesShow My code is api.GetDirectMessagesShow(url.Values{"id": []string{direct_message_id}). An error message is

    json: cannot unmarshal object into Go value of type []anaconda.DirectMessage

    According to twitter api document https://dev.twitter.com/rest/reference/get/direct_messages/show. It returns a single direct message, specified by an id parameter. It's example response shows there is a direct message in an array as show below. [ { "created_at": "Mon Aug 27 17:21:03 +0000 2012","..." } ] But when I use api via twitter api console, it returns only a direct message, not in an array. It should return DirectMessage, not []DirectMessage. Then I change the return data type from []DirectMessage to DirectMessage, it returns data without an error.

  • GetFriendsListAll return only 200 friends

    GetFriendsListAll return only 200 friends

    I tried get all friends of user but it returns only 200 of them. How can I get all of them ?

    api := getNewAPI(token, tokenSecret)
    v := url.Values{}
    v.Set("count", "200")
    v.Set("skip_status", "true")
    friends := <-api.GetFriendsListAll(v)
  • Decouple TwitterApi from global oauthClient

    Decouple TwitterApi from global oauthClient

    Each TwitterApi now maintains its own oauthClient. The global oauthClient has been replaced by a slimmer global oauthCredentials to maintain backwards-compatibility with the old API.

    This fixes #101 and is based on #182.

    I'd appreciate a thorough review.

  • Support the new `extended tweet_mode` API

    Support the new `extended tweet_mode` API

    Twitter's API has changed and now shortens statuses that are longer than 140 chars, but have an acceptable length by the new Twitter rules.

    This change introduces Tweet.FullText, which contains the unshortened form of the status. Tweet.Text's behavior should be unchanged and will contain the shortened form. All API requests are now executed in the new extended mode.

    Sadly the streaming API now behaves slightly different to the regular REST API and contains the extended Tweet information in a separate struct. This change also parses this extra struct and correctly merges the status into the Tweet struct, so both API modes behave the same and remain backwards compatible, as far as anaconda users are concerned.

    This PR makes #158 and #190 obsolete.

  • Cannot unmarshal Tweet.Scopes from JSON.

    Cannot unmarshal Tweet.Scopes from JSON.

    Anaconda I often use is very useful. Thank you always.

    But at times I bump into "json: cannot unmarshal array into Go value of type string". Probably I think a type of Tweet.Scopes is different. Is it not map[string]string but map[string]bool?

    • https://github.com/ChimeraCoder/anaconda/blob/master/tweet.go#L30
  • Parse Tweet Coordinate

    Parse Tweet Coordinate

    Hello,

    I am relatively new to Go so please forgive me if this is a noob question.

    I am trying to parse the coordinates out of a tweet. Currently I have the following code:

    for _, tweet := range tweets {
        p := tweet.Coordinates.(map[string]interface {})
        c := p["coordinates"].([]interface{})
        lat := c[1].(float64)
        lng := c[0].(float64)
    

    While this works fine I am wondering if there is a more idiomatic / type safe way too do this - perhaps with a struct like this (though I have no idea how to use this struct):

    type geoJSON struct {
        Coordinates []float64 `json:"coordinates"`
        Type        string    `json:"type"`
    }
    
  • Add two methods including VerifyCredentials. Add Rate Limit checking capability.

    Add two methods including VerifyCredentials. Add Rate Limit checking capability.

    Two methods were added to TwitterApi: GetSelf() and VerifyCredentials() which both request at /account/verify_credentials

    Errors thrown by decodeResponse are of a new type: *ApiError which returns the same string as legacy to err.Error(). But, this new error type can now be used to determine Rate Limit errors:

    if apiError, ok := err.(*ApiError); ok {
      if rateLimited, nextWindow := apiError.RateLimitCheck(); rateLimited {
        time.Sleep(nextWindow.Sub(time.Now()))
      } else {
        panic(err)
      }
    } else {
      panic(err)
    }
    
  • Multiple applications per executable

    Multiple applications per executable

    Hello,

    While making the twitter bot I realise that I should have to call two applications, e.g. use different application keys at the same time. It looks like the anaconda currently does not support it. I do not mind try to do it myself, but do you maybe have design considerations about it?

    Regards, Alex

  • Transports

    Transports

    Make it possible to provide another RoundTrip Transport to http.Client.

    This because limitations of some PaaS providers like GAE which does not allow DefaultClient and DefaultTransport.

    Changes does not break any of existing functionalists.

    See: https://developers.google.com/appengine/docs/go/urlfetch

  • I want to detect that a twitter user is tweeting.

    I want to detect that a twitter user is tweeting.

    When a specified user tweeted, I want to detect that tweet.

    How should I use which function of this project?

    v := url.Values{}
    s := api.PublicStreamFilter(v)
    
    v.Add("follow", "2876288241")
    
    for {
    item := <-s.C
    fmt.Println(item)
    }
    

    Result: {[] Sun Mar 07 12:24:31 +0000 2021 [] {[] [] {[]} [] []} {[] [] {[]} [] []} { [] {[] [] {[]} [] []} {[] [] {[]} [] []}} 0 false low xxxxxxxxxxxxx false 1368538049487978499 1368538049487978499 0
    0 false und {map[] {[] } [] {[] } [] } 0 false false 0 false Twitter Web App map[] xxxxxxxxxxxxx {false Fri Nov 14 11:50:22 +0000 2014 true false {[] [] {[]} [] []} 0 false 4 false 1 false false 2876288241 2876288241 false false 0 Daily Kids Games false C0DEED http://abs.twimg.com/images/themes/theme1/bg.png https://abs.twimg.com/images/themes/theme1/bg.png false https://pbs.twimg.com/profile_banners/2876288241/1415966811 http://pbs.twimg.com/profile_images/533227532913356803/l-x_UByU_normal.png https://pbs.twimg.com/profile_images/533227532913356803/l-x_UByU_normal.png 1DA1F2 C0DEED DDEEF6 333333 true false dailykidsgames false 2 0 false [] } false [] } {1368538049487978499 1368538049487978499 2876288241 2876288241}

  • App-only auth

    App-only auth

    I am using anaconda for mining hashtag information through the Twitter search API. As the docs states user auth allows 180 requests per 15 minutes (around 18000 tweets per 15 minutes) while app-only auth allows 450 requests per 15 minutes (around 45000 tweets per 15 minutes), which makes a huge difference as I am mining hashtags with up to hundred thousands of tweets in a single day.

    I noticed dghubble/go-twitter has an app-only auth example. I wonder if the same thing is possible through anaconda. If not, consider this a request for this feature.

    Thank you so much for this awesome library.

  •  The field `reply_count` is not included in `anaconda.Tweet`.

    The field `reply_count` is not included in `anaconda.Tweet`.

    The field "reply_count" is not included in the 'anaconda.Tweet' object.

    Is there a possibility of getting the reply_count for each tweet, Since both retweet_count and favorite_count are available within the 'anaconda.Tweet' object.?

wtf? paranormal twitter.com activity using Twitter Cards. Migros.tr #DoITYourself

GTKE - go-tweet-kart-ele wtf? paranormal twitter.com activity using Twitter Cards. Migros.tr #DoITYourself Just for fun. Go. # You have go. go install

Dec 7, 2021
Go-twitter - Simple Prototype for Twitter with frontend and backend
Go-twitter - Simple Prototype for Twitter with frontend and backend

Twitter Clone Introduction A Twitter clone created with Golang, PostgreSQL, Redi

Feb 21, 2022
A Go client library for the Twitter 1.1 API

Anaconda Anaconda is a simple, transparent Go package for accessing version 1.1 of the Twitter API. Successful API queries return native Go structs th

Jan 1, 2023
Go Twitter REST and Streaming API v1.1

go-twitter go-twitter is a Go client library for the Twitter API. Check the usage section or try the examples to see how to access the Twitter API. Fe

Dec 28, 2022
Scrape the Twitter Frontend API without authentication with Golang.

Twitter Scraper Twitter's API is annoying to work with, and has lots of limitations — luckily their frontend (JavaScript) has it's own API, which I re

Dec 29, 2022
A REST API microservices-based Twitter Clone server.

Simple API Twitter Clone A REST API microservices-based project to fetch, edit, post, and delete tweets. API documentation The API documentation is bu

May 13, 2022
twitter clone front-end for Internet Engineering course - fall 99 built by go+echo

twitter backend build twitter-like back-end for internet engeering course - fall 99 with go+echo+gorm team mates Roozbeh Sharifnasab + Parsa Fadaee +

Nov 9, 2022
Periodically collect data about my Twitter account and check in to github to preserve an audit trail.

Twitter audit trail backup This repository backs up my follower list, following list, blocked accounts list and muted accounts list periodically using

Dec 28, 2022
Twitter backend - Golang
Twitter backend - Golang

A Twitter-like Website This repository contains the backend code for the final project of Fall 2020 Internet Engineering course. In this project,

Nov 26, 2022
Twitter ID Finder For Golang

Twitter ID Finder n文字の全数IDを探せます Usage $ make go build -o main main.go $ ./main Twitter ID Finder Creator: @_m_vt Digits: 2 Target IDs: 100 Really? [

Dec 12, 2021
An app/container built in Go to automate a Twitter account using Notion

Notion Tweeter Notion Tweeter is a utility I built using Go to help automate scheduling my tweets using Notion as a backend. More documentation coming

Sep 26, 2022
Clusterpedia-client - clusterpedia-client supports the use of native client-go mode to call the clusterpedia API

clusterpedia-client supports the use of native client-go mode to call the cluste

Jan 7, 2022
Client-go - Clusterpedia-client supports the use of native client-go mode to call the clusterpedia API

clusterpedia-client supports the use of native client-go mode to call the cluste

Dec 5, 2022
A Go client implementing a client-side distributed consumer group client for Amazon Kinesis.
A Go client implementing a client-side distributed consumer group client for Amazon Kinesis.

Kinesumer is a Go client implementing a client-side distributed consumer group client for Amazon Kinesis.

Jan 5, 2023
Nutanix-client-go - Go client for the Nutanix Prism V3 API

nutanix-client-go This repository contains portions of the Nutanix API client code in nutanix/terraform-provider-nutanix. It has been extracted to red

Jan 6, 2022
Aoe4-client - Client library for aoe4 leaderboards etc

AOE4 Client Overview This is a go client used to query AOE4 data from either the

Jan 18, 2022
Go client for the YNAB API. Unofficial. It covers 100% of the resources made available by the YNAB API.

YNAB API Go Library This is an UNOFFICIAL Go client for the YNAB API. It covers 100% of the resources made available by the YNAB API. Installation go

Oct 6, 2022
An API client for the Notion API implemented in Golang

An API client for the Notion API implemented in Golang

Dec 30, 2022
A Wrapper Client for Google Spreadsheet API (Sheets API)

Senmai A Wrapper Client for Google Spreadsheet API (Sheets API) PREPARATION Service Account and Key File Create a service account on Google Cloud Plat

Nov 5, 2021