diff --git a/api.go b/api.go new file mode 100644 index 0000000..fbff826 --- /dev/null +++ b/api.go @@ -0,0 +1,81 @@ +package twitter + +import "errors" + +func NewTwitterClient(consumerKey, consumerSecret string, useServerClient bool) *Twitter { + newClient := new(Twitter) + + if useServerClient { + newClient.client = NewServerClient(consumerKey, consumerSecret) + } else { + newClient.client = NewDesktopClient(consumerKey, consumerSecret) + } + + newClient.useServerClient = useServerClient + return newClient +} + +type Twitter struct { + client interface{} + useServerClient bool +} + +func (t *Twitter) getServerClient() *ServerClient { + if srv, ok := t.client.(ServerClient); ok { + return &srv + } + + return nil +} + +func (t *Twitter) getDesktopClient() *DesktopClient { + if dst, ok := t.client.(DesktopClient); ok { + return &dst + } + + return nil +} + +func (t *Twitter) GetAuthURL(tokenUrl string) string { + if t.useServerClient { + return t.getServerClient().GetAuthURL(tokenUrl) + } else { + return "" + } + +} + +func (t *Twitter) CompleteAuth(tokenKey, verificationCode string) error { + if t.useServerClient { + return t.getServerClient().CompleteAuth(tokenKey, verificationCode) + } else { + return errors.New("New server client") + } +} + +func (t *Twitter) QueryTimeLine(count int) (interface{}, error) { + if t.useServerClient { + return t.getServerClient().QueryTimeLine(count) + } else { + return t.getDesktopClient().QueryTimeLine(count) + + } +} + +func (t *Twitter) QueryFollower(count int) (interface{}, error) { + if t.useServerClient { + return t.getServerClient().QueryTimeLine(count) + } else { + return t.getDesktopClient().QueryTimeLine(count) + + } +} + +func (t *Twitter) QueryTest(url string) (interface{}, error) { + if t.useServerClient { + return t.getServerClient().BasicQuery(url) + } else { + return t.getDesktopClient().BasicQuery(url) + + } +} diff --git a/client.go b/client.go new file mode 100644 index 0000000..81e5591 --- /dev/null +++ b/client.go @@ -0,0 +1,76 @@ +package twitter + +import ( + "encoding/json" + "errors" + "fmt" + "io/ioutil" + "log" + "net/http" + + "github.com/mrjones/oauth" +) + +const ( + //Basic OAuth related URLs + OAUTH_REQUES_TOKEN string = "https://api.twitter.com/oauth/request_token" + OAUTH_AUTH_TOKEN string = "https://api.twitter.com/oauth/authorize" + OAUTH_ACCESS_TOKEN string = "https://api.twitter.com/oauth/access_token" + + //List API URLs + API_BASE string = "https://api.twitter.com/1.1/" + API_TIMELINE string = API_BASE + "statuses/home_timeline.json" + API_FOLLOWER string = API_BASE + "followers/ids.json" +) + +type Client struct { + HttpConn *http.Client + OAuthConsumer *oauth.Consumer +} + +func NewClient(consumerKey, consumerSecret string) *Client { + newClient := &Client{} + + newClient.OAuthConsumer = oauth.NewConsumer( + consumerKey, + consumerSecret, + oauth.ServiceProvider{ + RequestTokenUrl: OAUTH_REQUES_TOKEN, + AuthorizeTokenUrl: OAUTH_AUTH_TOKEN, + AccessTokenUrl: OAUTH_ACCESS_TOKEN, + }, + ) + + //Enable debug info + newClient.OAuthConsumer.Debug(true) + + return newClient +} + +func (c *Client) BasicQuery(queryString string) (interface{}, error) { + if c.HttpConn == nil { + return nil, errors.New("No Client OAuth") + } + + response, err := c.HttpConn.Get(queryString) + if err != nil { + log.Fatal(err) + } + defer response.Body.Close() + + var data map[string]interface{} + bits, err := ioutil.ReadAll(response.Body) + err = json.Unmarshal(bits, &data) + + return data, err +} + +func (c *Client) QueryTimeLine(count int) (interface{}, error) { + requesURL := fmt.Sprintf("%s?count=%d", API_TIMELINE, count) + return c.BasicQuery(requesURL) +} + +func (c *Client) QueryFollower(count int) (interface{}, error) { + requesURL := fmt.Sprintf("%s?count=%d", API_FOLLOWER, count) + return c.BasicQuery(requesURL) +} diff --git a/desktop_client.go b/desktop_client.go new file mode 100644 index 0000000..5832123 --- /dev/null +++ b/desktop_client.go @@ -0,0 +1,44 @@ +package twitter + +import ( + "fmt" + "log" +) + +func NewDesktopClient(consumerKey, consumerSecret string) *DesktopClient { + newClient := NewClient(consumerKey, consumerKey) + newServer := new(DesktopClient) + newServer.Client = *newClient + return newServer +} + +type DesktopClient struct { + Client +} + +func (d *DesktopClient) DoAuth() error { + requestToken, u, err := d.OAuthConsumer.GetRequestTokenAndUrl("oob") + fmt.Println("rest token=", requestToken, " err=", err) + if err != nil { + log.Fatal(err) + } + + fmt.Println("(1) Go to: " + u) + fmt.Println("(2) Grant access, you should get back a verification code.") + fmt.Println("(3) Enter that verification code here: ") + + verificationCode := "" + fmt.Scanln(&verificationCode) + + accessToken, err := d.OAuthConsumer.AuthorizeToken(requestToken, verificationCode) + if err != nil { + log.Fatal(err) + } + + d.HttpConn, err = d.OAuthConsumer.MakeHttpClient(accessToken) + if err != nil { + log.Fatal(err) + } + + return err +} diff --git a/server_client.go b/server_client.go new file mode 100644 index 0000000..8a24010 --- /dev/null +++ b/server_client.go @@ -0,0 +1,43 @@ +package twitter + +import ( + "log" + + "github.com/mrjones/oauth" +) + +func NewServerClient(consumerKey, consumerSecret string) *ServerClient { + newClient := NewClient(consumerKey, consumerKey) + newServer := new(ServerClient) + newServer.Client = *newClient + newServer.OAuthTokens = make(map[string]*oauth.RequestToken) + return newServer +} + +type ServerClient struct { + Client + OAuthTokens map[string]*oauth.RequestToken +} + +func (s *ServerClient) GetAuthURL(tokenUrl string) string { + token, requestUrl, err := s.OAuthConsumer.GetRequestTokenAndUrl(tokenUrl) + if err != nil { + log.Fatal(err) + } + // Make sure to save the token, we'll need it for AuthorizeToken() + s.OAuthTokens[token.Token] = token + return requestUrl +} + +func (s *ServerClient) CompleteAuth(tokenKey, verificationCode string) error { + accessToken, err := s.OAuthConsumer.AuthorizeToken(s.OAuthTokens[tokenKey], verificationCode) + if err != nil { + log.Fatal(err) + } + + s.HttpConn, err = s.OAuthConsumer.MakeHttpClient(accessToken) + if err != nil { + log.Fatal(err) + } + return nil +}