Skip to content

Commit e0db0ca

Browse files
authored
introduce PromotedTweet.attach() method (#212)
* introduce PromotedTweet.attach() method - and deprecate .save() method * Update example * leave PromotedTweet.save() but mark as deprecated
1 parent e83a82c commit e0db0ca

File tree

4 files changed

+87
-17
lines changed

4 files changed

+87
-17
lines changed

examples/promoted_tweet.py

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,32 +8,32 @@
88
CONSUMER_SECRET = 'your consumer secret'
99
ACCESS_TOKEN = 'user access token'
1010
ACCESS_TOKEN_SECRET = 'user access token secret'
11-
ADS_ACCOUNT = 'ads account id'
11+
ACCOUNT_ID = 'ads account id'
1212

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

1616
# load up the account instance, campaign and line item
17-
account = client.accounts(ADS_ACCOUNT)
17+
account = client.accounts(ACCOUNT_ID)
1818
campaign = account.campaigns().next()
1919
line_item = account.line_items(None, campaign_ids=campaign.id).next()
2020

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

24-
# promote the tweet using our line item
25-
promoted_tweet = PromotedTweet(account)
26-
promoted_tweet.line_item_id = line_item.id
27-
promoted_tweet.tweet_id = tweet1['id']
28-
promoted_tweet.save()
29-
3024
# create request for a nullcasted tweet with a website card
3125
website_card = WebsiteCard.all(account).next()
32-
text = "Fine. There can be two. {card_url}".format(card_url=website_card.preview_url)
33-
tweet2 = Tweet.create(account, text)
26+
tweet2 = Tweet.create(account, text='Fine. There can be two.', card_uri=website_card.card_uri)
3427

3528
# promote the tweet using our line item
36-
promoted_tweet = PromotedTweet(account)
37-
promoted_tweet.line_item_id = line_item.id
38-
promoted_tweet.tweet_id = tweet2['id']
39-
promoted_tweet.save()
29+
tweet_ids = [tweet1['id'], tweet2['id']]
30+
31+
response = PromotedTweet.attach(
32+
account,
33+
line_item_id=line_item.id,
34+
tweet_ids=tweet_ids
35+
)
36+
37+
for i in response:
38+
print(i.id)
39+
print(i.tweet_id)
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"data_type": "promoted_tweet",
3+
"data": [
4+
{
5+
"line_item_id": "2b7xw",
6+
"id": "6thl4",
7+
"entity_status": "ACTIVE",
8+
"created_at": "2015-04-11T20:50:25Z",
9+
"updated_at": "2015-04-11T20:50:25Z",
10+
"approval_status": "ACCEPTED",
11+
"tweet_id": "585127452231467008",
12+
"deleted": false
13+
}
14+
],
15+
"request": {
16+
"params": {
17+
"line_item_id": "2b7xw",
18+
"tweet_ids": [
19+
585127452231467008
20+
],
21+
"account_id": "2iqph"
22+
}
23+
},
24+
"total_count": 1
25+
}

tests/test_promoted_tweets.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,34 @@ def test_promoted_tweets_load():
6565
promoted_tweet = PromotedTweet.load(account, '6thl4')
6666
assert promoted_tweet.id == '6thl4'
6767
assert promoted_tweet.entity_status == 'ACTIVE'
68+
69+
70+
@responses.activate
71+
def test_promoted_tweets_attach():
72+
responses.add(responses.GET,
73+
with_resource('/' + API_VERSION + '/accounts/2iqph'),
74+
body=with_fixture('accounts_load'),
75+
content_type='application/json')
76+
77+
responses.add(responses.POST,
78+
with_resource('/' + API_VERSION + '/accounts/2iqph/promoted_tweets'),
79+
body=with_fixture('promoted_tweets_attach'),
80+
content_type='application/json')
81+
82+
client = Client(
83+
characters(40),
84+
characters(40),
85+
characters(40),
86+
characters(40)
87+
)
88+
89+
account = Account.load(client, '2iqph')
90+
response = PromotedTweet.attach(
91+
account,
92+
line_item_id='2b7xw',
93+
tweet_ids=['585127452231467008']
94+
)
95+
96+
assert isinstance(response, Cursor)
97+
assert response.count == 1
98+
assert response.first.id == '6thl4'

twitter_ads/creative.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
"""Container for all creative management logic used by the Ads API SDK."""
44

55
from requests.exceptions import HTTPError
6-
76
from twitter_ads import API_VERSION
87
from twitter_ads.cursor import Cursor
98
from twitter_ads.enum import TRANSFORM
@@ -40,6 +39,9 @@ class PromotedTweet(Analytics, Resource, Persistence):
4039
RESOURCE_COLLECTION = '/' + API_VERSION + '/accounts/{account_id}/promoted_tweets'
4140
RESOURCE = '/' + API_VERSION + '/accounts/{account_id}/promoted_tweets/{id}'
4241

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

62+
@classmethod
63+
def attach(klass, account, line_item_id=None, tweet_ids=None):
64+
"""
65+
Associate one or more Tweets with the specified line item.
66+
"""
67+
params = {}
68+
params['line_item_id'] = line_item_id
69+
params['tweet_ids'] = ",".join(map(str, tweet_ids))
70+
71+
resource = klass.RESOURCE_COLLECTION.format(account_id=account.id)
72+
request = Request(account.client, 'post', resource, params=params)
73+
return Cursor(klass, request, init_with=[account])
74+
6075

6176
# promoted tweet properties
6277
# read-only
@@ -66,9 +81,8 @@ def save(self):
6681
resource_property(PromotedTweet, 'entity_status', readonly=True)
6782
resource_property(PromotedTweet, 'id', readonly=True)
6883
resource_property(PromotedTweet, 'updated_at', readonly=True, transform=TRANSFORM.TIME)
69-
# writable
84+
resource_property(PromotedTweet, 'tweet_id')
7085
resource_property(PromotedTweet, 'line_item_id')
71-
resource_property(PromotedTweet, 'tweet_id') # SDK limitation
7286

7387

7488
class AccountMedia(Resource, Persistence):

0 commit comments

Comments
 (0)