def load(klass, account, params): resource = klass.RESOURCE.format(account_id=account.id) headers = {'Content-Type': 'application/json'} response = Request(account.client, 'post', resource, headers=headers, body=json.dumps(params)).perform() return klass(account).from_response(response.body['data'])
def opt_out(klass, account, file_path, list_type): """ Updates the global opt-out list for the specified advertiser account. """ upload = TONUpload(account.client, file_path) params = {'input_file_path': upload.perform(), 'list_type': list_type} resource = klass.OPT_OUT.format(account_id=account.id) Request(account.client, 'put', resource, params=params).perform() return True
def all(klass, account, line_item_id, **kwargs): """Returns a Cursor instance for a given resource.""" params = {'line_item_id': line_item_id} params.update(kwargs) resource = klass.RESOURCE_COLLECTION.format(account_id=account.id) request = Request(account.client, 'get', resource, params=params) return Cursor(klass, request, init_with=[account])
def create(self, name, *ids): if isinstance(ids, list): ids = ','.join(map(str, ids)) resource = self.RESOURCE_COLLECTION.format(account_id=self.account.id) params = self.to_params.update({'app_store_identifiers': ids, 'name': name}) response = Request(self.account.client, 'post', resource, params=params).perform() return self.from_response(response.body['data'])
def save(self): """ Update the current object instance. """ resource = self.RESOURCE.format(account_id=self.account.id) response = Request( self.account.client, 'put', resource, params=self.to_params()).perform() return self.from_response(response.body['data'])
def all(klass, account, tailored_audience_id, **kwargs): """Returns a Cursor instance for the given tailored audience permission resource.""" resource = klass.RESOURCE_COLLECTION.format( account_id=account.id, tailored_audience_id=tailored_audience_id) request = Request(account.client, 'get', resource, params=kwargs) return Cursor(klass, request, init_with=[account])
def load(klass, account, **kwargs): # check whether both are specified or neither are specified if all([kwargs.get('card_uris'), kwargs.get('card_id')]) or \ not any([kwargs.get('card_uris'), kwargs.get('card_id')]): raise ValueError( 'card_uris and card_id are exclusive parameters. ' + 'Please supply one or the other, but not both.') if kwargs.get('card_uris'): resource = klass.FETCH_URI.format(account_id=account.id) request = Request(account.client, 'get', resource, params=kwargs) return Cursor(klass, request, init_with=[account]) else: resource = klass.FETCH_ID.format(account_id=account.id, id=kwargs.get('card_id')) response = Request(account.client, 'get', resource, params=kwargs).perform() return klass(account).from_response(response.body['data'])
def preview(self): """ Returns an HTML preview for a Scheduled Tweet. """ if self.id: resource = self.PREVIEW resource = resource.format(account_id=self.account.id, id=self.id) response = Request(self.account.client, 'get', resource).perform() return response.body['data']
def save(self): """ Saves or updates the current object instance depending on the presence of `object.id`. """ params = self.to_params() if 'tweet_id' in params: params['tweet_ids'] = [params['tweet_id']] del params['tweet_id'] if self.id: resource = self.RESOURCE.format(account_id=self.account.id, id=self.id) response = Request(self.account.client, 'put', resource, params=params).perform() return self.from_response(response.body['data']) resource = self.RESOURCE_COLLECTION.format(account_id=self.account.id) response = Request(self.account.client, 'post', resource, params=params).perform() return self.from_response(response.body['data'][0])
def all(klass, account, custom_audience_id, **kwargs): """Returns a Cursor instance for the given targeted custom audience resource.""" resource = klass.RESOURCE.format( account_id=account.id, custom_audience_id=custom_audience_id) request = Request(account.client, 'get', resource, params=kwargs) return Cursor(klass, request, init_with=[account])
def update(self): resource = self.RESOURCE.format(account_id=self.account.id, id=self.media_key) response = Request(self.account.client, 'put', resource, params=self.to_params()).perform() return self.from_response(response.body['data'])
def all_stats(klass, account, ids, metric_groups, **kwargs): """ Pulls a list of metrics for a specified set of object IDs. """ params = klass._standard_params(ids, metric_groups, **kwargs) resource = klass.RESOURCE_SYNC.format(account_id=account.id) response = Request(account.client, 'get', resource, params=params).perform() return response.body['data']
def create(klass, account, status, **kwargs): """ Creates a "Promoted-Only" Tweet using the specialized Ads API end point. """ params = {'status': status} params.update(kwargs) resource = klass.TWEET_CREATE.format(account_id=account.id) response = Request(account.client, 'post', resource, params=params).perform() return response.body['data']
def reload(self, **kwargs): if not self.media_key: return self resource = self.RESOURCE.format(account_id=self.account.id, id=self.media_key) response = Request(self.account.client, 'get', resource, params=kwargs).perform() return self.from_response(response.body['data'])
def __update_audience__(self, location, list_type, operation): params = { 'tailored_audience_id': self.id, 'input_file_path': location, 'list_type': list_type, 'operation': operation } resource = self.RESOURCE_UPDATE.format(account_id=self.account.id) return Request(self.account.client, 'post', resource, params=params).perform()
def get_resource(stream_name, client, path, params=None): resource = '/{}/{}'.format(API_VERSION, path) try: request = Request(client, 'get', resource, params=params) #, stream=True) except Error as err: # see twitter_ads.error for more details LOGGER.error('Stream: {} - ERROR: {}'.format(stream_name, err.details)) raise err cursor = Cursor(None, request) return cursor
def features(self): """ Returns a collection of features available to the current account. """ self._validate_loaded() resource = self.FEATURES.format(id=self.id) response = Request(self.client, 'get', resource).perform() return response.body['data']
def post_resource(report_name, client, path, params=None, body=None): resource = '/{}/{}'.format(API_VERSION, path) try: response = Request(client, 'post', resource, params=params, body=body).perform() except Error as err: # see twitter_ads.error for more details LOGGER.error('Report: {} - ERROR: {}'.format(report_name, err.details)) raise err response_body = response.body # Dictionary response of POST request return response_body
def delete(self): """ Deletes the current tailored audience permission. """ resource = self.RESOURCE.format( account_id=self.account.id, tailored_audience_id=self.tailored_audience_id, id=self.id) response = Request(self.account.client, 'delete', resource).perform() return self.from_response(response.body['data'])
def get(self, request): account_id = request.query_params.get('account_id') next_cursor = request.query_params.get('next_cursor') objective = request.query_params.get('objective', 'APP_INSTALLS') promotable_user_id = request.query_params.get('promotable_user_id') if objective == 'APP_INSTALLS': objective = 1 elif objective == 'WEBSITE_CLICKS': objective = 5 else: objective = 0 if not account_id: return Response([]) 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) api_domain = 'https://ads.twitter.com' if next_cursor: next_cursor = '&cursor=%s' % next_cursor else: next_cursor = '' resource = '/accounts/{account_id}/tweets/dashboard/tweet_rows?' \ 'manage_campaigns=true&objective={objective}&account={account_id}' \ '&lang=en&promotable_user={promotable_user}{next_cursor}' \ .format( account_id=account_id_base36, next_cursor=next_cursor, objective=objective, promotable_user=promotable_user_id ) response = Request(client, 'get', resource, domain=api_domain).perform() results = [] html = response.body['tweetRows'] soup = BeautifulSoup(html, 'html.parser') checkboxes = soup.find_all("input", {"class": "tweet-checkbox"}) tweets = soup.find_all("div", {"class": "Tweet--timeline"}) for i in range(len(tweets)): result = { 'preview': tweets[i].prettify(), 'tweet_id': str(checkboxes[i]['value']) } results.append(result) return Response( dict(results=results, next_cursor=response.body.get('cursor')))
def async_stats_job_result(klass, account, job_id, **kwargs): """ Returns the results of the specified async job IDs """ params = {'job_ids': job_id} resource = klass.RESOURCE_ASYNC.format(account_id=account.id) response = Request(account.client, 'get', resource, params=params).perform() return response.body['data'][0]
def async_stats_job_data(klass, account, url, **kwargs): """ Returns the results of the specified async job IDs """ resource = urlparse(url) domain = '{0}://{1}'.format(resource.scheme, resource.netloc) response = Request(account.client, 'get', resource.path, domain=domain, raw_body=True, stream=True).perform() return response.body
def reload(self, **kwargs): """ Reloads all attributes for the current object instance from the API. """ if not self.id: return self resource = self.RESOURCE.format(account_id=self.account.id, id=self.id) response = Request(self.account.client, 'get', resource, params=kwargs).perform() return self.from_response(response.body['data'])
def create(klass, account, name, components): method = 'post' resource = klass.RESOURCE_COLLECTION.format(account_id=account.id) headers = {'Content-Type': 'application/json'} payload = {'name': name, 'components': components} response = Request(account.client, method, resource, headers=headers, body=json.dumps(payload)).perform() return klass(account).from_response(response.body['data'])
def __get(klass, account, client, params): """ Helper function to get the conversation data Returns a Cursor instance """ resource = klass.RESOURCE_CONVERSATIONS.format(account_id=account.id) request = Request( account.client, klass.METHOD, resource, headers=klass.HEADERS, body=params) return Cursor(klass, request, init_with=[account])
def load(klass, account, card_uris=None, card_id=None, with_deleted=None): # check whether both are specified or neither are specified if all([card_uris, card_id]) or not any([card_uris, card_id]): raise ValueError( 'card_uris and card_id are exclusive parameters. ' + 'Please supply one or the other, but not both.') params = {} if with_deleted: params['with_deleted'] = 'true' if card_uris: params['card_uris'] = ','.join(card_uris) resource = klass.FETCH_URI.format(account_id=account.id) request = Request(account.client, 'get', resource, params=params) return Cursor(klass, request, init_with=[account]) else: params['card_id'] = card_id resource = klass.FETCH_ID.format(account_id=account.id, id=card_id) response = Request(account.client, 'get', resource, params=params).perform() return klass(account).from_response(response.body['data'])
def get_async_data(report_name, client, url): resource = urlparse(url) domain = '{0}://{1}'.format(resource.scheme, resource.netloc) try: response = Request( client, 'get', resource.path, domain=domain, raw_body=True, stream=True).perform() response_body = response.body except Error as err: # see twitter_ads.error for more details LOGGER.error('Report: {} - ERROR: {}'.format(report_name, err.details)) raise err return response_body
def get_published_tweets(self): """ Step 1 of 'ENTITY - CARD' report generation process: Returns details on 'PUBLISHED' tweets, as a generator of dictionaries Documentation: https://developer.twitter.com/en/docs/ads/creatives/api-reference/tweets """ resource = f"/{API_VERSION}/accounts/{self.account.id}/tweets" params = {"tweet_type": "PUBLISHED"} request = Request(self.client, "get", resource, params=params) yield from Cursor(None, request)
def status(self): """ Returns the status of all changes for the current tailored audience instance. """ if not self.id: return None resource = self.RESOURCE_UPDATE.format(account_id=self.account.id) request = Request(self.account.client, 'get', resource, params=self.to_params()) cursor = list(Cursor(None, request)) return filter(lambda change: change['tailored_audience_id'] == self.id, cursor)
def save(self): if self.media_key: method = 'put' resource = self.RESOURCE.format(account_id=self.account.id, id=self.media_key) else: method = 'post' resource = self.RESOURCE_COLLECTION.format(account_id=self.account.id) response = Request( self.account.client, method, resource, params=self.to_params()).perform() return self.from_response(response.body['data'])