From e0e4c3dcf2882a8cd2a1f6c0017992650cfdb2e5 Mon Sep 17 00:00:00 2001 From: Kris Nova Date: Fri, 13 Mar 2020 22:01:07 -0700 Subject: [PATCH 1/2] Starting work on polls --- tweets.go | 10 ++++++++++ twitter_entities.go | 11 +++++++++++ 2 files changed, 21 insertions(+) diff --git a/tweets.go b/tweets.go index 0baf4b2..ce50a09 100644 --- a/tweets.go +++ b/tweets.go @@ -36,6 +36,16 @@ func (a TwitterApi) GetRetweets(id int64, v url.Values) (tweets []Tweet, err err return tweets, (<-response_ch).err } +//PostTweetWithPoll will create a tweet with the specified status message and a user defined poll +func (a TwitterApi) PostTweetWithPoll(status string, v url.Values, choices []string, pollDurationMinutes int) (tweet Tweet, err error) { + // TODO @kris-nova we can support media here which would be cool because it's in beta and you can't do that from the web UI + v = cleanValues(v) + v.Set("status", status) + response_ch := make(chan response) + a.queryQueue <- query{a.baseUrl + fmt.Sprintf("/account/%d.json", id), v, &tweet, _POST, response_ch} + return tweet, (<-response_ch).err +} + //PostTweet will create a tweet with the specified status message func (a TwitterApi) PostTweet(status string, v url.Values) (tweet Tweet, err error) { v = cleanValues(v) diff --git a/twitter_entities.go b/twitter_entities.go index 6d4e483..b6d4fd5 100644 --- a/twitter_entities.go +++ b/twitter_entities.go @@ -29,6 +29,17 @@ type Entities struct { Id_str string `json:"id_str"` } `json:"user_mentions"` Media []EntityMedia `json:"media"` + Polls EntityPolls `json:"polls"` +} + +type EntityPollOptions struct { + Position int `json:"position"` + Text string `json:"text"` +} + +type EntityPolls struct { + Options []EntityPollOptions `json:"options"` + DurationMinutes int `json:"duration_minutes"` } type EntityMedia struct { From 89174c2d435b837b5d3432f3cb77b9f64898cc30 Mon Sep 17 00:00:00 2001 From: Kris Nova Date: Fri, 13 Mar 2020 23:11:34 -0700 Subject: [PATCH 2/2] Adding support for poll cards Signed-off-by: Kris Nova --- .gitignore | 1 + poll.go | 110 +++++++++++++++++++++++++++++++++++++++++++++++++++++ tweets.go | 10 ----- twitter.go | 1 + 4 files changed, 112 insertions(+), 10 deletions(-) create mode 100644 poll.go diff --git a/.gitignore b/.gitignore index db912a1..5b5616a 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ conf.sh *.patch anaconda.test +.idea* diff --git a/poll.go b/poll.go new file mode 100644 index 0000000..8a41d5d --- /dev/null +++ b/poll.go @@ -0,0 +1,110 @@ +package anaconda + +import ( + "fmt" + "net/url" +) + +//{ +// "request": { +// "params": { +// "first_choice": "East", +// "name": "best coast poll", +// "second_choice": "West", +// "media_key": "13_950589518557540353", +// "duration_in_minutes": 10080 +// } +// }, +// "data": { +// "video_poster_height": "9", +// "name": "best coast poll", +// "start_time": "2018-01-09T04:51:34Z", +// "first_choice": "East", +// "video_height": "9", +// "video_url": "https://video.twimg.com/amplify_video/vmap/950589518557540353.vmap", +// "content_duration_seconds": "8", +// "second_choice": "West", +// "end_time": "2018-01-16T04:51:34Z", +// "id": "57i77", +// "video_width": "16", +// "video_hls_url": "https://video.twimg.com/amplify_video/950589518557540353/vid/1280x720/BRkAhPxFoBREIaFA.mp4", +// "created_at": "2018-01-09T04:51:34Z", +// "duration_in_minutes": "10080", +// "card_uri": "card://950590850777497601", +// "updated_at": "2018-01-09T04:51:34Z", +// "video_poster_url": "https://pbs.twimg.com/amplify_video_thumb/950589518557540353/img/nZ1vX_MXYqmvbsXP.jpg", +// "video_poster_width": "16", +// "deleted": false, +// "card_type": "VIDEO_POLLS" +// } +//} +type PollCard struct { + Request PollRequest `json:"request"` + Data PollData `json:"data"` +} + +type PollData struct { + Name string `json:"name"` + FirstChoice string `json:"first_choice"` + SecondChoice string `json:"second_choice"` + ThirdChoice string `json:"third_choice"` + FourthChoice string `json:"fourthChoice"` + MediaKey string `json:"media_key"` + DurationInMinutes int `json:"duration_in_minutes"` + CardType string `json:"card_type"` + CardURI string `json:"card_uri"` +} + +type PollParams struct { + FirstChoice string `json:"first_choice"` + SecondChoice string `json:"second_choice"` + ThirdChoice string `json:"third_choice"` + FourthChoice string `json:"fourthChoice"` + MediaKey string `json:"media_key"` + DurationInMinutes int `json:"duration_in_minutes"` +} + +type PollRequest struct { + Params PollParams `json:"params"` +} + +//CreatePollCard will create a new poll card that can be attached to a tweet +func (a TwitterApi) CreatePollCard(choices []string, accountID string, durationInMinutes int, v url.Values) (card PollCard, err error) { + // TODO @kris-nova we can support media here which would be cool because it's in beta and you can't do that from the web UI + var firstChoice, secondChoice, thirdChoice, fourthChoice string + choiceCount := len(choices) + if choiceCount == 1 { + firstChoice = choices[0] + if len(firstChoice) > 25 { + return card, fmt.Errorf("choice longer than 25 characters") + } + } + if choiceCount == 2 { + secondChoice = choices[1] + if len(secondChoice) > 25 { + return card, fmt.Errorf("choice longer than 25 characters") + } + } + if choiceCount == 3 { + thirdChoice = choices[2] + if len(thirdChoice) > 25 { + return card, fmt.Errorf("choice longer than 25 characters") + } + } + if choiceCount == 4 { + fourthChoice = choices[3] + if len(fourthChoice) > 25 { + return card, fmt.Errorf("choice longer than 25 characters") + } + } + v = cleanValues(v) + v.Set("first_choice", firstChoice) + v.Set("second_choice", secondChoice) + v.Set("third_choice", thirdChoice) + v.Set("fourth_choice", fourthChoice) + v.Set("account_id", accountID) + v.Set("duration_in_minutes", fmt.Sprintf("%d", durationInMinutes)) + response_ch := make(chan response) + a.queryQueue <- query{AddBaseUrl + fmt.Sprintf("/account/%s/cards/poll.json", accountID), v, &card, _POST, response_ch} + return card, (<-response_ch).err +} diff --git a/tweets.go b/tweets.go index ce50a09..0baf4b2 100644 --- a/tweets.go +++ b/tweets.go @@ -36,16 +36,6 @@ func (a TwitterApi) GetRetweets(id int64, v url.Values) (tweets []Tweet, err err return tweets, (<-response_ch).err } -//PostTweetWithPoll will create a tweet with the specified status message and a user defined poll -func (a TwitterApi) PostTweetWithPoll(status string, v url.Values, choices []string, pollDurationMinutes int) (tweet Tweet, err error) { - // TODO @kris-nova we can support media here which would be cool because it's in beta and you can't do that from the web UI - v = cleanValues(v) - v.Set("status", status) - response_ch := make(chan response) - a.queryQueue <- query{a.baseUrl + fmt.Sprintf("/account/%d.json", id), v, &tweet, _POST, response_ch} - return tweet, (<-response_ch).err -} - //PostTweet will create a tweet with the specified status message func (a TwitterApi) PostTweet(status string, v url.Values) (tweet Tweet, err error) { v = cleanValues(v) diff --git a/twitter.go b/twitter.go index 069d581..4149e18 100644 --- a/twitter.go +++ b/twitter.go @@ -62,6 +62,7 @@ const ( BaseUrlV1 = "https://api.twitter.com/1" BaseUrl = "https://api.twitter.com/1.1" UploadBaseUrl = "https://upload.twitter.com/1.1" + AddBaseUrl = "https://ads-api.twitter.com/7" ) var (