Skip to content

introduce PromotedTweet.attach() method #212

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 14 additions & 14 deletions examples/promoted_tweet.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,32 +8,32 @@
CONSUMER_SECRET = 'your consumer secret'
ACCESS_TOKEN = 'user access token'
ACCESS_TOKEN_SECRET = 'user access token secret'
ADS_ACCOUNT = 'ads account id'
ACCOUNT_ID = 'ads account id'

# initialize the twitter ads api client
client = Client(CONSUMER_KEY, CONSUMER_SECRET, ACCESS_TOKEN, ACCESS_TOKEN_SECRET)

# load up the account instance, campaign and line item
account = client.accounts(ADS_ACCOUNT)
account = client.accounts(ACCOUNT_ID)
campaign = account.campaigns().next()
line_item = account.line_items(None, campaign_ids=campaign.id).next()

# create request for a simple nullcasted tweet
tweet1 = Tweet.create(account, text='There can be only one...')

# promote the tweet using our line item
promoted_tweet = PromotedTweet(account)
promoted_tweet.line_item_id = line_item.id
promoted_tweet.tweet_id = tweet1['id']
promoted_tweet.save()

# create request for a nullcasted tweet with a website card
website_card = WebsiteCard.all(account).next()
text = "Fine. There can be two. {card_url}".format(card_url=website_card.preview_url)
tweet2 = Tweet.create(account, text)
tweet2 = Tweet.create(account, text='Fine. There can be two.', card_uri=website_card.card_uri)

# promote the tweet using our line item
promoted_tweet = PromotedTweet(account)
promoted_tweet.line_item_id = line_item.id
promoted_tweet.tweet_id = tweet2['id']
promoted_tweet.save()
tweet_ids = [tweet1['id'], tweet2['id']]

response = PromotedTweet.attach(
account,
line_item_id=line_item.id,
tweet_ids=tweet_ids
)

for i in response:
print(i.id)
print(i.tweet_id)
25 changes: 25 additions & 0 deletions tests/fixtures/promoted_tweets_attach.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"data_type": "promoted_tweet",
"data": [
{
"line_item_id": "2b7xw",
"id": "6thl4",
"entity_status": "ACTIVE",
"created_at": "2015-04-11T20:50:25Z",
"updated_at": "2015-04-11T20:50:25Z",
"approval_status": "ACCEPTED",
"tweet_id": "585127452231467008",
"deleted": false
}
],
"request": {
"params": {
"line_item_id": "2b7xw",
"tweet_ids": [
585127452231467008
],
"account_id": "2iqph"
}
},
"total_count": 1
}
31 changes: 31 additions & 0 deletions tests/test_promoted_tweets.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,34 @@ def test_promoted_tweets_load():
promoted_tweet = PromotedTweet.load(account, '6thl4')
assert promoted_tweet.id == '6thl4'
assert promoted_tweet.entity_status == 'ACTIVE'


@responses.activate
def test_promoted_tweets_attach():
responses.add(responses.GET,
with_resource('/' + API_VERSION + '/accounts/2iqph'),
body=with_fixture('accounts_load'),
content_type='application/json')

responses.add(responses.POST,
with_resource('/' + API_VERSION + '/accounts/2iqph/promoted_tweets'),
body=with_fixture('promoted_tweets_attach'),
content_type='application/json')

client = Client(
characters(40),
characters(40),
characters(40),
characters(40)
)

account = Account.load(client, '2iqph')
response = PromotedTweet.attach(
account,
line_item_id='2b7xw',
tweet_ids=['585127452231467008']
)

assert isinstance(response, Cursor)
assert response.count == 1
assert response.first.id == '6thl4'
20 changes: 17 additions & 3 deletions twitter_ads/creative.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
"""Container for all creative management logic used by the Ads API SDK."""

from requests.exceptions import HTTPError

from twitter_ads import API_VERSION
from twitter_ads.cursor import Cursor
from twitter_ads.enum import TRANSFORM
Expand Down Expand Up @@ -40,6 +39,9 @@ class PromotedTweet(Analytics, Resource, Persistence):
RESOURCE_COLLECTION = '/' + API_VERSION + '/accounts/{account_id}/promoted_tweets'
RESOURCE = '/' + API_VERSION + '/accounts/{account_id}/promoted_tweets/{id}'

@Deprecated('This method has been deprecated and will no longer be available '
'in the next major version update. Please use PromotedTweet.attach() '
'method instead.')
def save(self):
"""
Saves or updates the current object instance depending on the
Expand All @@ -57,6 +59,19 @@ def save(self):
response = Request(self.account.client, 'post', resource, params=params).perform()
return self.from_response(response.body['data'][0])

@classmethod
def attach(klass, account, line_item_id=None, tweet_ids=None):
"""
Associate one or more Tweets with the specified line item.
"""
params = {}
params['line_item_id'] = line_item_id
params['tweet_ids'] = ",".join(map(str, tweet_ids))

resource = klass.RESOURCE_COLLECTION.format(account_id=account.id)
request = Request(account.client, 'post', resource, params=params)
return Cursor(klass, request, init_with=[account])


# promoted tweet properties
# read-only
Expand All @@ -66,9 +81,8 @@ def save(self):
resource_property(PromotedTweet, 'entity_status', readonly=True)
resource_property(PromotedTweet, 'id', readonly=True)
resource_property(PromotedTweet, 'updated_at', readonly=True, transform=TRANSFORM.TIME)
# writable
resource_property(PromotedTweet, 'tweet_id')
resource_property(PromotedTweet, 'line_item_id')
resource_property(PromotedTweet, 'tweet_id') # SDK limitation


class AccountMedia(Resource, Persistence):
Expand Down