diff --git a/facebookads/exceptions.py b/facebookads/exceptions.py index 5489a12c..709d5465 100644 --- a/facebookads/exceptions.py +++ b/facebookads/exceptions.py @@ -88,9 +88,9 @@ def __init__( super(FacebookRequestError, self).__init__( "\n\n" + " Message: %s\n" % self._message + - " Method: %s\n" % request['method'] + - " Path: %s\n" % request['path'] + - " Params: %s\n" % request['params'] + + " Method: %s\n" % request.get('method') + + " Path: %s\n" % request.get('path', '/') + + " Params: %s\n" % request.get('params') + "\n" + " Status: %s\n" % self._http_status + " Response:\n %s" % re.sub( diff --git a/facebookads/objects.py b/facebookads/objects.py index f1d58ca7..517454a2 100644 --- a/facebookads/objects.py +++ b/facebookads/objects.py @@ -1928,7 +1928,7 @@ def get_endpoint(cls): return 'customaudiences' @classmethod - def format_params(cls, schema, users, app_ids=None): + def format_params(cls, schema, users, app_ids=None, pre_hashed=None): hashed_users = [] if schema in (cls.Schema.phone_hash, cls.Schema.email_hash): for user in users: @@ -1936,7 +1936,10 @@ def format_params(cls, schema, users, app_ids=None): user = user.strip(" \t\r\n\0\x0B.").lower() if isinstance(user, six.text_type): user = user.encode('utf8') # required for hashlib - hashed_users.append(hashlib.sha256(user).hexdigest()) + if pre_hashed: + hashed_users.append(user) + else: + hashed_users.append(hashlib.sha256(user).hexdigest()) payload = { 'schema': schema, @@ -1955,7 +1958,7 @@ def format_params(cls, schema, users, app_ids=None): 'payload': payload, } - def add_users(self, schema, users, app_ids=None): + def add_users(self, schema, users, app_ids=None, pre_hashed=None): """Adds users to this CustomAudience. Args: @@ -1969,10 +1972,13 @@ def add_users(self, schema, users, app_ids=None): return self.get_api_assured().call( 'POST', (self.get_id_assured(), 'users'), - params=CustomAudience.format_params(schema, users, app_ids), + params=CustomAudience.format_params(schema, + users, + app_ids, + pre_hashed), ) - def remove_users(self, schema, users, app_ids=None): + def remove_users(self, schema, users, app_ids=None, pre_hashed=None): """Deletes users from this CustomAudience. Args: @@ -1986,7 +1992,10 @@ def remove_users(self, schema, users, app_ids=None): return self.get_api_assured().call( 'DELETE', (self.get_id_assured(), 'users'), - params=CustomAudience.format_params(schema, users, app_ids), + params=CustomAudience.format_params(schema, + users, + app_ids, + pre_hashed), ) def share_audience(self, account_ids): diff --git a/facebookads/test/integration.py b/facebookads/test/integration.py index 760613a5..d28f7c9c 100644 --- a/facebookads/test/integration.py +++ b/facebookads/test/integration.py @@ -118,11 +118,12 @@ def new_test_ad_set(self, campaign): objects.AdSet.Field.pacing_type: [ objects.AdSet.PacingType.standard, ], - objects.AdSet.Field.daily_budget: 100, - objects.AdSet.Field.bid_type: objects.AdSet.BidType.cpc, - objects.AdSet.Field.bid_info: { - objects.AdSet.Field.BidInfo.clicks: 20, - }, + objects.AdSet.Field.daily_budget: 2500, + objects.AdSet.Field.optimization_goal: + objects.AdSet.OptimizationGoal.impressions, + objects.AdSet.Field.billing_event: + objects.AdSet.BillingEvent.impressions, + objects.AdSet.Field.bid_amount: 500, objects.AdSet.Field.targeting: { objects.TargetingSpecsField.geo_locations: { 'countries': [ @@ -354,7 +355,6 @@ def setUp(self): objects.AdAccount.Field.account_status, objects.AdAccount.Field.business_name, objects.AdAccount.Field.timezone_name, - objects.AdAccount.Field.daily_spend_limit, ]) def tearDown(self): @@ -460,7 +460,6 @@ def setUp(self): objects.AdSet.Field.daily_budget, objects.AdSet.Field.created_time, objects.AdSet.Field.campaign_group_id, - objects.AdSet.Field.bid_type, objects.AdSet.Field.name, ]) diff --git a/facebookads/test/test.png b/facebookads/test/test.png new file mode 100755 index 00000000..9cd772cd Binary files /dev/null and b/facebookads/test/test.png differ diff --git a/facebookads/test/unit.py b/facebookads/test/unit.py index 281e2797..1b4a34d9 100644 --- a/facebookads/test/unit.py +++ b/facebookads/test/unit.py @@ -66,6 +66,19 @@ def uid_payload(): uid_payload, ) + def test_format_params_pre_hashed(self): + # This is the value of "test" when it's hashed with sha256 + test_hash = \ + "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08" + payload = objects.CustomAudience.format_params( + objects.CustomAudience.Schema.email_hash, + ["9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08"], + pre_hashed=True + ) + + users = payload['payload']['data'] + assert users[0] == test_hash + class EdgeIteratorTestCase(unittest.TestCase):