facebookbusiness 0.7.0.1 → 0.8.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/facebook_ads/ad_objects/ad_account.rb +16 -19
- data/lib/facebook_ads/ad_objects/ad_account_ad_volume.rb +23 -0
- data/lib/facebook_ads/ad_objects/ad_account_delivery_estimate.rb +1 -0
- data/lib/facebook_ads/ad_objects/ad_account_matched_search_applications_edge_data.rb +1 -0
- data/lib/facebook_ads/ad_objects/ad_account_targeting_unified.rb +1 -0
- data/lib/facebook_ads/ad_objects/ad_activity.rb +7 -0
- data/lib/facebook_ads/ad_objects/ad_asset_feed_spec.rb +2 -0
- data/lib/facebook_ads/ad_objects/ad_campaign_activity.rb +2 -2
- data/lib/facebook_ads/ad_objects/ad_campaign_delivery_estimate.rb +1 -0
- data/lib/facebook_ads/ad_objects/ad_creative.rb +1 -0
- data/lib/facebook_ads/ad_objects/{atlas_url.rb → ad_creative_instagram_branded_content.rb} +1 -2
- data/lib/facebook_ads/ad_objects/ad_creative_interactive_components_spec.rb +1 -0
- data/lib/facebook_ads/ad_objects/ad_creative_link_data_call_to_action.rb +1 -0
- data/lib/facebook_ads/ad_objects/ad_network_analytics_sync_query_result.rb +1 -0
- data/lib/facebook_ads/ad_objects/ad_place_page_set.rb +6 -0
- data/lib/facebook_ads/ad_objects/ad_preview.rb +0 -1
- data/lib/facebook_ads/ad_objects/ad_report_spec.rb +0 -1
- data/lib/facebook_ads/ad_objects/ad_set.rb +2 -0
- data/lib/facebook_ads/ad_objects/ad_study.rb +2 -0
- data/lib/facebook_ads/ad_objects/ad_video.rb +12 -27
- data/lib/facebook_ads/ad_objects/adgroup_placement_specific_review_feedback.rb +4 -0
- data/lib/facebook_ads/ad_objects/{ads_interest.rb → adoptable_pet.rb} +19 -5
- data/lib/facebook_ads/ad_objects/ads_insights.rb +4 -0
- data/lib/facebook_ads/ad_objects/ads_pixel.rb +3 -0
- data/lib/facebook_ads/ad_objects/application.rb +26 -0
- data/lib/facebook_ads/ad_objects/atlas_campaign.rb +3 -3
- data/lib/facebook_ads/ad_objects/automotive_model.rb +1 -0
- data/lib/facebook_ads/ad_objects/business.rb +46 -117
- data/lib/facebook_ads/ad_objects/business_asset_group.rb +2 -3
- data/lib/facebook_ads/ad_objects/business_role_request.rb +9 -0
- data/lib/facebook_ads/ad_objects/business_unit.rb +1 -1
- data/lib/facebook_ads/ad_objects/business_user.rb +9 -0
- data/lib/facebook_ads/ad_objects/campaign.rb +257 -0
- data/lib/facebook_ads/ad_objects/catalog_sub_vertical_list.rb +88 -0
- data/lib/facebook_ads/ad_objects/commerce_merchant_settings.rb +27 -0
- data/lib/facebook_ads/ad_objects/commerce_order.rb +6 -0
- data/lib/facebook_ads/ad_objects/commerce_order_transaction_detail.rb +4 -0
- data/lib/facebook_ads/ad_objects/{creative_asset_tag.rb → connections_targeting.rb} +2 -2
- data/lib/facebook_ads/ad_objects/{business_creative_folder_sharing_agreement.rb → cpas_advertiser_partnership_recommendation.rb} +8 -11
- data/lib/facebook_ads/ad_objects/{brand_audience.rb → cpas_collaboration_request.rb} +15 -9
- data/lib/facebook_ads/ad_objects/custom_audience_data_source.rb +1 -0
- data/lib/facebook_ads/ad_objects/da_check.rb +7 -0
- data/lib/facebook_ads/ad_objects/destination.rb +1 -0
- data/lib/facebook_ads/ad_objects/event.rb +12 -1
- data/lib/facebook_ads/ad_objects/extended_credit.rb +7 -0
- data/lib/facebook_ads/ad_objects/external_event_source.rb +1 -0
- data/lib/facebook_ads/ad_objects/flight.rb +1 -0
- data/lib/facebook_ads/ad_objects/group.rb +10 -1
- data/lib/facebook_ads/ad_objects/home_listing.rb +1 -0
- data/lib/facebook_ads/ad_objects/hotel.rb +1 -0
- data/lib/facebook_ads/ad_objects/ig_media.rb +1 -0
- data/lib/facebook_ads/ad_objects/life_event.rb +0 -4
- data/lib/facebook_ads/ad_objects/link.rb +0 -6
- data/lib/facebook_ads/ad_objects/live_video.rb +12 -16
- data/lib/facebook_ads/ad_objects/media_fingerprint.rb +0 -1
- data/lib/facebook_ads/ad_objects/native_offer_view.rb +0 -1
- data/lib/facebook_ads/ad_objects/oracle_transaction.rb +0 -7
- data/lib/facebook_ads/ad_objects/page.rb +34 -65
- data/lib/facebook_ads/ad_objects/page_admin_note.rb +1 -0
- data/lib/facebook_ads/ad_objects/page_call_to_action.rb +3 -0
- data/lib/facebook_ads/ad_objects/page_change_proposal.rb +2 -0
- data/lib/facebook_ads/ad_objects/page_post.rb +2 -0
- data/lib/facebook_ads/ad_objects/{business_creative.rb → payment_subscription.rb} +24 -16
- data/lib/facebook_ads/ad_objects/photo.rb +6 -0
- data/lib/facebook_ads/ad_objects/post.rb +4 -2
- data/lib/facebook_ads/ad_objects/product_catalog.rb +42 -0
- data/lib/facebook_ads/ad_objects/product_feed.rb +31 -0
- data/lib/facebook_ads/ad_objects/product_group.rb +1 -0
- data/lib/facebook_ads/ad_objects/product_item.rb +2 -0
- data/lib/facebook_ads/ad_objects/product_set.rb +4 -0
- data/lib/facebook_ads/ad_objects/{client_transparency_status.rb → product_set_metadata.rb} +5 -5
- data/lib/facebook_ads/ad_objects/profile.rb +1 -0
- data/lib/facebook_ads/ad_objects/profile_picture_source.rb +4 -0
- data/lib/facebook_ads/ad_objects/publisher_block_list.rb +6 -0
- data/lib/facebook_ads/ad_objects/saved_audience.rb +1 -0
- data/lib/facebook_ads/ad_objects/security_settings.rb +0 -1
- data/lib/facebook_ads/ad_objects/server_side/batch_processor.rb +73 -0
- data/lib/facebook_ads/ad_objects/server_side/content.rb +75 -13
- data/lib/facebook_ads/ad_objects/server_side/custom_data.rb +45 -6
- data/lib/facebook_ads/ad_objects/server_side/delivery_category.rb +33 -0
- data/lib/facebook_ads/ad_objects/server_side/event.rb +62 -3
- data/lib/facebook_ads/ad_objects/server_side/event_request.rb +134 -13
- data/lib/facebook_ads/ad_objects/server_side/event_request_async.rb +43 -0
- data/lib/facebook_ads/ad_objects/{whats_app_business_profile.rb → server_side/http_method.rb} +7 -15
- data/lib/facebook_ads/ad_objects/server_side/http_service_interface.rb +33 -0
- data/lib/facebook_ads/ad_objects/server_side/http_util.rb +31 -0
- data/lib/facebook_ads/ad_objects/server_side/user_data.rb +145 -17
- data/lib/facebook_ads/ad_objects/server_side/util.rb +216 -149
- data/lib/facebook_ads/ad_objects/system_user.rb +9 -4
- data/lib/facebook_ads/ad_objects/targeting.rb +4 -3
- data/lib/facebook_ads/ad_objects/{user_influence.rb → targeting_relaxation.rb} +2 -4
- data/lib/facebook_ads/ad_objects/third_party_measurement_report_dataset.rb +1 -0
- data/lib/facebook_ads/ad_objects/unified_thread.rb +1 -0
- data/lib/facebook_ads/ad_objects/user.rb +9 -15
- data/lib/facebook_ads/ad_objects/vehicle.rb +1 -0
- data/lib/facebook_ads/ad_objects/vehicle_offer.rb +1 -0
- data/lib/facebook_ads/ad_objects/whats_app_business_account.rb +22 -0
- data/lib/facebook_ads/errors.rb +1 -1
- data/lib/facebook_ads/version.rb +2 -2
- metadata +64 -25
- data/lib/facebook_ads/ad_objects/business_creative_folder.rb +0 -79
- data/lib/facebook_ads/ad_objects/business_image.rb +0 -95
- data/lib/facebook_ads/ad_objects/iterative_split_test_config.rb +0 -43
- data/lib/facebook_ads/ad_objects/messenger_platform_referral.rb +0 -39
- data/lib/facebook_ads/ad_objects/page_about_story.rb +0 -39
- data/lib/facebook_ads/ad_objects/split_test_config.rb +0 -41
- data/lib/facebook_ads/ad_objects/streaming_reaction.rb +0 -51
- data/lib/facebook_ads/ad_objects/user_taggable_friend.rb +0 -49
@@ -0,0 +1,43 @@
|
|
1
|
+
# Copyright (c) 2017-present, Facebook, Inc. All rights reserved.
|
2
|
+
#
|
3
|
+
# You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
4
|
+
# copy, modify, and distribute this software in source code or binary form for use
|
5
|
+
# in connection with the web services and APIs provided by Facebook.
|
6
|
+
#
|
7
|
+
# As with any software that integrates with the Facebook platform, your use of
|
8
|
+
# this software is subject to the Facebook Platform Policy
|
9
|
+
# [http://developers.facebook.com/policy/]. This copyright notice shall be
|
10
|
+
# included in all copies or substantial portions of the software.
|
11
|
+
#
|
12
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
13
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
14
|
+
# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
15
|
+
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
16
|
+
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
17
|
+
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
18
|
+
|
19
|
+
require 'concurrent'
|
20
|
+
|
21
|
+
module FacebookAds
|
22
|
+
module ServerSide
|
23
|
+
class EventRequestAsync < EventRequest
|
24
|
+
def execute
|
25
|
+
Concurrent::Promise.execute do
|
26
|
+
super
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def clone_without_events
|
31
|
+
FacebookAds::ServerSide::EventRequestAsync.new(
|
32
|
+
pixel_id: pixel_id,
|
33
|
+
test_event_code: test_event_code,
|
34
|
+
partner_agent: partner_agent,
|
35
|
+
namespace_id: namespace_id,
|
36
|
+
upload_id: upload_id,
|
37
|
+
upload_tag: upload_tag,
|
38
|
+
upload_source: upload_source,
|
39
|
+
)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
data/lib/facebook_ads/ad_objects/{whats_app_business_profile.rb → server_side/http_method.rb}
RENAMED
@@ -16,21 +16,13 @@
|
|
16
16
|
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
17
17
|
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
18
18
|
|
19
|
-
# FB:AUTOGEN
|
20
|
-
|
21
19
|
module FacebookAds
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
field :id, 'string'
|
31
|
-
field :name_verification, 'object'
|
32
|
-
field :verified_name, 'string'
|
33
|
-
has_no_delete
|
34
|
-
|
20
|
+
module ServerSide
|
21
|
+
class HttpMethod
|
22
|
+
POST = 'POST'
|
23
|
+
PUT = 'PUT'
|
24
|
+
GET = 'GET'
|
25
|
+
DELETE = 'DELETE'
|
26
|
+
end
|
35
27
|
end
|
36
28
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# Copyright (c) 2017-present, Facebook, Inc. All rights reserved.
|
2
|
+
#
|
3
|
+
# You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
4
|
+
# copy, modify, and distribute this software in source code or binary form for use
|
5
|
+
# in connection with the web services and APIs provided by Facebook.
|
6
|
+
#
|
7
|
+
# As with any software that integrates with the Facebook platform, your use of
|
8
|
+
# this software is subject to the Facebook Platform Policy
|
9
|
+
# [http://developers.facebook.com/policy/]. This copyright notice shall be
|
10
|
+
# included in all copies or substantial portions of the software.
|
11
|
+
#
|
12
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
13
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
14
|
+
# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
15
|
+
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
16
|
+
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
17
|
+
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
18
|
+
|
19
|
+
|
20
|
+
module FacebookAds
|
21
|
+
module ServerSide
|
22
|
+
class HttpServiceInterface
|
23
|
+
|
24
|
+
# String url | The graph API endpoint that will be requested
|
25
|
+
# String request_method | The HTTP request method
|
26
|
+
# Hash headers | Contains HTTP request headers including User-Agent and Accept-Encoding
|
27
|
+
# Hash params | Contains request parameters including access_token, data, test_event_code, etc.
|
28
|
+
def execute(url, request_method, headers, params)
|
29
|
+
raise Exception.new("Method 'execute' not implemented")
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# Copyright (c) 2017-present, Facebook, Inc. All rights reserved.
|
2
|
+
#
|
3
|
+
# You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
|
4
|
+
# copy, modify, and distribute this software in source code or binary form for use
|
5
|
+
# in connection with the web services and APIs provided by Facebook.
|
6
|
+
#
|
7
|
+
# As with any software that integrates with the Facebook platform, your use of
|
8
|
+
# this software is subject to the Facebook Platform Policy
|
9
|
+
# [http://developers.facebook.com/policy/]. This copyright notice shall be
|
10
|
+
# included in all copies or substantial portions of the software.
|
11
|
+
#
|
12
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
13
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
14
|
+
# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
15
|
+
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
16
|
+
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
17
|
+
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
18
|
+
|
19
|
+
module FacebookAds
|
20
|
+
module ServerSide
|
21
|
+
class HttpUtil
|
22
|
+
def self.appsecret_proof(app_secret, access_token)
|
23
|
+
OpenSSL::HMAC.hexdigest(
|
24
|
+
OpenSSL::Digest.new('sha256'),
|
25
|
+
app_secret,
|
26
|
+
access_token
|
27
|
+
)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -16,8 +16,6 @@
|
|
16
16
|
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
17
17
|
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
18
18
|
|
19
|
-
require_relative 'util'
|
20
|
-
|
21
19
|
module FacebookAds
|
22
20
|
module ServerSide
|
23
21
|
|
@@ -93,6 +91,27 @@ module FacebookAds
|
|
93
91
|
# The subscription ID for the user in this transaction. This is similar to the order ID for an individual product.
|
94
92
|
attr_accessor :subscription_id
|
95
93
|
|
94
|
+
# The lead ID for the user in this transaction. This ID is associated with a lead generated by Facebook's Lead Ads.
|
95
|
+
attr_accessor :lead_id
|
96
|
+
|
97
|
+
# The first 5 letters of the first name.
|
98
|
+
attr_accessor :f5first
|
99
|
+
|
100
|
+
# The first 5 letters of the last name.
|
101
|
+
attr_accessor :f5last
|
102
|
+
|
103
|
+
# The first initial.
|
104
|
+
attr_accessor :fi
|
105
|
+
|
106
|
+
# The date of birth day.
|
107
|
+
attr_accessor :dobd
|
108
|
+
|
109
|
+
# The date of birth month.
|
110
|
+
attr_accessor :dobm
|
111
|
+
|
112
|
+
# THe date of birth year.
|
113
|
+
attr_accessor :doby
|
114
|
+
|
96
115
|
#UserData is a set of identifiers Facebook can use for targeted attribution
|
97
116
|
# @param [String] email
|
98
117
|
# @param [String] phone
|
@@ -110,10 +129,18 @@ module FacebookAds
|
|
110
129
|
# @param [String] fbc
|
111
130
|
# @param [String] fbp
|
112
131
|
# @param [String] subscription_id
|
132
|
+
# @param [String] lead_id
|
133
|
+
# @param [String] f5first
|
134
|
+
# @param [String] f5last
|
135
|
+
# @param [String] fi
|
136
|
+
# @param [String] dobd
|
137
|
+
# @param [String] dobm
|
138
|
+
# @param [String] doby
|
113
139
|
def initialize(email: nil, phone: nil, gender: nil, date_of_birth: nil,
|
114
140
|
last_name: nil, first_name: nil, city: nil, state: nil,
|
115
141
|
country_code: nil, zip_code: nil, external_id: nil, client_ip_address: nil,
|
116
|
-
client_user_agent: nil, fbc: nil, fbp: nil, subscription_id: nil
|
142
|
+
client_user_agent: nil, fbc: nil, fbp: nil, subscription_id: nil, lead_id: nil,
|
143
|
+
f5first: nil, f5last: nil, fi: nil, dobd: nil, dobm: nil, doby: nil)
|
117
144
|
unless email.nil?
|
118
145
|
self.email = email
|
119
146
|
end
|
@@ -162,6 +189,27 @@ module FacebookAds
|
|
162
189
|
unless subscription_id.nil?
|
163
190
|
self.subscription_id = subscription_id
|
164
191
|
end
|
192
|
+
unless lead_id.nil?
|
193
|
+
self.lead_id = lead_id
|
194
|
+
end
|
195
|
+
unless f5first.nil?
|
196
|
+
self.f5first = f5first
|
197
|
+
end
|
198
|
+
unless f5last.nil?
|
199
|
+
self.f5last = f5last
|
200
|
+
end
|
201
|
+
unless fi.nil?
|
202
|
+
self.fi = fi
|
203
|
+
end
|
204
|
+
unless dobd.nil?
|
205
|
+
self.dobd = dobd
|
206
|
+
end
|
207
|
+
unless dobm.nil?
|
208
|
+
self.dobm = dobm
|
209
|
+
end
|
210
|
+
unless doby.nil?
|
211
|
+
self.doby = doby
|
212
|
+
end
|
165
213
|
end
|
166
214
|
|
167
215
|
# build the object using the input hash
|
@@ -232,8 +280,32 @@ module FacebookAds
|
|
232
280
|
self.fbp = attributes[:'fbp']
|
233
281
|
end
|
234
282
|
|
235
|
-
if attributes.has_key?(:'
|
236
|
-
self.
|
283
|
+
if attributes.has_key?(:'lead_id')
|
284
|
+
self.lead_id = attributes[:'lead_id']
|
285
|
+
end
|
286
|
+
|
287
|
+
if attributes.has_key?(:'f5first')
|
288
|
+
self.f5first = attributes[:'f5first']
|
289
|
+
end
|
290
|
+
|
291
|
+
if attributes.has_key?(:'f5last')
|
292
|
+
self.f5last = attributes[:'f5last']
|
293
|
+
end
|
294
|
+
|
295
|
+
if attributes.has_key?(:'fi')
|
296
|
+
self.fi = attributes[:'fi']
|
297
|
+
end
|
298
|
+
|
299
|
+
if attributes.has_key?(:'dobd')
|
300
|
+
self.dobd = attributes[:'dobd']
|
301
|
+
end
|
302
|
+
|
303
|
+
if attributes.has_key?(:'dobm')
|
304
|
+
self.dobm = attributes[:'dobm']
|
305
|
+
end
|
306
|
+
|
307
|
+
if attributes.has_key?(:'doby')
|
308
|
+
self.doby = attributes[:'doby']
|
237
309
|
end
|
238
310
|
end
|
239
311
|
|
@@ -256,7 +328,14 @@ module FacebookAds
|
|
256
328
|
client_user_agent == o.client_user_agent &&
|
257
329
|
fbc == o.fbc &&
|
258
330
|
fbp == o.fbp &&
|
259
|
-
subscription_id == o.subscription_id
|
331
|
+
subscription_id == o.subscription_id &&
|
332
|
+
lead_id == o.lead_id &&
|
333
|
+
f5first == o.f5first &&
|
334
|
+
f5last == o.f5last &&
|
335
|
+
fi == o.fi &&
|
336
|
+
dobd == o.dobd &&
|
337
|
+
dobm == o.dobm &&
|
338
|
+
doby == o.doby
|
260
339
|
end
|
261
340
|
|
262
341
|
# @see the `==` method
|
@@ -283,7 +362,14 @@ module FacebookAds
|
|
283
362
|
client_user_agent,
|
284
363
|
fbc,
|
285
364
|
fbp,
|
286
|
-
subscription_id
|
365
|
+
subscription_id,
|
366
|
+
lead_id,
|
367
|
+
f5first,
|
368
|
+
f5last,
|
369
|
+
fi,
|
370
|
+
dobd,
|
371
|
+
dobm,
|
372
|
+
doby,
|
287
373
|
].hash
|
288
374
|
|
289
375
|
end
|
@@ -340,6 +426,27 @@ module FacebookAds
|
|
340
426
|
unless subscription_id.nil?
|
341
427
|
hash['subscription_id'] = subscription_id
|
342
428
|
end
|
429
|
+
unless lead_id.nil?
|
430
|
+
hash['lead_id'] = lead_id
|
431
|
+
end
|
432
|
+
unless f5first.nil?
|
433
|
+
hash['f5first'] = f5first
|
434
|
+
end
|
435
|
+
unless f5last.nil?
|
436
|
+
hash['f5last'] = f5last
|
437
|
+
end
|
438
|
+
unless fi.nil?
|
439
|
+
hash['fi'] = fi
|
440
|
+
end
|
441
|
+
unless dobd.nil?
|
442
|
+
hash['dobd'] = dobd
|
443
|
+
end
|
444
|
+
unless dobm.nil?
|
445
|
+
hash['dobm'] = dobm
|
446
|
+
end
|
447
|
+
unless doby.nil?
|
448
|
+
hash['doby'] = doby
|
449
|
+
end
|
343
450
|
hash.to_s
|
344
451
|
end
|
345
452
|
|
@@ -348,34 +455,34 @@ module FacebookAds
|
|
348
455
|
def normalize
|
349
456
|
hash = {}
|
350
457
|
unless email.nil?
|
351
|
-
hash['em'] = FacebookAds::ServerSide::normalize(email, 'em')
|
458
|
+
hash['em'] = FacebookAds::ServerSide::Util.normalize(email, 'em')
|
352
459
|
end
|
353
460
|
unless phone.nil?
|
354
|
-
hash['ph'] = FacebookAds::ServerSide::normalize(phone, 'ph')
|
461
|
+
hash['ph'] = FacebookAds::ServerSide::Util.normalize(phone, 'ph')
|
355
462
|
end
|
356
463
|
unless gender.nil?
|
357
|
-
hash['ge'] = FacebookAds::ServerSide::normalize(gender, 'ge')
|
464
|
+
hash['ge'] = FacebookAds::ServerSide::Util.normalize(gender, 'ge')
|
358
465
|
end
|
359
466
|
unless date_of_birth.nil?
|
360
|
-
hash['db'] = FacebookAds::ServerSide::normalize(date_of_birth, 'db')
|
467
|
+
hash['db'] = FacebookAds::ServerSide::Util.normalize(date_of_birth, 'db')
|
361
468
|
end
|
362
469
|
unless last_name.nil?
|
363
|
-
hash['ln'] = FacebookAds::ServerSide::normalize(last_name, 'ln')
|
470
|
+
hash['ln'] = FacebookAds::ServerSide::Util.normalize(last_name, 'ln')
|
364
471
|
end
|
365
472
|
unless first_name.nil?
|
366
|
-
hash['fn'] = FacebookAds::ServerSide::normalize(first_name, 'fn')
|
473
|
+
hash['fn'] = FacebookAds::ServerSide::Util.normalize(first_name, 'fn')
|
367
474
|
end
|
368
475
|
unless city.nil?
|
369
|
-
hash['ct'] = FacebookAds::ServerSide::normalize(city, 'ct')
|
476
|
+
hash['ct'] = FacebookAds::ServerSide::Util.normalize(city, 'ct')
|
370
477
|
end
|
371
478
|
unless country_code.nil?
|
372
|
-
hash['country'] = FacebookAds::ServerSide::normalize(country_code, 'country')
|
479
|
+
hash['country'] = FacebookAds::ServerSide::Util.normalize(country_code, 'country')
|
373
480
|
end
|
374
481
|
unless state.nil?
|
375
|
-
hash['st'] = FacebookAds::ServerSide::normalize(state, 'st')
|
482
|
+
hash['st'] = FacebookAds::ServerSide::Util.normalize(state, 'st')
|
376
483
|
end
|
377
484
|
unless zip_code.nil?
|
378
|
-
hash['zp'] = FacebookAds::ServerSide::normalize(zip_code, 'zp')
|
485
|
+
hash['zp'] = FacebookAds::ServerSide::Util.normalize(zip_code, 'zp')
|
379
486
|
end
|
380
487
|
unless external_id.nil?
|
381
488
|
hash['external_id'] = external_id
|
@@ -395,6 +502,27 @@ module FacebookAds
|
|
395
502
|
unless subscription_id.nil?
|
396
503
|
hash['subscription_id'] = subscription_id
|
397
504
|
end
|
505
|
+
unless lead_id.nil?
|
506
|
+
hash['lead_id'] = lead_id
|
507
|
+
end
|
508
|
+
unless f5first.nil?
|
509
|
+
hash['f5first'] = FacebookAds::ServerSide::Util.normalize(f5first, 'f5first')
|
510
|
+
end
|
511
|
+
unless f5last.nil?
|
512
|
+
hash['f5last'] = FacebookAds::ServerSide::Util.normalize(f5last, 'f5last')
|
513
|
+
end
|
514
|
+
unless fi.nil?
|
515
|
+
hash['fi'] = FacebookAds::ServerSide::Util.normalize(fi, 'fi')
|
516
|
+
end
|
517
|
+
unless dobd.nil?
|
518
|
+
hash['dobd'] = FacebookAds::ServerSide::Util.normalize(dobd, 'dobd')
|
519
|
+
end
|
520
|
+
unless dobm.nil?
|
521
|
+
hash['dobm'] = FacebookAds::ServerSide::Util.normalize(dobm, 'dobm')
|
522
|
+
end
|
523
|
+
unless doby.nil?
|
524
|
+
hash['doby'] = FacebookAds::ServerSide::Util.normalize(doby, 'doby')
|
525
|
+
end
|
398
526
|
hash
|
399
527
|
end
|
400
528
|
end
|
@@ -19,210 +19,277 @@
|
|
19
19
|
require 'digest'
|
20
20
|
require 'countries'
|
21
21
|
require 'money'
|
22
|
+
require 'time'
|
22
23
|
|
23
24
|
module FacebookAds
|
24
25
|
module ServerSide
|
26
|
+
class Util
|
27
|
+
PHONE_NUMBER_IGNORE_CHAR_SET = /[\-\s\(\)]+/
|
28
|
+
PHONE_NUMBER_DROP_PREFIX_ZEROS = /^\+?0{0,2}/
|
29
|
+
US_PHONE_NUMBER_REGEX = /^1\(?\d{3}\)?\d{7}$/
|
30
|
+
INTL_PHONE_NUMBER_REGEX = /^\d{1,4}\(?\d{2,3}\)?\d{4,}$/
|
31
|
+
|
32
|
+
# RFC 2822 for email format
|
33
|
+
EMAIL_REGEX = /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i
|
34
|
+
|
35
|
+
# Normalizes the input string given the field_type
|
36
|
+
# @param [String] input Input string that needs to be normalized
|
37
|
+
# @param [String] field_type Type/Key for the value provided
|
38
|
+
# @return [String] Normalized value for the input and field_type.
|
39
|
+
def self.normalize(input, field_type)
|
40
|
+
|
41
|
+
if input.nil? or field_type.nil?
|
42
|
+
return nil;
|
43
|
+
end
|
44
|
+
|
45
|
+
input = input.strip.downcase
|
46
|
+
|
47
|
+
# If the data is already hashed, we by-pass input normalization
|
48
|
+
if is_already_hashed?(input) == true
|
49
|
+
return input
|
50
|
+
end
|
51
|
+
|
52
|
+
normalized_input = input;
|
53
|
+
|
54
|
+
case field_type
|
55
|
+
when 'country'
|
56
|
+
normalized_input = normalize_country input
|
57
|
+
when 'ct'
|
58
|
+
normalized_input = normalize_city input
|
59
|
+
when 'currency'
|
60
|
+
return normalize_currency input
|
61
|
+
when 'delivery_category'
|
62
|
+
return normalize_delivery_category input
|
63
|
+
when 'em'
|
64
|
+
normalized_input = normalize_email input
|
65
|
+
when 'ge'
|
66
|
+
normalized_input = normalize_gender input
|
67
|
+
when 'ph'
|
68
|
+
normalized_input = normalize_phone input
|
69
|
+
when 'st'
|
70
|
+
normalized_input = normalize_state input
|
71
|
+
when 'zp'
|
72
|
+
normalized_input = normalize_zip input
|
73
|
+
when 'f5first'
|
74
|
+
normalized_input = normalize_f5 input
|
75
|
+
when 'f5last'
|
76
|
+
normalized_input = normalize_f5 input
|
77
|
+
when 'fi'
|
78
|
+
normalized_input = normalize_fi input
|
79
|
+
when 'dobd'
|
80
|
+
normalized_input = normalize_dobd input
|
81
|
+
when 'dobm'
|
82
|
+
normalized_input = normalize_dobm input
|
83
|
+
when 'doby'
|
84
|
+
normalized_input = normalize_doby input
|
85
|
+
end
|
86
|
+
|
87
|
+
normalized_input = sha256Hash normalized_input
|
88
|
+
|
89
|
+
return normalized_input
|
90
|
+
end
|
91
|
+
|
92
|
+
# @return [String] SHA 256 hash of input string
|
93
|
+
def self.sha256Hash(input)
|
94
|
+
unless input.nil?
|
95
|
+
Digest::SHA256.hexdigest input
|
96
|
+
end
|
97
|
+
end
|
25
98
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
99
|
+
# Boolean method which checks if a input is already hashed with MD5 or SHA256
|
100
|
+
# @param [String] input Input string that is to be validated
|
101
|
+
# @return [TrueClass|FalseClass] representing whether the value is hashed
|
102
|
+
def self.is_already_hashed?(input)
|
30
103
|
|
31
|
-
|
32
|
-
|
104
|
+
# We support Md5 and SHA256, and highly recommend users to use SHA256 for hashing PII keys.
|
105
|
+
md5_match = /^[a-f0-9]{32}$/.match(input)
|
106
|
+
sha256_match = /^[a-f0-9]{64}$/.match(input)
|
33
107
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
108
|
+
if md5_match != nil or sha256_match != nil
|
109
|
+
return true
|
110
|
+
end
|
111
|
+
|
112
|
+
return false
|
38
113
|
end
|
39
|
-
end
|
40
114
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
input = input.strip.downcase
|
52
|
-
|
53
|
-
# If the data is already hashed, we by-pass input normalization
|
54
|
-
if FacebookAds::ServerSide::is_already_hashed?(input) == true
|
55
|
-
return input
|
56
|
-
end
|
57
|
-
|
58
|
-
normalized_input = input;
|
59
|
-
|
60
|
-
case field_type
|
61
|
-
when 'country'
|
62
|
-
normalized_input = FacebookAds::ServerSide::normalize_country input
|
63
|
-
when 'ct'
|
64
|
-
normalized_input = FacebookAds::ServerSide::normalize_city input
|
65
|
-
when 'currency'
|
66
|
-
return FacebookAds::ServerSide::normalize_currency input
|
67
|
-
when 'em'
|
68
|
-
normalized_input = FacebookAds::ServerSide::normalize_email input
|
69
|
-
when 'ge'
|
70
|
-
normalized_input = FacebookAds::ServerSide::normalize_gender input
|
71
|
-
when 'ph'
|
72
|
-
normalized_input = FacebookAds::ServerSide::normalize_phone input
|
73
|
-
when 'st'
|
74
|
-
normalized_input = FacebookAds::ServerSide::normalize_state input
|
75
|
-
when 'zp'
|
76
|
-
normalized_input = FacebookAds::ServerSide::normalize_zip input
|
77
|
-
end
|
78
|
-
|
79
|
-
normalized_input = FacebookAds::ServerSide::sha256Hash normalized_input
|
80
|
-
|
81
|
-
return normalized_input
|
82
|
-
end
|
115
|
+
# Normalizes the given country code and returns acceptable hashed country ISO code
|
116
|
+
def self.normalize_country(country)
|
117
|
+
|
118
|
+
# Replace unwanted characters and retain only alpha characters bounded for ISO code.
|
119
|
+
country = country.gsub(/[^a-z]/,'')
|
120
|
+
iso_country = ISO3166::Country.search(country)
|
121
|
+
if iso_country == nil
|
122
|
+
raise ArgumentError, "Invalid format for country:'" + country + "'.Please follow ISO 2-letter ISO 3166-1 standard for representing country. eg: us"
|
123
|
+
end
|
83
124
|
|
84
|
-
|
85
|
-
|
86
|
-
# @return [TrueClass|FalseClass] representing whether the value is hashed
|
87
|
-
def self.is_already_hashed?(input)
|
125
|
+
return country
|
126
|
+
end
|
88
127
|
|
89
|
-
#
|
90
|
-
|
91
|
-
sha256_match = /^[a-f0-9]{64}$/.match(input)
|
128
|
+
# Normalizes the given city and returns acceptable hashed city value
|
129
|
+
def self.normalize_city(city)
|
92
130
|
|
93
|
-
|
94
|
-
|
131
|
+
# Remove commonly occuring characters from city name.
|
132
|
+
city = city.gsub(/[0-9.\s\-()]/,'')
|
133
|
+
|
134
|
+
return city
|
95
135
|
end
|
96
136
|
|
97
|
-
|
98
|
-
|
137
|
+
# Normalizes the given currency code and returns acceptable hashed currency ISO code
|
138
|
+
def self.normalize_currency(currency)
|
99
139
|
|
100
|
-
|
101
|
-
|
140
|
+
# Retain only alpha characters bounded for ISO code.
|
141
|
+
currency = currency.gsub(/[^a-z]/,'')
|
102
142
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
143
|
+
iso_currency = Money::Currency.find(currency)
|
144
|
+
if iso_currency == nil
|
145
|
+
raise ArgumentError, "Invalid format for currency:'" + currency + "'.Please follow ISO 3-letter ISO 4217 standard for representing currency. Eg: usd"
|
146
|
+
end
|
147
|
+
|
148
|
+
return currency;
|
108
149
|
end
|
109
150
|
|
110
|
-
|
111
|
-
|
151
|
+
# Normalizes the given email and returns acceptable hashed email value
|
152
|
+
def self.normalize_email(email)
|
112
153
|
|
113
|
-
|
114
|
-
|
154
|
+
if EMAIL_REGEX.match(email) == nil
|
155
|
+
return ArgumentError, "Invalid email format for the passed email:' + email + '.Please check the passed email format."
|
156
|
+
end
|
115
157
|
|
116
|
-
|
117
|
-
|
158
|
+
return email
|
159
|
+
end
|
118
160
|
|
119
|
-
|
120
|
-
|
161
|
+
# Normalizes the given gender and returns acceptable hashed gender value
|
162
|
+
def self.normalize_gender(gender)
|
121
163
|
|
122
|
-
|
123
|
-
|
164
|
+
# Replace extra characters with space, to bound under alpha characters set.
|
165
|
+
gender = gender.gsub(/[^a-z]/,'')
|
124
166
|
|
125
|
-
|
126
|
-
|
167
|
+
case gender
|
168
|
+
when 'female' , 'f'
|
169
|
+
gender = 'f'
|
170
|
+
when 'male' , 'm'
|
171
|
+
gender = 'm'
|
172
|
+
else
|
173
|
+
return nil
|
174
|
+
end
|
127
175
|
|
128
|
-
|
129
|
-
|
130
|
-
raise ArgumentError, "Invalid format for currency:'" + currency + "'.Please follow ISO 3-letter ISO 4217 standard for representing currency. Eg: usd"
|
131
|
-
end
|
176
|
+
return gender
|
177
|
+
end
|
132
178
|
|
133
|
-
|
134
|
-
|
179
|
+
# Normalizes the given phone and returns acceptable hashed phone value
|
180
|
+
def self.normalize_phone(phone)
|
135
181
|
|
136
|
-
|
137
|
-
|
182
|
+
# Drop the spaces, hyphen and parenthesis from the Phone Number
|
183
|
+
normalized_phone = phone.gsub(PHONE_NUMBER_IGNORE_CHAR_SET, '')
|
138
184
|
|
139
|
-
|
140
|
-
|
141
|
-
|
185
|
+
if(is_international_number?(normalized_phone))
|
186
|
+
normalized_phone = normalized_phone.gsub(PHONE_NUMBER_DROP_PREFIX_ZEROS, '')
|
187
|
+
end
|
142
188
|
|
143
|
-
|
144
|
-
|
189
|
+
if normalized_phone.length < 7 || normalized_phone.length > 15
|
190
|
+
return nil;
|
191
|
+
end
|
145
192
|
|
146
|
-
|
147
|
-
|
193
|
+
return normalized_phone
|
194
|
+
end
|
148
195
|
|
149
|
-
|
150
|
-
|
196
|
+
# Normalizes the given state and returns acceptable hashed state value
|
197
|
+
def self.normalize_state(state)
|
198
|
+
state = state.gsub(/[0-9.\s\-()]/,'')
|
151
199
|
|
152
|
-
|
153
|
-
when 'female' , 'f'
|
154
|
-
gender = 'f'
|
155
|
-
when 'male' , 'm'
|
156
|
-
gender = 'm'
|
157
|
-
else
|
158
|
-
return nil
|
200
|
+
return state
|
159
201
|
end
|
160
202
|
|
161
|
-
|
162
|
-
|
203
|
+
# Normalizes the given zip and returns acceptable hashed zip code value
|
204
|
+
def self.normalize_zip(zip)
|
163
205
|
|
164
|
-
|
165
|
-
|
206
|
+
# Remove spaces from the Postal code
|
207
|
+
zip = zip.gsub(/[\s]/,'')
|
166
208
|
|
167
|
-
|
168
|
-
|
209
|
+
# If the zip code '-', we retain just the first part alone.
|
210
|
+
zip = zip.split('-')[0]
|
169
211
|
|
170
|
-
|
171
|
-
|
172
|
-
|
212
|
+
if zip.length < 2
|
213
|
+
return nil
|
214
|
+
end
|
173
215
|
|
174
|
-
|
175
|
-
return nil;
|
216
|
+
return zip
|
176
217
|
end
|
177
218
|
|
178
|
-
|
179
|
-
|
219
|
+
# Boolean method which checks if a given number is represented in international format
|
220
|
+
# @param [String] phone_number that has to be tested.
|
221
|
+
# @return [TrueClass | FalseClass] boolean value representing if a number is international
|
222
|
+
def self.is_international_number?(phone_number)
|
180
223
|
|
181
|
-
|
182
|
-
|
183
|
-
state = state.gsub(/[0-9.\s\-()]/,'')
|
224
|
+
# Drop upto 2 leading 0s from the number
|
225
|
+
phone_number = phone_number.gsub(PHONE_NUMBER_DROP_PREFIX_ZEROS, '')
|
184
226
|
|
185
|
-
|
186
|
-
|
227
|
+
if phone_number.start_with?('0')
|
228
|
+
return false;
|
229
|
+
end
|
187
230
|
|
188
|
-
|
189
|
-
|
231
|
+
if phone_number.start_with?('1') && US_PHONE_NUMBER_REGEX.match(phone_number) != nil
|
232
|
+
return false;
|
233
|
+
end
|
190
234
|
|
191
|
-
|
192
|
-
|
235
|
+
if INTL_PHONE_NUMBER_REGEX.match(phone_number) != nil
|
236
|
+
return true;
|
237
|
+
end
|
193
238
|
|
194
|
-
|
195
|
-
|
239
|
+
return false;
|
240
|
+
end
|
196
241
|
|
197
|
-
|
198
|
-
|
242
|
+
def self.normalize_f5(input)
|
243
|
+
input[0, 5]
|
199
244
|
end
|
200
245
|
|
201
|
-
|
202
|
-
|
246
|
+
def self.normalize_fi(fi)
|
247
|
+
fi[0, 1]
|
248
|
+
end
|
203
249
|
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
250
|
+
def self.normalize_dobd(dobd)
|
251
|
+
if dobd.length == 1
|
252
|
+
dobd = '0' + dobd
|
253
|
+
end
|
208
254
|
|
209
|
-
|
210
|
-
|
255
|
+
dobd_int = dobd.to_i
|
256
|
+
if dobd.length > 2 or dobd_int < 1 or dobd_int > 31
|
257
|
+
raise ArgumentError.new("Invalid dobd format: '#{dobd}'. Please pass in a valid date of birth day in 'DD' format.")
|
258
|
+
end
|
211
259
|
|
212
|
-
|
213
|
-
return false;
|
260
|
+
return dobd
|
214
261
|
end
|
215
262
|
|
216
|
-
|
217
|
-
|
263
|
+
def self.normalize_dobm(dobm)
|
264
|
+
if dobm.length == 1
|
265
|
+
dobm = '0' + dobm
|
266
|
+
end
|
267
|
+
|
268
|
+
dobm_int = dobm.to_i
|
269
|
+
if dobm.length > 2 or dobm_int < 1 or dobm_int > 12
|
270
|
+
raise ArgumentError.new("Invalid dobm format: '#{dobm}'. Please pass in a valid date of birth month in 'MM' format.")
|
271
|
+
end
|
272
|
+
|
273
|
+
return dobm
|
218
274
|
end
|
219
275
|
|
220
|
-
|
221
|
-
|
276
|
+
def self.normalize_doby(doby)
|
277
|
+
unless doby.match("^[0-9]{4}$")
|
278
|
+
raise ArgumentError.new("Invalid doby format: '#{doby}'. Please pass in a valid birth year in 'YYYY' format.")
|
279
|
+
end
|
280
|
+
doby
|
222
281
|
end
|
223
282
|
|
224
|
-
|
225
|
-
|
283
|
+
# Normalizes the input delivery category and returns valid value (or throw exception if invalid).
|
284
|
+
def self.normalize_delivery_category(delivery_category)
|
226
285
|
|
286
|
+
unless FacebookAds::ServerSide::DeliveryCategory.include?(delivery_category)
|
287
|
+
raise ArgumentError.new("Invalid delivery_category passed: " + delivery_category + ". Please use one of the defined values #{FacebookAds::ServerSide::DeliveryCategory.to_a.join(',')}" )
|
288
|
+
end
|
289
|
+
|
290
|
+
delivery_category;
|
291
|
+
end
|
292
|
+
|
293
|
+
end
|
227
294
|
end
|
228
295
|
end
|