facebookbusiness 0.6.0.3 → 0.7.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (111) hide show
  1. checksums.yaml +4 -4
  2. data/lib/facebook_ads/ad_objects/ad.rb +0 -1
  3. data/lib/facebook_ads/ad_objects/ad_account.rb +8 -16
  4. data/lib/facebook_ads/ad_objects/ad_account_activity.rb +3 -5
  5. data/lib/facebook_ads/ad_objects/ad_account_creation_request.rb +0 -1
  6. data/lib/facebook_ads/ad_objects/ad_account_delivery_estimate.rb +1 -0
  7. data/lib/facebook_ads/ad_objects/ad_account_matched_search_applications_edge_data.rb +1 -0
  8. data/lib/facebook_ads/ad_objects/ad_account_targeting_unified.rb +4 -0
  9. data/lib/facebook_ads/ad_objects/ad_activity.rb +8 -0
  10. data/lib/facebook_ads/ad_objects/ad_asset_feed_spec.rb +7 -0
  11. data/lib/facebook_ads/ad_objects/ad_campaign_activity.rb +2 -2
  12. data/lib/facebook_ads/ad_objects/ad_campaign_delivery_estimate.rb +1 -0
  13. data/lib/facebook_ads/ad_objects/ad_creative.rb +6 -3
  14. data/lib/facebook_ads/ad_objects/{user_influence.rb → ad_creative_ad_disclaimer.rb} +4 -4
  15. data/lib/facebook_ads/ad_objects/ad_creative_link_data_call_to_action.rb +6 -0
  16. data/lib/facebook_ads/ad_objects/ad_creative_video_data.rb +1 -0
  17. data/lib/facebook_ads/ad_objects/ad_customization_rule_spec.rb +2 -0
  18. data/lib/facebook_ads/ad_objects/ad_network_analytics_sync_query_result.rb +1 -0
  19. data/lib/facebook_ads/ad_objects/ad_place_page_set.rb +1 -0
  20. data/lib/facebook_ads/ad_objects/ad_preview.rb +1 -0
  21. data/lib/facebook_ads/ad_objects/ad_report_run.rb +2 -0
  22. data/lib/facebook_ads/ad_objects/ad_set.rb +10 -2
  23. data/lib/facebook_ads/ad_objects/ad_study.rb +1 -0
  24. data/lib/facebook_ads/ad_objects/ad_video.rb +7 -26
  25. data/lib/facebook_ads/ad_objects/adgroup_activity.rb +4 -4
  26. data/lib/facebook_ads/ad_objects/adgroup_placement_specific_review_feedback.rb +5 -0
  27. data/lib/facebook_ads/ad_objects/{ads_interest.rb → adoptable_pet.rb} +18 -5
  28. data/lib/facebook_ads/ad_objects/ads_insights.rb +10 -0
  29. data/lib/facebook_ads/ad_objects/album.rb +7 -0
  30. data/lib/facebook_ads/ad_objects/application.rb +4 -12
  31. data/lib/facebook_ads/ad_objects/atlas_campaign.rb +2 -2
  32. data/lib/facebook_ads/ad_objects/automotive_model.rb +1 -0
  33. data/lib/facebook_ads/ad_objects/business.rb +24 -128
  34. data/lib/facebook_ads/ad_objects/{business_creative_folder_sharing_agreement.rb → business_agreement.rb} +2 -5
  35. data/lib/facebook_ads/ad_objects/business_asset_group.rb +0 -7
  36. data/lib/facebook_ads/ad_objects/business_owned_object_on_behalf_of_request.rb +1 -0
  37. data/lib/facebook_ads/ad_objects/business_role_request.rb +6 -0
  38. data/lib/facebook_ads/ad_objects/business_user.rb +6 -0
  39. data/lib/facebook_ads/ad_objects/campaign.rb +267 -5
  40. data/lib/facebook_ads/ad_objects/{request_history.rb → catalog_item_app_links.rb} +9 -14
  41. data/lib/facebook_ads/ad_objects/catalog_item_appeal_status.rb +1 -1
  42. data/lib/facebook_ads/ad_objects/comment.rb +1 -0
  43. data/lib/facebook_ads/ad_objects/commerce_merchant_settings.rb +107 -0
  44. data/lib/facebook_ads/ad_objects/commerce_merchant_settings_setup_status.rb +41 -0
  45. data/lib/facebook_ads/ad_objects/commerce_order.rb +147 -0
  46. data/lib/facebook_ads/ad_objects/{business_creative.rb → commerce_order_transaction_detail.rb} +10 -12
  47. data/lib/facebook_ads/ad_objects/{client_transparency_status.rb → commerce_payout.rb} +6 -5
  48. data/lib/facebook_ads/ad_objects/cpas_parent_catalog_settings.rb +1 -0
  49. data/lib/facebook_ads/ad_objects/custom_audience.rb +1 -4
  50. data/lib/facebook_ads/ad_objects/custom_conversion.rb +1 -0
  51. data/lib/facebook_ads/ad_objects/destination.rb +1 -0
  52. data/lib/facebook_ads/ad_objects/event.rb +11 -0
  53. data/lib/facebook_ads/ad_objects/external_event_source.rb +1 -0
  54. data/lib/facebook_ads/ad_objects/flight.rb +1 -0
  55. data/lib/facebook_ads/ad_objects/group.rb +7 -36
  56. data/lib/facebook_ads/ad_objects/home_listing.rb +1 -0
  57. data/lib/facebook_ads/ad_objects/hotel.rb +1 -1
  58. data/lib/facebook_ads/ad_objects/hotel_room.rb +1 -0
  59. data/lib/facebook_ads/ad_objects/ig_media.rb +1 -0
  60. data/lib/facebook_ads/ad_objects/ig_user.rb +2 -0
  61. data/lib/facebook_ads/ad_objects/life_event.rb +0 -4
  62. data/lib/facebook_ads/ad_objects/media_fingerprint.rb +0 -1
  63. data/lib/facebook_ads/ad_objects/messenger_profile.rb +0 -1
  64. data/lib/facebook_ads/ad_objects/offline_conversion_data_set.rb +0 -6
  65. data/lib/facebook_ads/ad_objects/open_graph_context.rb +0 -12
  66. data/lib/facebook_ads/ad_objects/page.rb +50 -50
  67. data/lib/facebook_ads/ad_objects/page_admin_note.rb +1 -0
  68. data/lib/facebook_ads/ad_objects/page_call_to_action.rb +12 -0
  69. data/lib/facebook_ads/ad_objects/page_change_proposal.rb +2 -0
  70. data/lib/facebook_ads/ad_objects/page_post.rb +9 -0
  71. data/lib/facebook_ads/ad_objects/partner_study.rb +0 -4
  72. data/lib/facebook_ads/ad_objects/{brand_audience.rb → payment_subscription.rb} +23 -9
  73. data/lib/facebook_ads/ad_objects/post.rb +11 -2
  74. data/lib/facebook_ads/ad_objects/product_catalog.rb +12 -1
  75. data/lib/facebook_ads/ad_objects/product_feed.rb +2 -0
  76. data/lib/facebook_ads/ad_objects/product_feed_upload_diagnostics_report.rb +38 -0
  77. data/lib/facebook_ads/ad_objects/product_item.rb +1 -0
  78. data/lib/facebook_ads/ad_objects/product_set.rb +3 -0
  79. data/lib/facebook_ads/ad_objects/{custom_audience_prefill_state.rb → product_set_metadata.rb} +3 -3
  80. data/lib/facebook_ads/ad_objects/profile.rb +2 -0
  81. data/lib/facebook_ads/ad_objects/profile_picture_source.rb +4 -0
  82. data/lib/facebook_ads/ad_objects/publisher_block_list.rb +0 -6
  83. data/lib/facebook_ads/ad_objects/rtb_dynamic_post.rb +0 -4
  84. data/lib/facebook_ads/ad_objects/saved_audience.rb +1 -0
  85. data/lib/facebook_ads/ad_objects/server_side/content.rb +75 -13
  86. data/lib/facebook_ads/ad_objects/server_side/custom_data.rb +24 -6
  87. data/lib/facebook_ads/ad_objects/server_side/event.rb +62 -3
  88. data/lib/facebook_ads/ad_objects/server_side/event_request.rb +80 -6
  89. data/lib/facebook_ads/ad_objects/server_side/user_data.rb +132 -17
  90. data/lib/facebook_ads/ad_objects/server_side/util.rb +204 -150
  91. data/lib/facebook_ads/ad_objects/store_catalog_settings.rb +0 -1
  92. data/lib/facebook_ads/ad_objects/system_user.rb +6 -0
  93. data/lib/facebook_ads/ad_objects/targeting.rb +1 -0
  94. data/lib/facebook_ads/ad_objects/{creative_asset_tag.rb → targeting_relaxation.rb} +2 -2
  95. data/lib/facebook_ads/ad_objects/third_party_measurement_report_dataset.rb +1 -0
  96. data/lib/facebook_ads/ad_objects/user.rb +6 -38
  97. data/lib/facebook_ads/ad_objects/user_taggable_friend.rb +1 -0
  98. data/lib/facebook_ads/ad_objects/vehicle.rb +1 -1
  99. data/lib/facebook_ads/ad_objects/vehicle_offer.rb +1 -0
  100. data/lib/facebook_ads/ad_objects/whats_app_business_account.rb +4 -0
  101. data/lib/facebook_ads/ad_objects/{business_pixel_tos.rb → work_meeting_link.rb} +2 -2
  102. data/lib/facebook_ads/version.rb +2 -2
  103. metadata +45 -22
  104. data/lib/facebook_ads/ad_objects/business_creative_folder.rb +0 -79
  105. data/lib/facebook_ads/ad_objects/business_image.rb +0 -94
  106. data/lib/facebook_ads/ad_objects/instagram_comment.rb +0 -47
  107. data/lib/facebook_ads/ad_objects/messenger_platform_referral.rb +0 -39
  108. data/lib/facebook_ads/ad_objects/open_graph_object.rb +0 -70
  109. data/lib/facebook_ads/ad_objects/streaming_reaction.rb +0 -50
  110. data/lib/facebook_ads/ad_objects/video_game_show.rb +0 -43
  111. data/lib/facebook_ads/ad_objects/whats_app_business_profile.rb +0 -36
@@ -19,210 +19,264 @@
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 'em'
62
+ normalized_input = normalize_email input
63
+ when 'ge'
64
+ normalized_input = normalize_gender input
65
+ when 'ph'
66
+ normalized_input = normalize_phone input
67
+ when 'st'
68
+ normalized_input = normalize_state input
69
+ when 'zp'
70
+ normalized_input = normalize_zip input
71
+ when 'f5first'
72
+ normalized_input = normalize_f5 input
73
+ when 'f5last'
74
+ normalized_input = normalize_f5 input
75
+ when 'fi'
76
+ normalized_input = normalize_fi input
77
+ when 'dobd'
78
+ normalized_input = normalize_dobd input
79
+ when 'dobm'
80
+ normalized_input = normalize_dobm input
81
+ when 'doby'
82
+ normalized_input = normalize_doby input
83
+ end
84
+
85
+ normalized_input = sha256Hash normalized_input
86
+
87
+ return normalized_input
88
+ end
25
89
 
26
- PHONE_NUMBER_IGNORE_CHAR_SET = /[\-\s\(\)]+/
27
- PHONE_NUMBER_DROP_PREFIX_ZEROS = /^\+?0{0,2}/
28
- US_PHONE_NUMBER_REGEX = /^1\(?\d{3}\)?\d{7}$/
29
- INTL_PHONE_NUMBER_REGEX = /^\d{1,4}\(?\d{2,3}\)?\d{4,}$/
30
-
31
- # RFC 2822 for email format
32
- EMAIL_REGEX = /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i
33
-
34
- # @return [String] SHA 256 hash of input string
35
- def self.sha256Hash(input)
36
- unless input.nil?
37
- Digest::SHA256.hexdigest input
90
+ # @return [String] SHA 256 hash of input string
91
+ def self.sha256Hash(input)
92
+ unless input.nil?
93
+ Digest::SHA256.hexdigest input
94
+ end
38
95
  end
39
- end
40
96
 
41
- # Normalizes the input string given the field_type
42
- # @param [String] input Input string that needs to be normalized
43
- # @param [String] field_type Type/Key for the value provided
44
- # @return [String] Normalized value for the input and field_type.
45
- def self.normalize(input, field_type)
46
-
47
- if input.nil? or field_type.nil?
48
- return nil;
49
- end
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
97
+ # Boolean method which checks if a input is already hashed with MD5 or SHA256
98
+ # @param [String] input Input string that is to be validated
99
+ # @return [TrueClass|FalseClass] representing whether the value is hashed
100
+ def self.is_already_hashed?(input)
83
101
 
84
- # Boolean method which checks if a input is already hashed with MD5 or SHA256
85
- # @param [String] input Input string that is to be validated
86
- # @return [TrueClass|FalseClass] representing whether the value is hashed
87
- def self.is_already_hashed?(input)
102
+ # We support Md5 and SHA256, and highly recommend users to use SHA256 for hashing PII keys.
103
+ md5_match = /^[a-f0-9]{32}$/.match(input)
104
+ sha256_match = /^[a-f0-9]{64}$/.match(input)
88
105
 
89
- # We support Md5 and SHA256, and highly recommend users to use SHA256 for hashing PII keys.
90
- md5_match = /^[a-f0-9]{32}$/.match(input)
91
- sha256_match = /^[a-f0-9]{64}$/.match(input)
106
+ if md5_match != nil or sha256_match != nil
107
+ return true
108
+ end
92
109
 
93
- if md5_match != nil or sha256_match != nil
94
- return true
110
+ return false
95
111
  end
96
112
 
97
- return false
98
- end
113
+ # Normalizes the given country code and returns acceptable hashed country ISO code
114
+ def self.normalize_country(country)
99
115
 
100
- # Normalizes the given country code and returns acceptable hashed country ISO code
101
- def self.normalize_country(country)
116
+ # Replace unwanted characters and retain only alpha characters bounded for ISO code.
117
+ country = country.gsub(/[^a-z]/,'')
118
+ iso_country = ISO3166::Country.search(country)
119
+ if iso_country == nil
120
+ raise ArgumentError, "Invalid format for country:'" + country + "'.Please follow ISO 2-letter ISO 3166-1 standard for representing country. eg: us"
121
+ end
102
122
 
103
- # Replace unwanted characters and retain only alpha characters bounded for ISO code.
104
- country = country.gsub(/[^a-z]/,'')
105
- iso_country = ISO3166::Country.search(country)
106
- if iso_country == nil
107
- raise ArgumentError, "Invalid format for country:'" + country + "'.Please follow ISO 2-letter ISO 3166-1 standard for representing country. eg: us"
123
+ return country
108
124
  end
109
125
 
110
- return country
111
- end
126
+ # Normalizes the given city and returns acceptable hashed city value
127
+ def self.normalize_city(city)
112
128
 
113
- # Normalizes the given city and returns acceptable hashed city value
114
- def self.normalize_city(city)
129
+ # Remove commonly occuring characters from city name.
130
+ city = city.gsub(/[0-9.\s\-()]/,'')
115
131
 
116
- # Remove commonly occuring characters from city name.
117
- city = city.gsub(/[0-9.\s\-()]/,'')
132
+ return city
133
+ end
118
134
 
119
- return city
120
- end
135
+ # Normalizes the given currency code and returns acceptable hashed currency ISO code
136
+ def self.normalize_currency(currency)
121
137
 
122
- # Normalizes the given currency code and returns acceptable hashed currency ISO code
123
- def self.normalize_currency(currency)
138
+ # Retain only alpha characters bounded for ISO code.
139
+ currency = currency.gsub(/[^a-z]/,'')
124
140
 
125
- # Retain only alpha characters bounded for ISO code.
126
- currency = currency.gsub(/[^a-z]/,'')
141
+ iso_currency = Money::Currency.find(currency)
142
+ if iso_currency == nil
143
+ raise ArgumentError, "Invalid format for currency:'" + currency + "'.Please follow ISO 3-letter ISO 4217 standard for representing currency. Eg: usd"
144
+ end
127
145
 
128
- iso_currency = Money::Currency.find(currency)
129
- if iso_currency == nil
130
- raise ArgumentError, "Invalid format for currency:'" + currency + "'.Please follow ISO 3-letter ISO 4217 standard for representing currency. Eg: usd"
131
- end
146
+ return currency;
147
+ end
132
148
 
133
- return currency;
134
- end
149
+ # Normalizes the given email and returns acceptable hashed email value
150
+ def self.normalize_email(email)
135
151
 
136
- # Normalizes the given email and returns acceptable hashed email value
137
- def self.normalize_email(email)
152
+ if EMAIL_REGEX.match(email) == nil
153
+ return ArgumentError, "Invalid email format for the passed email:' + email + '.Please check the passed email format."
154
+ end
138
155
 
139
- if EMAIL_REGEX.match(email) == nil
140
- return ArgumentError, "Invalid email format for the passed email:' + email + '.Please check the passed email format."
141
- end
156
+ return email
157
+ end
142
158
 
143
- return email
144
- end
159
+ # Normalizes the given gender and returns acceptable hashed gender value
160
+ def self.normalize_gender(gender)
145
161
 
146
- # Normalizes the given gender and returns acceptable hashed gender value
147
- def self.normalize_gender(gender)
162
+ # Replace extra characters with space, to bound under alpha characters set.
163
+ gender = gender.gsub(/[^a-z]/,'')
148
164
 
149
- # Replace extra characters with space, to bound under alpha characters set.
150
- gender = gender.gsub(/[^a-z]/,'')
165
+ case gender
166
+ when 'female' , 'f'
167
+ gender = 'f'
168
+ when 'male' , 'm'
169
+ gender = 'm'
170
+ else
171
+ return nil
172
+ end
151
173
 
152
- case gender
153
- when 'female' , 'f'
154
- gender = 'f'
155
- when 'male' , 'm'
156
- gender = 'm'
157
- else
158
- return nil
174
+ return gender
159
175
  end
160
176
 
161
- return gender
162
- end
177
+ # Normalizes the given phone and returns acceptable hashed phone value
178
+ def self.normalize_phone(phone)
163
179
 
164
- # Normalizes the given phone and returns acceptable hashed phone value
165
- def self.normalize_phone(phone)
180
+ # Drop the spaces, hyphen and parenthesis from the Phone Number
181
+ normalized_phone = phone.gsub(PHONE_NUMBER_IGNORE_CHAR_SET, '')
166
182
 
167
- # Drop the spaces, hyphen and parenthesis from the Phone Number
168
- normalized_phone = phone.gsub(PHONE_NUMBER_IGNORE_CHAR_SET, '')
183
+ if(is_international_number?(normalized_phone))
184
+ normalized_phone = normalized_phone.gsub(PHONE_NUMBER_DROP_PREFIX_ZEROS, '')
185
+ end
169
186
 
170
- if(FacebookAds::ServerSide::is_international_number?(normalized_phone))
171
- normalized_phone = normalized_phone.gsub(PHONE_NUMBER_DROP_PREFIX_ZEROS, '')
172
- end
187
+ if normalized_phone.length < 7 || normalized_phone.length > 15
188
+ return nil;
189
+ end
173
190
 
174
- if normalized_phone.length < 7 || normalized_phone.length > 15
175
- return nil;
191
+ return normalized_phone
176
192
  end
177
193
 
178
- return normalized_phone
179
- end
194
+ # Normalizes the given state and returns acceptable hashed state value
195
+ def self.normalize_state(state)
196
+ state = state.gsub(/[0-9.\s\-()]/,'')
180
197
 
181
- # Normalizes the given city and returns acceptable hashed city value
182
- def self.normalize_state(state)
183
- state = state.gsub(/[0-9.\s\-()]/,'')
198
+ return state
199
+ end
184
200
 
185
- return state
186
- end
201
+ # Normalizes the given zip and returns acceptable hashed zip code value
202
+ def self.normalize_zip(zip)
187
203
 
188
- # Normalizes the given zip and returns acceptable hashed zip code value
189
- def self.normalize_zip(zip)
204
+ # Remove spaces from the Postal code
205
+ zip = zip.gsub(/[\s]/,'')
190
206
 
191
- # Remove spaces from the Postal code
192
- zip = zip.gsub(/[\s]/,'')
207
+ # If the zip code '-', we retain just the first part alone.
208
+ zip = zip.split('-')[0]
193
209
 
194
- # If the zip code '-', we retain just the first part alone.
195
- zip = zip.split('-')[0]
210
+ if zip.length < 2
211
+ return nil
212
+ end
196
213
 
197
- if zip.length < 2
198
- return nil
214
+ return zip
199
215
  end
200
216
 
201
- return zip
202
- end
217
+ # Boolean method which checks if a given number is represented in international format
218
+ # @param [String] phone_number that has to be tested.
219
+ # @return [TrueClass | FalseClass] boolean value representing if a number is international
220
+ def self.is_international_number?(phone_number)
221
+
222
+ # Drop upto 2 leading 0s from the number
223
+ phone_number = phone_number.gsub(PHONE_NUMBER_DROP_PREFIX_ZEROS, '')
203
224
 
204
- # Boolean method which checks if a given number is represented in international format
205
- # @param [String] phone_number that has to be tested.
206
- # @return [TrueClass | FalseClass] boolean value representing if a number is international
207
- def self.is_international_number?(phone_number)
225
+ if phone_number.start_with?('0')
226
+ return false;
227
+ end
208
228
 
209
- # Drop upto 2 leading 0s from the number
210
- phone_number = phone_number.gsub(PHONE_NUMBER_DROP_PREFIX_ZEROS, '')
229
+ if phone_number.start_with?('1') && US_PHONE_NUMBER_REGEX.match(phone_number) != nil
230
+ return false;
231
+ end
232
+
233
+ if INTL_PHONE_NUMBER_REGEX.match(phone_number) != nil
234
+ return true;
235
+ end
211
236
 
212
- if phone_number.start_with?('0')
213
237
  return false;
214
238
  end
215
239
 
216
- if phone_number.start_with?('1') && US_PHONE_NUMBER_REGEX.match(phone_number) != nil
217
- return false;
240
+ def self.normalize_f5(input)
241
+ input[0, 5]
218
242
  end
219
243
 
220
- if INTL_PHONE_NUMBER_REGEX.match(phone_number) != nil
221
- return true;
244
+ def self.normalize_fi(fi)
245
+ fi[0, 1]
222
246
  end
223
247
 
224
- return false;
225
- end
248
+ def self.normalize_dobd(dobd)
249
+ if dobd.length == 1
250
+ dobd = '0' + dobd
251
+ end
252
+
253
+ dobd_int = dobd.to_i
254
+ if dobd.length > 2 or dobd_int < 1 or dobd_int > 31
255
+ raise ArgumentError.new("Invalid dobd format: '#{dobd}'. Please pass in a valid date of birth day in 'DD' format.")
256
+ end
226
257
 
258
+ return dobd
259
+ end
260
+
261
+ def self.normalize_dobm(dobm)
262
+ if dobm.length == 1
263
+ dobm = '0' + dobm
264
+ end
265
+
266
+ dobm_int = dobm.to_i
267
+ if dobm.length > 2 or dobm_int < 1 or dobm_int > 12
268
+ raise ArgumentError.new("Invalid dobm format: '#{dobm}'. Please pass in a valid date of birth month in 'MM' format.")
269
+ end
270
+
271
+ return dobm
272
+ end
273
+
274
+ def self.normalize_doby(doby)
275
+ unless doby.match("^[0-9]{4}$")
276
+ raise ArgumentError.new("Invalid doby format: '#{doby}'. Please pass in a valid birth year in 'YYYY' format.")
277
+ end
278
+ doby
279
+ end
280
+ end
227
281
  end
228
282
  end
@@ -29,7 +29,6 @@ module FacebookAds
29
29
 
30
30
  field :id, 'string'
31
31
  field :page, 'Page'
32
- has_no_delete
33
32
 
34
33
  end
35
34
  end
@@ -29,9 +29,15 @@ module FacebookAds
29
29
  ROLE = [
30
30
  "ADMIN",
31
31
  "ADS_RIGHTS_REVIEWER",
32
+ "DEVELOPER",
32
33
  "EMPLOYEE",
33
34
  "FINANCE_ANALYST",
34
35
  "FINANCE_EDITOR",
36
+ "PARTNER_CENTER_ADMIN",
37
+ "PARTNER_CENTER_ANALYST",
38
+ "PARTNER_CENTER_EDUCATION",
39
+ "PARTNER_CENTER_MARKETING",
40
+ "PARTNER_CENTER_OPERATIONS",
35
41
  ]
36
42
 
37
43
 
@@ -98,6 +98,7 @@ module FacebookAds
98
98
  field :income, { list: 'IdName' }
99
99
  field :industries, { list: 'IdName' }
100
100
  field :instagram_positions, { list: 'string' }
101
+ field :instream_video_skippable_excluded, 'bool'
101
102
  field :interested_in, { list: 'int' }
102
103
  field :interests, { list: 'IdName' }
103
104
  field :is_whatsapp_destination_ad, 'bool'
@@ -25,9 +25,9 @@ module FacebookAds
25
25
  # on github and we'll fix in our codegen framework. We'll not be able to accept
26
26
  # pull request for this class.
27
27
 
28
- class CreativeAssetTag < AdObject
28
+ class TargetingRelaxation < AdObject
29
29
 
30
- field :name, 'string'
30
+ field :lookalike, 'int'
31
31
  has_no_id
32
32
  has_no_get
33
33
  has_no_post