Skip to content

Commit

Permalink
Feature/issue 56 manage tweet (#57)
Browse files Browse the repository at this point in the history
* created the request body

* added request validation

* added manage tweet APIs

* added the examples

* update the readme

* added the comments

* updatd typos
  • Loading branch information
g8rswimmer authored Dec 29, 2021
1 parent b6f7281 commit 214266f
Show file tree
Hide file tree
Showing 9 changed files with 686 additions and 0 deletions.
5 changes: 5 additions & 0 deletions v2/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ Here are the current twitter `v2` API features supported:
* [example](./_examples/user-lookup)
* [example: by usernames](./_examples/username-lookup)
* [User Dictionary](https://developer.twitter.com/en/docs/twitter-api/data-dictionary/object-model/user) - the user and all of its references related to it
* [Tweet Counts](https://developer.twitter.com/en/docs/twitter-api/tweets/counts/introduction)
* [example](./_examples/tweet-recent-counts)
* [Manage Tweet](https://developer.twitter.com/en/docs/twitter-api/tweets/manage-tweets/introduction)
* [create example](./_examples/tweet-create)
* [delete example](./_examples/tweet-delete)

## Examples
Much like `v1`, there is an `_example` directory to demostrate library usage. Refer to the [readme](./_examples) for more information.
Expand Down
14 changes: 14 additions & 0 deletions v2/_examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,20 @@ This [example](./tweet-lookup) demonstrates the tweets lookup API call.
go run *.go -token=YOUR_API_TOKEN -ids=1261326399320715264,1278347468690915330
```

## Create Tweet
This [example](./tweet-create) demonstrates the create tweet API call.

```
go run *.go -token=YOUR_API_TOKEN -text='Hello World'
```

## Delete Tweet
This [example](./tweet-delete) demonstrates the delete tweet API call.

```
go run *.go -token=YOUR_API_TOKEN -id=YOUR_TWEET_TO_DELETE
```

## Recent Tweet Count
This [example](./tweet-recent-counts) demonstrates the recent tweet counts API call.
```
Expand Down
53 changes: 53 additions & 0 deletions v2/_examples/tweet-create/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
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")
text := flag.String("text", "", "twitter text")
flag.Parse()

client := &twitter.Client{
Authorizer: authorize{
Token: *token,
},
Client: http.DefaultClient,
Host: "https://api.twitter.com",
}

req := twitter.CreateTweetRequest{
Text: *text,
}
fmt.Println("Callout to create tweet callout")

tweetResponse, err := client.CreateTweet(context.Background(), req)
if err != nil {
log.Panicf("create tweet error: %v", err)
}

enc, err := json.MarshalIndent(tweetResponse, "", " ")
if err != nil {
log.Panic(err)
}
fmt.Println(string(enc))
}
50 changes: 50 additions & 0 deletions v2/_examples/tweet-delete/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
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",
}

fmt.Println("Callout to delete tweet callout")

tweetResponse, err := client.DeleteTweet(context.Background(), *id)
if err != nil {
log.Panicf("delete tweet error: %v", err)
}

enc, err := json.MarshalIndent(tweetResponse, "", " ")
if err != nil {
log.Panic(err)
}
fmt.Println(string(enc))
}
90 changes: 90 additions & 0 deletions v2/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,96 @@ type Client struct {
Host string
}

// CreateTweet will let a user post polls, quote tweets, tweet with reply setting, tweet with geo, attach
// perviously uploaded media toa tweet and tag users, tweet to super followers, etc.
func (c *Client) CreateTweet(ctx context.Context, tweet CreateTweetRequest) (*CreateTweetResponse, error) {
if err := tweet.validate(); err != nil {
return nil, err
}
body, err := json.Marshal(tweet)
if err != nil {
return nil, fmt.Errorf("create tweet marshal error %w", err)
}
ep := tweetCreateEndpoint.url(c.Host)

req, err := http.NewRequestWithContext(ctx, http.MethodPost, ep, bytes.NewReader(body))
if err != nil {
return nil, fmt.Errorf("create tweet request: %w", err)
}
req.Header.Add("Content-Type", "application/json")
req.Header.Add("Accept", "application/json")
c.Authorizer.Add(req)

resp, err := c.Client.Do(req)
if err != nil {
return nil, fmt.Errorf("create tweet response: %w", err)
}
defer resp.Body.Close()

decoder := json.NewDecoder(resp.Body)

if resp.StatusCode != http.StatusCreated {
e := &ErrorResponse{}
if err := decoder.Decode(e); err != nil {
return nil, &HTTPError{
Status: resp.Status,
StatusCode: resp.StatusCode,
URL: resp.Request.URL.String(),
}
}
e.StatusCode = resp.StatusCode
return nil, e
}

raw := &CreateTweetResponse{}
if err := decoder.Decode(raw); err != nil {
return nil, fmt.Errorf("create tweet decode response %w", err)
}
return raw, nil
}

// DeleteTweet allow the user to delete a specific tweet
func (c *Client) DeleteTweet(ctx context.Context, id string) (*DeleteTweetResponse, error) {
if len(id) == 0 {
return nil, fmt.Errorf("delete tweet id is required")
}
ep := tweetDeleteEndpoint.urlID(c.Host, id)

req, err := http.NewRequestWithContext(ctx, http.MethodDelete, ep, nil)
if err != nil {
return nil, fmt.Errorf("delete tweet request: %w", err)
}
req.Header.Add("Accept", "application/json")
c.Authorizer.Add(req)

resp, err := c.Client.Do(req)
if err != nil {
return nil, fmt.Errorf("delete tweet response: %w", err)
}
defer resp.Body.Close()

decoder := json.NewDecoder(resp.Body)

if resp.StatusCode != http.StatusOK {
e := &ErrorResponse{}
if err := decoder.Decode(e); err != nil {
return nil, &HTTPError{
Status: resp.Status,
StatusCode: resp.StatusCode,
URL: resp.Request.URL.String(),
}
}
e.StatusCode = resp.StatusCode
return nil, e
}

raw := &DeleteTweetResponse{}
if err := decoder.Decode(raw); err != nil {
return nil, fmt.Errorf("delete tweet decode response %w", err)
}
return raw, nil
}

// TweetLookup returns information about a tweet or group of tweets specified by a group of tweet ids.
func (c *Client) TweetLookup(ctx context.Context, ids []string, opts TweetLookupOpts) (*TweetLookupResponse, error) {
ep := tweetLookupEndpoint.url(c.Host)
Expand Down
Loading

0 comments on commit 214266f

Please sign in to comment.