Class: FacebookAds::ServerSide::Util

Inherits:
Object
  • Object
show all
Defined in:
lib/facebook_ads/ad_objects/server_side/util.rb

Constant Summary collapse

PHONE_NUMBER_IGNORE_CHAR_SET =
/[\-\s\(\)]+/
PHONE_NUMBER_DROP_PREFIX_ZEROS =
/^\+?0{0,2}/
US_PHONE_NUMBER_REGEX =
/^1\(?\d{3}\)?\d{7}$/
INTL_PHONE_NUMBER_REGEX =
/^\d{1,4}\(?\d{2,3}\)?\d{4,}$/
EMAIL_REGEX =

RFC 2822 for email format

/\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i

Class Method Summary collapse

Class Method Details

.is_already_hashed?(input) ⇒ TrueClass|FalseClass

Boolean method which checks if a input is already hashed with MD5 or SHA256

Parameters:

  • input (String)

    Input string that is to be validated

Returns:

  • (TrueClass|FalseClass)

    representing whether the value is hashed



119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/facebook_ads/ad_objects/server_side/util.rb', line 119

def self.is_already_hashed?(input)

	# We support Md5 and SHA256, and highly recommend users to use SHA256 for hashing PII keys.
	md5_match = /^[a-f0-9]{32}$/.match(input)
	sha256_match = /^[a-f0-9]{64}$/.match(input)

	if md5_match != nil or sha256_match != nil
		return true
	end

	return false
end

.is_international_number?(phone_number) ⇒ TrueClass | FalseClass

Boolean method which checks if a given number is represented in international format

Parameters:

  • phone_number (String)

    that has to be tested.

Returns:

  • (TrueClass | FalseClass)

    boolean value representing if a number is international



239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
# File 'lib/facebook_ads/ad_objects/server_side/util.rb', line 239

def self.is_international_number?(phone_number)

	# Drop upto 2 leading 0s from the number
	phone_number = phone_number.gsub(PHONE_NUMBER_DROP_PREFIX_ZEROS, '')

	if phone_number.start_with?('0')
		return false;
	end

	if phone_number.start_with?('1') && US_PHONE_NUMBER_REGEX.match(phone_number) != nil
		return false;
	end

	if INTL_PHONE_NUMBER_REGEX.match(phone_number) != nil
		return true;
	end

	return false;
end

.normalize(input, field_type) ⇒ String

Normalizes the input string given the field_type

Parameters:

  • input (String)

    Input string that needs to be normalized

  • field_type (String)

    Type/Key for the value provided

Returns:

  • (String)

    Normalized value for the input and field_type.



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/facebook_ads/ad_objects/server_side/util.rb', line 54

def self.normalize(input, field_type)

	if input.nil? or field_type.nil?
		return nil;
	end

	input = input.strip.downcase

	# If the data is already hashed, we by-pass input normalization
	if is_already_hashed?(input) == true
		return input
	end

	normalized_input = input;

	case field_type
	when 'action_source'
		return normalize_action_source input
	when 'country'
		normalized_input = normalize_country input
	when 'ct'
		normalized_input = normalize_city input
	when 'currency'
		return normalize_currency input
	when 'delivery_category'
		return normalize_delivery_category input
	when 'em'
		normalized_input = normalize_email input
	when 'ge'
		normalized_input = normalize_gender input
	when 'ph'
		normalized_input = normalize_phone input
	when 'st'
		normalized_input = normalize_state input
	when 'zp'
		normalized_input = normalize_zip input
	when 'f5first'
		normalized_input = normalize_f5 input
	when 'f5last'
		normalized_input = normalize_f5 input
	when 'fi'
		normalized_input = normalize_fi input
	when 'dobd'
		normalized_input = normalize_dobd input
	when 'dobm'
		normalized_input = normalize_dobm input
	when 'doby'
		normalized_input = normalize_doby input
	end

	normalized_input = sha256Hash normalized_input

	return normalized_input
end

.normalize_action_source(action_source) ⇒ Object

Normalizes the input action_source and returns valid value (or throw exception if invalid).



311
312
313
314
315
316
317
318
319
320
# File 'lib/facebook_ads/ad_objects/server_side/util.rb', line 311

def self.normalize_action_source(action_source)
	unless FacebookAds::ServerSide::ActionSource.include?(action_source)
		values = FacebookAds::ServerSide::ActionSource.to_a.join(',')
		raise ArgumentError.new(
			"Invalid action_source passed: #{action_source}. Please use one of the defined values: #{values}"
		)
	end

	action_source
end

.normalize_array(input_array, field_type) ⇒ Array<String>

Normalizes the input array of strings given the field_type

Parameters:

  • input (Array<String>)

    string array that needs to be normalized

  • field_type (String)

    Type/Key for the value provided

Returns:

  • (Array<String>)

    Normalized values for the input and field_type.



39
40
41
42
43
44
45
46
47
48
# File 'lib/facebook_ads/ad_objects/server_side/util.rb', line 39

def self.normalize_array(input_array, field_type)
	return nil unless input_array.is_a?(Enumerable)
	return nil if input_array.empty?
	return nil unless input_array.all?{|value| value.is_a?(String)}

	input_array
		.map{|value| self.normalize(value, field_type)}
		.to_set
		.to_a
end

.normalize_city(city) ⇒ Object

Normalizes the given city and returns acceptable hashed city value



146
147
148
149
150
151
152
# File 'lib/facebook_ads/ad_objects/server_side/util.rb', line 146

def self.normalize_city(city)

     # Remove commonly occuring characters from city name.
	city = city.gsub(/[0-9.\s\-()]/,'')

	return city
end

.normalize_country(country) ⇒ Object

Normalizes the given country code and returns acceptable hashed country ISO code



133
134
135
136
137
138
139
140
141
142
143
# File 'lib/facebook_ads/ad_objects/server_side/util.rb', line 133

def self.normalize_country(country)

	# Replace unwanted characters and retain only alpha characters bounded for ISO code.
	country = country.gsub(/[^a-z]/,'')
	iso_country = ISO3166::Country.search(country)
	if iso_country == nil
		raise ArgumentError, "Invalid format for country:'" + country + "'.Please follow ISO 2-letter ISO 3166-1 standard for representing country. eg: us"
	end

	return  country
end

.normalize_currency(currency) ⇒ Object

Normalizes the given currency code and returns acceptable hashed currency ISO code



155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/facebook_ads/ad_objects/server_side/util.rb', line 155

def self.normalize_currency(currency)

	# Retain only alpha characters bounded for ISO code.
	currency = currency.gsub(/[^a-z]/,'')

	iso_currency = Money::Currency.find(currency)
	if iso_currency == nil
		raise ArgumentError, "Invalid format for currency:'" + currency + "'.Please follow ISO 3-letter ISO 4217 standard for representing currency. Eg: usd"
	end

	return currency;
end

.normalize_delivery_category(delivery_category) ⇒ Object

Normalizes the input delivery category and returns valid value (or throw exception if invalid).



301
302
303
304
305
306
307
308
# File 'lib/facebook_ads/ad_objects/server_side/util.rb', line 301

def self.normalize_delivery_category(delivery_category)

	unless FacebookAds::ServerSide::DeliveryCategory.include?(delivery_category)
		raise ArgumentError.new("Invalid delivery_category passed: " + delivery_category + ". Please use one of the defined values #{FacebookAds::ServerSide::DeliveryCategory.to_a.join(',')}" )
	end

	delivery_category;
end

.normalize_dobd(dobd) ⇒ Object



267
268
269
270
271
272
273
274
275
276
277
278
# File 'lib/facebook_ads/ad_objects/server_side/util.rb', line 267

def self.normalize_dobd(dobd)
	if dobd.length == 1
		dobd = '0' + dobd
	end

	dobd_int = dobd.to_i
	if dobd.length > 2 or dobd_int < 1 or dobd_int > 31
		raise ArgumentError.new("Invalid dobd format: '#{dobd}'. Please pass in a valid date of birth day in 'DD' format.")
	end

	return dobd
end

.normalize_dobm(dobm) ⇒ Object



280
281
282
283
284
285
286
287
288
289
290
291
# File 'lib/facebook_ads/ad_objects/server_side/util.rb', line 280

def self.normalize_dobm(dobm)
	if dobm.length == 1
		dobm = '0' + dobm
	end

	dobm_int = dobm.to_i
	if dobm.length > 2 or dobm_int < 1 or dobm_int > 12
		raise ArgumentError.new("Invalid dobm format: '#{dobm}'. Please pass in a valid date of birth month in 'MM' format.")
	end

	return dobm
end

.normalize_doby(doby) ⇒ Object



293
294
295
296
297
298
# File 'lib/facebook_ads/ad_objects/server_side/util.rb', line 293

def self.normalize_doby(doby)
	unless doby.match("^[0-9]{4}$")
		raise ArgumentError.new("Invalid doby format: '#{doby}'. Please pass in a valid birth year in 'YYYY' format.")
	end
	doby
end

.normalize_email(email) ⇒ Object

Normalizes the given email and returns acceptable hashed email value



169
170
171
172
173
174
175
176
# File 'lib/facebook_ads/ad_objects/server_side/util.rb', line 169

def self.normalize_email(email)

	if EMAIL_REGEX.match(email) == nil
		raise ArgumentError, "Invalid email format for the passed email: '#{email}'. Please check the passed email format."
	end

	return email
end

.normalize_f5(input) ⇒ Object



259
260
261
# File 'lib/facebook_ads/ad_objects/server_side/util.rb', line 259

def self.normalize_f5(input)
	input[0, 5]
end

.normalize_fi(fi) ⇒ Object



263
264
265
# File 'lib/facebook_ads/ad_objects/server_side/util.rb', line 263

def self.normalize_fi(fi)
	fi[0, 1]
end

.normalize_gender(gender) ⇒ Object

Normalizes the given gender and returns acceptable hashed gender value



179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'lib/facebook_ads/ad_objects/server_side/util.rb', line 179

def self.normalize_gender(gender)

	# Replace extra characters with space, to bound under alpha characters set.
	gender = gender.gsub(/[^a-z]/,'')

	case gender
	when 'female' , 'f'
		gender = 'f'
	when 'male' , 'm'
		gender = 'm'
	else
		return nil
	end

	return gender
end

.normalize_phone(phone) ⇒ Object

Normalizes the given phone and returns acceptable hashed phone value



197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
# File 'lib/facebook_ads/ad_objects/server_side/util.rb', line 197

def self.normalize_phone(phone)

	# Drop the spaces, hyphen and parenthesis from the Phone Number
	normalized_phone = phone.gsub(PHONE_NUMBER_IGNORE_CHAR_SET, '')

	if(is_international_number?(normalized_phone))
		normalized_phone = normalized_phone.gsub(PHONE_NUMBER_DROP_PREFIX_ZEROS, '')
	end

	if normalized_phone.length < 7 || normalized_phone.length > 16
		return nil;
	end

	return normalized_phone
end

.normalize_state(state) ⇒ Object

Normalizes the given state and returns acceptable hashed state value



214
215
216
217
218
# File 'lib/facebook_ads/ad_objects/server_side/util.rb', line 214

def self.normalize_state(state)
	state = state.gsub(/[0-9.\s\-()]/,'')

	return state
end

.normalize_zip(zip) ⇒ Object

Normalizes the given zip and returns acceptable hashed zip code value



221
222
223
224
225
226
227
228
229
230
231
232
233
234
# File 'lib/facebook_ads/ad_objects/server_side/util.rb', line 221

def self.normalize_zip(zip)

	# Remove spaces from the Postal code
	zip = zip.gsub(/[\s]/,'')

	# If the zip code '-', we retain just the first part alone.
	zip = zip.split('-')[0]

	if zip.length < 2
		return nil
	end

	return zip
end

.sha256Hash(input) ⇒ String

Returns SHA 256 hash of input string.

Returns:

  • (String)

    SHA 256 hash of input string



110
111
112
113
114
# File 'lib/facebook_ads/ad_objects/server_side/util.rb', line 110

def self.sha256Hash(input)
	unless input.nil?
		Digest::SHA256.hexdigest input
	end
end