def pushEmails2Twitter(hashedEmails,twCred): from twitter_ads.client import Client from twitter_ads.audience import TailoredAudience from twitter_ads.enum import TA_LIST_TYPES, TA_OPERATIONS CONSUMER_KEY = 'your consumer key' CONSUMER_SECRET = 'your consumer secret' ACCESS_TOKEN = 'access token' ACCESS_TOKEN_SECRET = 'access token secret' ACCOUNT_ID = 'account id' # initialize the client client = Client(CONSUMER_KEY, CONSUMER_SECRET, ACCESS_TOKEN, ACCESS_TOKEN_SECRET) # load the advertiser account instance account = client.accounts(ACCOUNT_ID) # create a new tailored audience audience = TailoredAudience.create(account, '/path/to/file', 'my list', TA_LIST_TYPES.EMAIL) # check the processing status audience.status() # update the tailored audience audience.update('/path/to/file', TA_LIST_TYPES.TWITTER_ID, TA_OPERATIONS.REMOVE) audience.update('/path/to/file', TA_LIST_TYPES.PHONE_NUMBER, TA_OPERATIONS.ADD) # delete the tailored audience audience.delete() # add users to the account's global opt-out list TailoredAudience.opt_out(account, '/path/to/file', TA_OPERATIONS.HANDLE)
def json_handler(request): """ Returns json_data {"campaigns": [campaign_list} for given request """ client = Client(settings.SOCIAL_AUTH_TWITTER_KEY, settings.SOCIAL_AUTH_TWITTER_SECRET, settings.TWITTER_ACCESS_TOKEN, settings.TWITTER_ACCESS_TOKEN_SECRET) account_id = request.GET.get("account_id", "") campaign_id = request.GET.get("campaign_id", "") account = client.accounts(account_id) # TODO: Link to Ads API Docs for LineItem.rst line_items = account.line_items(None, campaign_ids=campaign_id) line_item_list = [] for line_item in line_items: name = line_item.name identifier = line_item.id objective = line_item.objective bid_amount = line_item.bid_amount_local_micro # Sometimes Bid Amount is None if bid_amount is not None: bid_amount = bid_amount / 10000 line_item_list.append({ "name": name, "id": identifier, "objective": objective, "bid_amount": bid_amount }) return HttpResponse(json.dumps({ "account_id": account_id, "campaign_id": campaign_id, "line_items": line_item_list }), content_type="application/json")
def new(request): """ Returns a new campaign """ client = Client(settings.SOCIAL_AUTH_TWITTER_KEY, settings.SOCIAL_AUTH_TWITTER_SECRET, settings.TWITTER_ACCESS_TOKEN, settings.TWITTER_ACCESS_TOKEN_SECRET) account_id = request.GET.get("account_id", "") campaign_name = request.GET.get("campaign", "") daily_budget = request.GET.get("daily_budget", "") account = client.accounts(account_id) # create your campaign json_data = {} try: campaign = Campaign(account) campaign.funding_instrument_id = account.funding_instruments().next( ).id campaign.daily_budget_amount_local_micro = int(daily_budget) * 1000 campaign.name = campaign_name campaign.paused = True campaign.start_time = datetime.datetime.utcnow() campaign.save() json_data = { "valid": True, "account_id": account_id, "campaign_name": campaign_name, "campaign_id": campaign.id } except Error as e: json_data["response"] = e.details json_data["valid"] = False # passing as we send the json_data pass return HttpResponse(json.dumps(json_data), content_type="application/json")
def new(request): """ Returns a new campaign """ client = Client( settings.SOCIAL_AUTH_TWITTER_KEY, settings.SOCIAL_AUTH_TWITTER_SECRET, settings.TWITTER_ACCESS_TOKEN, settings.TWITTER_ACCESS_TOKEN_SECRET) account_id = request.GET.get("account_id", "") campaign_name = request.GET.get("campaign", "") daily_budget = request.GET.get("daily_budget", "") account = client.accounts(account_id) # create your campaign json_data = {} try: campaign = Campaign(account) campaign.funding_instrument_id = account.funding_instruments().next().id campaign.daily_budget_amount_local_micro = int(daily_budget) * 1000 campaign.name = campaign_name campaign.paused = True campaign.start_time = datetime.datetime.utcnow() campaign.save() json_data = { "valid": True, "account_id": account_id, "campaign_name": campaign_name, "campaign_id": campaign.id} except Error as e: json_data["response"] = e.details json_data["valid"] = False # passing as we send the json_data pass return HttpResponse(json.dumps(json_data), content_type="application/json")
def json_handler(request): """ Returns json_data {"campaigns": [campaign_list} for given request """ client = Client( settings.SOCIAL_AUTH_TWITTER_KEY, settings.SOCIAL_AUTH_TWITTER_SECRET, settings.TWITTER_ACCESS_TOKEN, settings.TWITTER_ACCESS_TOKEN_SECRET) account_id = request.GET.get("account_id", "") campaign_id = request.GET.get("campaign_id", "") account = client.accounts(account_id) # TODO: Link to Ads API Docs for LineItem.rst line_items = account.line_items(None, campaign_ids=campaign_id) line_item_list = [] for line_item in line_items: name = line_item.name identifier = line_item.id objective = line_item.objective bid_amount = line_item.bid_amount_local_micro # Sometimes Bid Amount is None if bid_amount is not None: bid_amount = bid_amount / 10000 line_item_list.append({"name": name, "id": identifier, "objective": objective, "bid_amount": bid_amount}) return HttpResponse( json.dumps( { "account_id": account_id, "campaign_id": campaign_id, "line_items": line_item_list}), content_type="application/json")
def get(self, request): account_id = request.query_params.get('account_id') keywords = request.query_params.get('keywords') number = request.query_params.get('number', 40) if account_id and keywords and number: account = TwitterAccount.objects_raw.get(pk=account_id) oauth_token = account.tw_twitter_user_id.oauth_token or settings.TW_ACCESS_TOKEN oauth_secret = account.tw_twitter_user_id.oauth_secret or settings.TW_ACCESS_SECRET if not account_id: return Response([]) account_id = long(account_id) if isinstance(account_id, (int, long)): account_id = int_to_base36(account_id) client = Client(settings.TW_CONSUMER_KEY, settings.TW_CONSUMER_SECRET, oauth_token, oauth_secret) if settings.TW_SANDBOX: client.sandbox = settings.TW_SANDBOX api_domain = 'https://ads.twitter.com' resource = '/accounts/%s/keyword_recommendations.json?keywords=%s&number=%s' % \ (account_id, urllib.quote_plus(keywords), number) response = Request(client, 'get', resource, domain=api_domain).perform() return Response(response.body) else: return Response( {'errors': 'account_id, keywords or number is missing.'}, status=status.HTTP_400_BAD_REQUEST)
def new_targeting(request): """ Creates a new """ line_item_id = request.GET.get("line_item_id", "") account_id = request.GET.get("account_id", "") targeting_value = request.GET.get("targeting_value") targeting_type = "BEHAVIOR_EXPANDED" json_data = {} try: client = Client( settings.SOCIAL_AUTH_TWITTER_KEY, settings.SOCIAL_AUTH_TWITTER_SECRET, settings.TWITTER_ACCESS_TOKEN, settings.TWITTER_ACCESS_TOKEN_SECRET) account = client.accounts(account_id) targeting_criteria = TargetingCriteria(account) targeting_criteria.line_item_id = line_item_id targeting_criteria.targeting_type = targeting_type targeting_criteria.targeting_value = targeting_value if targeting_value == "TAILORED_AUDIENCE": targeting_criteria.tailored_audience_type = "FLEXIBLE" targeting_criteria.save() json_data = { "valid": True, "account_id": account_id, "line_item_id": line_item_id, "targeting_value": targeting_value} except Error as e: json_data["response"] = e.details json_data["valid"] = False # passing to push the json_data to the browser pass return HttpResponse(json.dumps(json_data), content_type="application/json")
def new_targeting(request): """ Creates a new """ line_item_id = request.GET.get("line_item_id", "") account_id = request.GET.get("account_id", "") targeting_value = request.GET.get("targeting_value") targeting_type = "BEHAVIOR_EXPANDED" json_data = {} try: client = Client(settings.SOCIAL_AUTH_TWITTER_KEY, settings.SOCIAL_AUTH_TWITTER_SECRET, settings.TWITTER_ACCESS_TOKEN, settings.TWITTER_ACCESS_TOKEN_SECRET) account = client.accounts(account_id) targeting_criteria = TargetingCriteria(account) targeting_criteria.line_item_id = line_item_id targeting_criteria.targeting_type = targeting_type targeting_criteria.targeting_value = targeting_value if targeting_value == "TAILORED_AUDIENCE": targeting_criteria.tailored_audience_type = "FLEXIBLE" targeting_criteria.save() json_data = { "valid": True, "account_id": account_id, "line_item_id": line_item_id, "targeting_value": targeting_value } except Error as e: json_data["response"] = e.details json_data["valid"] = False # passing to push the json_data to the browser pass return HttpResponse(json.dumps(json_data), content_type="application/json")
def fetch_behaviors(self, data, oauth_token=settings.TW_ACCESS_TOKEN, oauth_token_secret=settings.TW_ACCESS_SECRET): res = {} res['data'] = [] res['success'] = False account_id = data.get('account_id') country_code = data.get('country_code', 'US') if isinstance(account_id,(int,long)): account_id = int_to_base36(account_id) if account_id is None: res = { 'success': False, 'message': "Missing Twitter Account ID" } return res client = Client(settings.TW_CONSUMER_KEY, settings.TW_CONSUMER_SECRET, oauth_token, oauth_token_secret) if settings.TW_SANDBOX: client.sandbox = settings.TW_SANDBOX try: resource = '/{api_version}/targeting_criteria/behaviors?count=1000&country_code={country_code}'.format(api_version=settings.TW_API_VERSION, country_code=country_code) response = Request(client, 'get', resource).perform() if response.headers['x-rate-limit-remaining'] == "0" and settings.TW_RATE_LIMIT_ALERT: send_twitter_alert_email({"account_id": account_id, "endpoint": resource}) res['data'] = response.body['data'] next_cursor = response.body.get('next_cursor', False) while next_cursor: resource = '/{api_version}/targeting_criteria/behaviors?count=1000&cursor={next_cursor}&country_code={country_code}'.format(next_cursor=next_cursor, country_code=country_code, api_version=settings.TW_API_VERSION) response = Request(client, 'get', resource).perform() next_cursor = response.body.get('next_cursor', False) res['data'] += response.body['data'] res['success'] = True except Error as e: code = None if e.code: code = e.code elif e.details[0]['code']: code = e.details[0]['code'] res = { 'data': {}, 'success': False, 'message': e.details[0]['message'] if e.details and e.details[0] and e.details[0]['message'] else '', 'errors': { str(code): True } if code else {} } except Exception as e: res = { 'success': False, 'message': str(e) } return res
def get(self, request, oauth_token=settings.TW_ACCESS_TOKEN, oauth_token_secret=settings.TW_ACCESS_SECRET): account_id = request.query_params.get('account_id') if not account_id: return Response([]) client = Client(settings.TW_CONSUMER_KEY, settings.TW_CONSUMER_SECRET, oauth_token, oauth_token_secret) if settings.TW_SANDBOX: client.sandbox = settings.TW_SANDBOX resource = '/{api_version}/accounts/{account_id}/app_lists'.format(api_version=settings.TW_API_VERSION, account_id=account_id) response = Request(client, 'get', resource).perform() json = response.body['data'] return Response(json)
def test_accounts_with_no_id(): responses.add(responses.GET, with_resource('/1/accounts'), body=with_fixture('accounts_all'), content_type='application/json') client = Client(characters(40), characters(40), characters(40), characters(40)) cursor = client.accounts() assert cursor is not None assert isinstance(cursor, Cursor) assert cursor.count == 5
def test_accounts_with_id(): responses.add(responses.GET, with_resource('/1/accounts/2iqph'), body=with_fixture('accounts_load'), content_type='application/json') client = Client(characters(40), characters(40), characters(40), characters(40)) account = client.accounts('2iqph') assert account is not None assert isinstance(account, Account) assert account.id == '2iqph'
def fetch_accounts(self, data, oauth_token=settings.TW_ACCESS_TOKEN, oauth_token_secret=settings.TW_ACCESS_SECRET): res = {} account_id = data.get('account_id') if isinstance(account_id,(int,long)): account_id = int_to_base36(account_id) if account_id is None: res = { 'data': {}, 'success': False, 'message': "Missing Twitter Account ID" } return res client = Client(settings.TW_CONSUMER_KEY, settings.TW_CONSUMER_SECRET, oauth_token, oauth_token_secret) if settings.TW_SANDBOX: client.sandbox = settings.TW_SANDBOX try: account = client.accounts(account_id) resource = '/{api_version}/accounts/{account_id}'.format(api_version=settings.TW_API_VERSION, account_id=account_id) response = Request(client, 'get', resource).perform() if response.headers['x-rate-limit-remaining'] == "0" and settings.TW_RATE_LIMIT_ALERT: send_twitter_alert_email({"account_id": account_id, "endpoint": resource}) res['data'] = response.body['data'] res['success'] = True except Error as e: code = None if e.code: code = e.code elif e.details[0]['code']: code = e.details[0]['code'] res = { 'data': {}, 'success': False, 'message': e.details[0]['message'] if e.details and e.details[0] and e.details[0]['message'] else '', 'errors': { str(code): True } if code else {} } except Exception as e: res = { 'data': {}, 'success': False, 'message': str(e) } return res
def get(self, request): account_id = request.query_params.get('account_id') handles = request.query_params.get('handles') number = request.query_params.get('number', 40) if account_id and handles and number: account = TwitterAccount.objects_raw.get(pk=account_id) oauth_token = account.tw_twitter_user_id.oauth_token or settings.TW_ACCESS_TOKEN oauth_secret = account.tw_twitter_user_id.oauth_secret or settings.TW_ACCESS_SECRET if not account_id: return Response([]) account_id = long(account_id) if isinstance(account_id, (int, long)): account_id = int_to_base36(account_id) client = Client(settings.TW_CONSUMER_KEY, settings.TW_CONSUMER_SECRET, oauth_token, oauth_secret) if settings.TW_SANDBOX: client.sandbox = settings.TW_SANDBOX api_domain = 'https://ads.twitter.com' resource = '/accounts/%s/handle_recommendation.json?handles=%s&number=%s' % ( account_id, handles, number) response = Request(client, 'get', resource, domain=api_domain).perform() if not (int(number) == 2): res = [] api_domain = 'https://api.twitter.com' i = 0 while i < len(response.body): temp = response.body[i:i + 100] i += 100 resource = '/1.1/users/lookup.json?screen_name=%s' % ','.join( temp) resource = resource.replace('@', '') result = Request(client, 'get', resource, domain=api_domain).perform() for r in result.body: r['followers_count_str'] = human_format( r['followers_count']) res = res + result.body return Response(res) return Response(response.body) else: return Response( {'errors': 'account_id, keywords or number is missing.'}, status=status.HTTP_400_BAD_REQUEST)
def test_analytics_sync_stats(): responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph'), body=with_fixture('accounts_load'), content_type='application/json') responses.add(responses.GET, with_resource('/' + API_VERSION + '/stats/accounts/2iqph'), body=with_fixture('analytics_sync_stats'), content_type='application/json') client = Client(characters(40), characters(40), characters(40), characters(40)) account = Account.load(client, '2iqph') ids = ['aaaa', 'bbbb'] metric_groups = [METRIC_GROUP.ENGAGEMENT] stats = Campaign.all_stats(account, ids, metric_groups, granularity=GRANULARITY.TOTAL) assert len(responses.calls) == 2 assert 'granularity=TOTAL' in responses.calls[1].request.url assert stats is not None assert isinstance(stats, list) assert len(stats) == 2 assert stats[0]['id'] == 'aaaa'
def delete(self, request, *args, **kwargs): instance = self.get_object() try: tw_account = instance.tw_account_id account_id = tw_account.pk oauth_token = tw_account.tw_twitter_user_id.oauth_token \ or settings.TW_ACCESS_TOKEN oauth_token_secret = tw_account.tw_twitter_user_id.oauth_secret \ or settings.TW_ACCESS_SECRET _key = 'twitter_tailored_audiences_%s' % account_id client = Client(settings.TW_CONSUMER_KEY, settings.TW_CONSUMER_SECRET, oauth_token, oauth_token_secret) tw_account_id = int_to_base36(int(tw_account.pk)) audience_id = int_to_base36(instance.pk) except Exception as e: return Response(data=dict(msg='invalid tw_account_id', detail=str(e)), status=status.HTTP_400_BAD_REQUEST) try: resource = "/{api_version}/accounts/{account_id}/" \ "tailored_audiences/{audience_id}".format( api_version=settings.TW_API_VERSION, account_id=tw_account_id, audience_id=audience_id) response = Request(client, 'delete', resource).perform() except Error as e: return Response(data=dict(msg=str(e)), status=status.HTTP_400_BAD_REQUEST) instance.delete() redis_cache.delete(_key) return Response(data=dict(status='ok'))
def get_targeting(self, instance): targetings = TwitterTargeting.objects_raw.filter( tw_line_item_id=instance.tw_line_item_id).all().order_by( 'tw_targeting_type') user_ids = [ t.targeting_value for t in TwitterTargeting.objects_raw.filter( tw_line_item_id=instance.tw_line_item_id, tw_targeting_type=9).all() ] event_ids = [ int_to_base36(int(t.tw_targeting_id)) for t in TwitterTargeting.objects_raw.filter( tw_line_item_id=instance.tw_line_item_id, tw_targeting_type=23).all() ] i = 0 api_domain = 'https://api.twitter.com' client = Client(settings.TW_CONSUMER_KEY, settings.TW_CONSUMER_SECRET, settings.TW_ACCESS_TOKEN, settings.TW_ACCESS_SECRET) targeting_json = TwitterTargetingDetailSerializer(targetings, many=True).data try: while i < len(user_ids): temp = user_ids[i:i + 100] i += 100 resource = '/1.1/users/lookup.json?user_id=%s' % ','.join(temp) result = Request(client, 'get', resource, domain=api_domain).perform() for r in result.body: extra = dict(followers_count_str=human_format( r['followers_count']), targeting_value=r['id_str'], name=r['name'], profile_image_url=r['profile_image_url'], screen_name=r['screen_name']) for k, target in enumerate(targeting_json): if str(target['targeting_value']) == str(r['id']): targeting_json[k]['extra'] = extra except Exception as e: print str(e) print 'fetching users failed' try: if len(event_ids) > 0: resource = '/%s/targeting_criteria/events?ids=%s' % ( settings.TW_API_VERSION, ','.join(event_ids)) result = Request(client, 'get', resource).perform() for r in result.body['data']: _id = str(base36_to_int(r['id'])) event_type = r['event_type'] event_type = event_type.replace('MUSIC_AND_', '') event_type = event_type.replace('_', ' ').capitalize() extra = dict(id=_id, name=r['name'], category=event_type) for k, target in enumerate(targeting_json): if str(target['tw_targeting_id']) == _id: targeting_json[k]['extra'] = extra except: print 'fetching events failed' return targeting_json
def get(self, request): account_id = request.query_params.get('account_id') account = TwitterAccount.objects_raw.get(pk=account_id) account_id_base36 = int_to_base36(int(account_id)) oauth_token = account.tw_twitter_user_id.oauth_token oauth_secret = account.tw_twitter_user_id.oauth_secret client = Client(settings.TW_CONSUMER_KEY, settings.TW_CONSUMER_SECRET, oauth_token, oauth_secret) resource = '/{api_version}/accounts/{account_id}/promotable_users'.format( api_version=settings.TW_API_VERSION, account_id=account_id_base36) response = Request(client, 'get', resource).perform() response.body['data'] root_promotable_user_id = '' user_ids = [] for u in response.body['data']: if u['promotable_user_type'] == 'FULL': root_promotable_user_id = int(u['user_id']) user_ids.append(u['user_id']) api = twitter.Api(consumer_key=settings.TW_CONSUMER_KEY, consumer_secret=settings.TW_CONSUMER_SECRET, access_token_key=settings.TW_ACCESS_TOKEN, access_token_secret=settings.TW_ACCESS_SECRET) res = [] promotable_users = api.UsersLookup(user_id=user_ids) for u in promotable_users: _id = u.id if root_promotable_user_id == u.id: _id = '' res.append({'id': _id, 'screen_name': '@%s' % u.screen_name}) return Response({'results': res})
def test_active_entities(): responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph'), body=with_fixture('accounts_load'), content_type='application/json') responses.add(responses.GET, with_resource('/' + API_VERSION + '/stats/accounts/2iqph/active_entities'), body=with_fixture('active_entities'), content_type='application/json') client = Client(characters(40), characters(40), characters(40), characters(40)) account = Account.load(client, '2iqph') end_time = datetime.utcnow().date() start_time = end_time - timedelta(days=1) active_entities = Campaign.active_entities(account, start_time, end_time, campaign_ids=['foo', 'bar']) assert len(responses.calls) == 2 assert 'campaign_ids=foo%2Cbar' in responses.calls[1].request.url assert active_entities is not None assert isinstance(active_entities, list) assert len(active_entities) == 4 assert active_entities[0]['entity_id'] == '2mvb28'
def get(self, request): q = request.query_params.get('q') tw_user_id = request.query_params.get('tw_user_id') tw_user = TwitterUser.objects_raw.get(pk=tw_user_id) client = Client(settings.TW_CONSUMER_KEY, settings.TW_CONSUMER_SECRET, tw_user.oauth_token, tw_user.oauth_secret) accounts = client.accounts() results = [] for a in accounts: tw_account = TwitterAccount.objects_raw.filter( tw_account_id=int(a.id, 36)).first() if not tw_account and (not q or (q and (q in a.name or q in a.id))): results.append(dict(name=a.name, id=a.id)) return Response(dict(results=results))
def test_tweets_get_all(): responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph'), body=with_fixture('accounts_load'), content_type='application/json') responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph/tweets'), body=with_fixture('tweets_get'), content_type='application/json') client = Client( characters(40), characters(40), characters(40), characters(40) ) account = Account.load(client, '2iqph') tweets = Tweets.all( account, tweet_ids=['1166476031668015104'], tweet_type=TWEET_TYPE.PUBLISHED, trim_user=True ) assert tweets is not None assert isinstance(tweets, Cursor) assert tweets.count == 1 assert tweets.first['tweet_id'] == '1166476031668015104'
def main(): parsed_args = singer.utils.parse_args(REQUIRED_CONFIG_KEYS) config = parsed_args.config # Twitter Ads SDK Reference: https://github.com/twitterdev/twitter-python-ads-sdk # Client reference: https://github.com/twitterdev/twitter-python-ads-sdk#rate-limit-handling-and-request-options client = Client( consumer_key=config.get('consumer_key'), consumer_secret=config.get('consumer_secret'), access_token=config.get('access_token'), access_token_secret=config.get('access_token_secret'), options={ 'handle_rate_limit': True, # Handles 429 errors 'retry_max': 10, 'retry_delay': 60000, # milliseconds, wait 1 minute for each retry # Error codes: https://developer.twitter.com/en/docs/basics/response-codes 'retry_on_status': [400, 420, 500, 502, 503, 504], 'retry_on_timeouts': True, 'timeout': (5.0, 10.0) }) # Tuple: (connect, read) timeout in seconds state = {} if parsed_args.state: state = parsed_args.state catalog = parsed_args.catalog reports = config.get('reports', {}) if parsed_args.discover: do_discover(reports) elif parsed_args.catalog: sync(client=client, config=config, catalog=catalog, state=state)
def change(request): """ Returns a change to TA to upload a bucket location. """ client = Client(settings.SOCIAL_AUTH_TWITTER_KEY, settings.SOCIAL_AUTH_TWITTER_SECRET, settings.TWITTER_ACCESS_TOKEN, settings.TWITTER_ACCESS_TOKEN_SECRET) account_id = request.GET.get("account_id", "") identifier = request.GET.get("id", "") input_file_path = request.GET.get("input_file_path", "") # Update With location resource = '/0/accounts/' + account_id + '/tailored_audience_changes' params = { 'tailored_audience_id': identifier, 'input_file_path': base64.b64decode(input_file_path), 'operation': "ADD" } json_data = {} try: request = Request(client, 'post', resource, params=params).perform() json_data["account_id"] = account_id json_data["data"] = request.body["data"] except Error as e: json_data["error"] = e.details return HttpResponse(json.dumps(json_data), content_type="application/json")
def new(request): """ Returns a new TA path to hold the bucket location. """ client = Client(settings.SOCIAL_AUTH_TWITTER_KEY, settings.SOCIAL_AUTH_TWITTER_SECRET, settings.TWITTER_ACCESS_TOKEN, settings.TWITTER_ACCESS_TOKEN_SECRET) account_id = request.GET.get("account_id", "") name = request.GET.get("name", "") resource = '/0/accounts/' + account_id + '/tailored_audiences' params = {'name': name, 'list_type': 'HANDLE'} json_data = {} try: request = Request(client, 'post', resource, params=params).perform() # return audience.id to use ta_id = request.body['data']['id'] json_data = { "valid": True, "account_id": account_id, "name": name, "id": str(ta_id) } except Error as e: json_data["response"] = e.details json_data["valid"] = False return HttpResponse(json.dumps(json_data), content_type="application/json")
def test_tweet_previews_load(): responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph'), body=with_fixture('accounts_load'), content_type='application/json') responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph/tweet_previews'), body=with_fixture('tweet_previews'), content_type='application/json') client = Client(characters(40), characters(40), characters(40), characters(40)) account = Account.load(client, '2iqph') tweets = TweetPreview.load( account, tweet_ids=['1130942781109596160', '1101254234031370240'], tweet_type=TWEET_TYPE.PUBLISHED) assert tweets is not None assert isinstance(tweets, Cursor) assert tweets.count == 2 tweet = tweets.next() assert tweet.tweet_id == '1130942781109596160' assert '<iframe' in tweet.preview
def main(): parsed_args = singer.utils.parse_args(REQUIRED_CONFIG_KEYS) config = parsed_args.config # Twitter Ads SDK Reference: https://github.com/twitterdev/twitter-python-ads-sdk client = Client(consumer_key=config.get('consumer_key'), consumer_secret=config.get('consumer_secret'), access_token=config.get('access_token'), access_token_secret=config.get('access_token_secret'), options={ 'handle_rate_limit': True, 'retry_max': 3, 'retry_delay': 5000, 'retry_on_status': [404, 500, 503], 'retry_on_timeouts': True, 'timeout': (1.0, 3.0) }) state = {} if parsed_args.state: state = parsed_args.state catalog = parsed_args.catalog reports = config.get('reports', {}) if parsed_args.discover: do_discover(reports) elif parsed_args.catalog: sync(client=client, config=config, catalog=catalog, state=state)
def main(): parsed_args = singer.utils.parse_args(REQUIRED_CONFIG_KEYS) config = parsed_args.config # Twitter Ads SDK Reference: https://github.com/twitterdev/twitter-python-ads-sdk client = Client( consumer_key=config.get("consumer_key"), consumer_secret=config.get("consumer_secret"), access_token=config.get("access_token"), access_token_secret=config.get("access_token_secret"), options={ "handle_rate_limit": True, "retry_max": 3, "retry_delay": 5000, "retry_on_status": [404, 500, 503], "retry_on_timeouts": True, "timeout": (1.0, 3.0), }, ) state = {} if parsed_args.state: state = parsed_args.state sync(client=client, config=config, state=state)
def test_campaigns_all(): responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph'), body=with_fixture('accounts_load'), content_type='application/json') responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph/campaigns'), body=with_fixture('campaigns_all'), content_type='application/json') client = Client(characters(40), characters(40), characters(40), characters(40)) account = Account.load(client, '2iqph') cursor = account.campaigns() assert cursor is not None assert isinstance(cursor, Cursor) assert cursor.count == 10 campaign = cursor.next() assert campaign.id == '2wap7' assert campaign.entity_status == 'ACTIVE'
def test_line_items_all(): responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph'), body=with_fixture('accounts_load'), content_type='application/json') responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph/line_items'), body=with_fixture('line_items_all'), content_type='application/json') client = Client( characters(40), characters(40), characters(40), characters(40) ) account = Account.load(client, '2iqph') cursor = account.line_items() assert cursor is not None assert isinstance(cursor, Cursor) assert cursor.count == 10 lineitem = cursor.next() assert lineitem.id == 'bw2' assert lineitem.entity_status == 'ACTIVE'
def test_targeted_audiences(): responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph'), body=with_fixture('accounts_load')) responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph/custom_audiences/2906h'), body=with_fixture('custom_audiences_load')) responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph/custom_audiences/abc2/targeted?with_active=True'), body=with_fixture('targeted_audiences')) client = Client( characters(40), characters(40), characters(40), characters(40) ) account = Account.load(client, '2iqph') audience = CustomAudience.load(account, '2906h') targeted_audiences = audience.targeted( with_active=True ) assert isinstance(targeted_audiences, Cursor) assert isinstance(targeted_audiences.first.line_items, list) assert targeted_audiences.first.campaign_id == '59hod' assert targeted_audiences.first.line_items[0]['id'] == '5gzog' assert targeted_audiences.first.line_items[0]['name'] == 'test-line-item' assert targeted_audiences.first.line_items[0]['servable'] == True assert len(responses.calls) == 3
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'
def test_rate_limit_cursor_class_access(): responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph'), body=with_fixture('accounts_load'), content_type='application/json') responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph/campaigns'), body=with_fixture('campaigns_all'), content_type='application/json', headers={ 'x-account-rate-limit-limit': '10000', 'x-account-rate-limit-remaining': '9999', 'x-account-rate-limit-reset': '1546300800' }) client = Client(characters(40), characters(40), characters(40), characters(40)) account = Account.load(client, '2iqph') cursor = Campaign.all(account) assert cursor is not None assert isinstance(cursor, Cursor) assert cursor.account_rate_limit_limit == '10000' assert cursor.account_rate_limit_remaining == '9999' assert cursor.account_rate_limit_reset == '1546300800'
def test_promoted_tweets_all(): responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph'), body=with_fixture('accounts_load'), content_type='application/json') responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph/promoted_tweets'), body=with_fixture('promoted_tweets_all'), content_type='application/json') client = Client( characters(40), characters(40), characters(40), characters(40) ) account = Account.load(client, '2iqph') cursor = PromotedTweet.all(account) assert cursor is not None assert isinstance(cursor, Cursor) assert cursor.count == 20 promoted_tweet = cursor.next() assert promoted_tweet.id == '6thl4' assert promoted_tweet.entity_status == 'ACTIVE'
def test_accounts_with_id(): responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph'), body=with_fixture('accounts_load'), content_type='application/json') client = Client( characters(40), characters(40), characters(40), characters(40) ) account = client.accounts('2iqph') assert account is not None assert isinstance(account, Account) assert account.id == '2iqph'
def test_accounts_with_no_id(): responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts'), body=with_fixture('accounts_all'), content_type='application/json') client = Client( characters(40), characters(40), characters(40), characters(40) ) cursor = client.accounts() assert cursor is not None assert isinstance(cursor, Cursor) assert cursor.count == 5
def __init__( self, consumer_key, consumer_secret, access_token, access_token_secret, account_id, report_type, entity, entity_attribute, granularity, metric_group, placement, segmentation_type, platform, country, start_date, end_date, add_request_date_to_report, date_range, ): # Authentication inputs self.client = Client(consumer_key, consumer_secret, access_token, access_token_secret) self.account = self.client.accounts(account_id) # General inputs self.report_type = report_type self.entity = entity self.start_date, self.end_date = build_date_range( start_date, end_date, date_range) self.end_date = self.end_date + timedelta(days=1) self.add_request_date_to_report = add_request_date_to_report # Report inputs: ENTITY self.entity_attributes = list(entity_attribute) # Report inputs: ANALYTICS self.granularity = granularity self.metric_groups = list(metric_group) self.placement = placement self.segmentation_type = segmentation_type self.platform = platform self.country = country # Validate inputs self.validate_inputs()
def json_handler(request): """ Returns json_data {"accounts": [account_list]} for given request """ client = Client( settings.SOCIAL_AUTH_TWITTER_KEY, settings.SOCIAL_AUTH_TWITTER_SECRET, settings.TWITTER_ACCESS_TOKEN, settings.TWITTER_ACCESS_TOKEN_SECRET) accounts = client.accounts() # TODO: Link to Ads API Docs for Account.request account_list = [] for account in accounts: name = account.name identifier = account.id account_list.append({"name": name, "id": identifier}) return HttpResponse(json.dumps( {"accounts": account_list}), content_type="application/json")
def json_handler(request): """ Returns json_data {"campaigns": [campaign_list} for given request """ client = Client( settings.SOCIAL_AUTH_TWITTER_KEY, settings.SOCIAL_AUTH_TWITTER_SECRET, settings.TWITTER_ACCESS_TOKEN, settings.TWITTER_ACCESS_TOKEN_SECRET) account_id = request.GET.get("account_id", "") account = client.accounts(account_id) # TODO: Link to Ads API Docs for Campaign.rst campaigns = account.campaigns() campaign_list = [] for campaign in campaigns: name = campaign.name identifier = campaign.id campaign_list.append({"name": name, "id": identifier}) return HttpResponse(json.dumps( {"account_id": account_id, "campaigns": campaign_list}), content_type="application/json")
def new(request): """ Returns a new line item """ client = Client( settings.SOCIAL_AUTH_TWITTER_KEY, settings.SOCIAL_AUTH_TWITTER_SECRET, settings.TWITTER_ACCESS_TOKEN, settings.TWITTER_ACCESS_TOKEN_SECRET) account_id = request.GET.get("account_id", "") campaign_id = request.GET.get("campaign_id", "") campaign_name = request.GET.get("name", "") budget = request.GET.get("budget", "") account_id = request.GET.get("account_id", "") name = request.GET.get("name", "") bid_amount = request.GET.get("bid_amount", "") json_data = {} try: account = client.accounts(account_id) # create your campaign line_item = LineItem(account) line_item.campaign_id = campaign_id line_item.name = name line_item.product_type = PRODUCT.PROMOTED_TWEETS line_item.placements = [PLACEMENT.ALL_ON_TWITTER] line_item.objective = OBJECTIVE.TWEET_ENGAGEMENTS line_item.bid_amount_local_micro = int(bid_amount) * 1000 line_item.paused = True line_item.save() json_data = { "account_id": account_id, "campaign_name": campaign_name, "campaign_id": campaign_id} except Error as e: json_data["response"] = e.details json_data["valid"] = False pass return HttpResponse(json.dumps(json_data), content_type="application/json")
# Copyright (C) 2015 Twitter, Inc. from twitter_ads.client import Client from twitter_ads.campaign import Tweet from twitter_ads.creative import PromotedTweet, WebsiteCard CONSUMER_KEY = 'your consumer key' CONSUMER_SECRET = 'your consumer secret' ACCESS_TOKEN = 'user access token' ACCESS_TOKEN_SECRET = 'user access token secret' ADS_ACCOUNT = '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) 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()
from twitter_ads.client import Client from twitter_ads.creative import CardsFetch from twitter_ads.http import Request CONSUMER_KEY = '' CONSUMER_SECRET = '' ACCESS_TOKEN = '' ACCESS_TOKEN_SECRET = '' ACCOUNT_ID = '' # initialize the client client = Client(CONSUMER_KEY, CONSUMER_SECRET, ACCESS_TOKEN, ACCESS_TOKEN_SECRET) # load the advertiser account instance account = client.accounts(ACCOUNT_ID) # retrieve a Tweet tweet_id = '973002610033610753' # use one of your own Tweets resource = '/1.1/statuses/show/{id}.json'.format(id=tweet_id) domain = 'https://api.twitter.com' params = {'include_card_uri' : 'true'} response = Request(client, 'get', resource, domain=domain, params=params).perform() card_uri = response.body['card_uri'] # Tweet must include a card_uri card # fetch by card_uri cf = CardsFetch(account) card = cf.load(account, card_uri=card_uri) card.card_type # 'VIDEO_POLLS' card.id # '5g83p'
from twitter_ads.client import Client from twitter_ads.account import Account from twitter_ads.campaign import Campaign CONSUMER_KEY = "your consumer key" CONSUMER_SECRET = "your consumer secret" ACCESS_TOKEN = "access token" ACCESS_TOKEN_SECRET = "access token secret" ACCOUNT_ID = "account id" # initialize the client client = Client(CONSUMER_KEY, CONSUMER_SECRET, ACCESS_TOKEN, ACCESS_TOKEN_SECRET) # load the advertiser account instance account = client.accounts(id=ACCOUNT_ID) # load and update a specific campaign campaign = account.campaigns().next() campaign.name = "updated campaign name" campaign.paused = True campaign.save() # iterate through campaigns for campaign in account.campaigns(): print(campaign.id)