retreaverjs-rails 0.0.12 → 0.1.0
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/Gruntfile.js +1 -0
- data/config/README +1 -1
- data/config/jsdocs.json +1 -0
- data/lib/retreaverjs/compile.rb +5 -5
- data/lib/retreaverjs/rails/version.rb +1 -1
- data/src/retreaver/base/model.js +1 -1
- data/src/retreaver/campaign.js +1 -1
- data/src/retreaver.js +28 -0
- data/vendor/assets/javascripts/retreaver.js +1179 -0
- data/vendor/assets/javascripts/retreaver.min.js +2 -0
- data/vendor/documentation/javascript/v1/Retreaver.Campaign.html +425 -0
- data/vendor/documentation/javascript/v1/Retreaver.Number.html +1415 -0
- data/vendor/documentation/javascript/v1/Retreaver.Retreaver.html +146 -0
- data/vendor/documentation/javascript/v1/Retreaver.context.Retreaver.html +146 -0
- data/vendor/documentation/javascript/v1/Retreaver.html +304 -0
- data/vendor/documentation/javascript/v1/campaign.js.html +157 -0
- data/vendor/documentation/javascript/v1/global.html +232 -0
- data/vendor/documentation/javascript/v1/index.html +67 -0
- data/vendor/documentation/javascript/v1/number.js.html +255 -0
- data/vendor/documentation/javascript/v1/retreaver.js.html +78 -0
- data/vendor/documentation/javascript/v1/scripts/linenumber.js +17 -0
- data/vendor/documentation/javascript/v1/scripts/prettify/Apache-License-2.0.txt +202 -0
- data/vendor/documentation/javascript/v1/scripts/prettify/lang-css.js +2 -0
- data/vendor/documentation/javascript/v1/scripts/prettify/prettify.js +28 -0
- data/vendor/documentation/javascript/v1/styles/jsdoc-default.css +290 -0
- data/vendor/documentation/javascript/v1/styles/prettify-jsdoc.css +111 -0
- data/vendor/documentation/javascript/v1/styles/prettify-tomorrow.css +132 -0
- metadata +22 -2
@@ -0,0 +1,1179 @@
|
|
1
|
+
(function (context) {
|
2
|
+
/**
|
3
|
+
* @namespace Retreaver
|
4
|
+
*/
|
5
|
+
var Retreaver = {
|
6
|
+
|
7
|
+
/**
|
8
|
+
* Configure the retreaver client library.
|
9
|
+
* @function configure
|
10
|
+
* @memberof Retreaver
|
11
|
+
* @param {Object} options
|
12
|
+
* @param {String} options.host - Retreaver API Host
|
13
|
+
* @example
|
14
|
+
* Retreaver.configure({host: 'api.retreaver.com'});
|
15
|
+
*
|
16
|
+
*/
|
17
|
+
configure: function (options) {
|
18
|
+
var params = {
|
19
|
+
addr: options.host,
|
20
|
+
http_prefix: 'http',
|
21
|
+
urlregex: "/\\/\\/[^\\/]*\\/(.*)/"
|
22
|
+
};
|
23
|
+
window.Retreaver._connection = new Retreaver.Base.Request(params);
|
24
|
+
}
|
25
|
+
};
|
26
|
+
context.Retreaver = Retreaver;
|
27
|
+
|
28
|
+
})(window);
|
29
|
+
;(function () {
|
30
|
+
// ensure namespace is present
|
31
|
+
if (typeof window.Retreaver === 'undefined') window.Retreaver = {};
|
32
|
+
var Base = {};
|
33
|
+
// define helpers
|
34
|
+
Base.assert_required_keys = function () {
|
35
|
+
var args = Array.prototype.slice.call(arguments);
|
36
|
+
var object = args.shift();
|
37
|
+
for (var i = 0; i < args.length; i++) {
|
38
|
+
var key = args[i];
|
39
|
+
if (typeof object === 'undefined' || typeof object[key] === 'undefined') {
|
40
|
+
throw "ArgumentError: Required keys are not defined: " + args.join(', ');
|
41
|
+
}
|
42
|
+
}
|
43
|
+
return object;
|
44
|
+
};
|
45
|
+
Base.merge = function (obj1, obj2) {
|
46
|
+
for (var p in obj2) {
|
47
|
+
try {
|
48
|
+
if (obj2[p].constructor == Object) {
|
49
|
+
obj1[p] = Base.merge(obj1[p], obj2[p]);
|
50
|
+
} else {
|
51
|
+
obj1[p] = obj2[p];
|
52
|
+
}
|
53
|
+
} catch (e) {
|
54
|
+
obj1[p] = obj2[p];
|
55
|
+
}
|
56
|
+
}
|
57
|
+
return obj1;
|
58
|
+
};
|
59
|
+
Base.isArray = function (arg) {
|
60
|
+
return Object.prototype.toString.call(arg) === '[object Array]';
|
61
|
+
};
|
62
|
+
Base.ieVersion = function () {
|
63
|
+
if (Base._ieVersion == null) {
|
64
|
+
Base._ieVersion = (function () {
|
65
|
+
var v = 3,
|
66
|
+
div = document.createElement('div'),
|
67
|
+
all = div.getElementsByTagName('i');
|
68
|
+
|
69
|
+
while (
|
70
|
+
div.innerHTML = '<!--[if gt IE ' + (++v) + ']><i></i><![endif]-->',
|
71
|
+
all[0]
|
72
|
+
) {
|
73
|
+
}
|
74
|
+
return v > 4 ? v : false;
|
75
|
+
}());
|
76
|
+
}
|
77
|
+
if (Base._ieVersion == 6 || Base._ieVersion == 7) {
|
78
|
+
if (Retreaver['easyxdm_loaded'] == null) Retreaver['easyxdm_loaded'] = false;
|
79
|
+
}
|
80
|
+
return Base._ieVersion;
|
81
|
+
};
|
82
|
+
Retreaver.Base = Base;
|
83
|
+
})();;// https://github.com/evertton/cookiejs
|
84
|
+
(function (f) {
|
85
|
+
var a = function (b, c, d) {
|
86
|
+
return 1 === arguments.length ? a.get(b) : a.set(b, c, d)
|
87
|
+
};
|
88
|
+
a._document = document;
|
89
|
+
a._navigator = navigator;
|
90
|
+
a.defaults = {path: "/"};
|
91
|
+
a.get = function (b) {
|
92
|
+
a._cachedDocumentCookie !== a._document.cookie && a._renewCache();
|
93
|
+
return a._cache[b]
|
94
|
+
};
|
95
|
+
a.set = function (b, c, d) {
|
96
|
+
d = a._getExtendedOptions(d);
|
97
|
+
a._document.cookie = a._generateCookieString(b, c, d);
|
98
|
+
return a
|
99
|
+
};
|
100
|
+
a._getExtendedOptions = function (b) {
|
101
|
+
return{path: b && b.path || a.defaults.path, domain: b && b.domain || a.defaults.domain, secure: b && b.secure !== f ? b.secure :
|
102
|
+
a.defaults.secure}
|
103
|
+
};
|
104
|
+
a._isValidDate = function (a) {
|
105
|
+
return"[object Date]" === Object.prototype.toString.call(a) && !isNaN(a.getTime())
|
106
|
+
};
|
107
|
+
a._generateCookieString = function (a, c, d) {
|
108
|
+
a = encodeURIComponent(a);
|
109
|
+
c = (c + "").replace(/[^!#$&-+\--:<-\[\]-~]/g, encodeURIComponent);
|
110
|
+
d = d || {};
|
111
|
+
a = a + "=" + c + (d.path ? ";path=" + d.path : "");
|
112
|
+
a += d.domain ? ";domain=" + d.domain : "";
|
113
|
+
return a += d.secure ? ";secure" : ""
|
114
|
+
};
|
115
|
+
a._getCookieObjectFromString = function (b) {
|
116
|
+
var c = {};
|
117
|
+
b = b ? b.split("; ") : [];
|
118
|
+
for (var d = 0; d < b.length; d++) {
|
119
|
+
var e = a._getKeyValuePairFromCookieString(b[d]);
|
120
|
+
c[e.key] === f && (c[e.key] = e.value)
|
121
|
+
}
|
122
|
+
return c
|
123
|
+
};
|
124
|
+
a._getKeyValuePairFromCookieString = function (a) {
|
125
|
+
var c = a.indexOf("="), c = 0 > c ? a.length : c;
|
126
|
+
return{key: decodeURIComponent(a.substr(0, c)), value: decodeURIComponent(a.substr(c + 1))}
|
127
|
+
};
|
128
|
+
a._renewCache = function () {
|
129
|
+
a._cache = a._getCookieObjectFromString(a._document.cookie);
|
130
|
+
a._cachedDocumentCookie = a._document.cookie
|
131
|
+
};
|
132
|
+
a._areEnabled = function () {
|
133
|
+
return a._navigator.cookieEnabled || "1" === a.set("cookies.js", 1).get("cookies.js")
|
134
|
+
};
|
135
|
+
a.enabled = a._areEnabled();
|
136
|
+
"function" === typeof define &&
|
137
|
+
define.amd ? define(function () {
|
138
|
+
return a
|
139
|
+
}) : "undefined" !== typeof exports ? ("undefined" !== typeof module && module.exports && (exports = module.exports = a), exports.Cookies = a) : a;
|
140
|
+
Retreaver.Base.Cookies = a;
|
141
|
+
})();;// http://www.webtoolkit.info/javascript-base64.html#.U-qwzYBdUwQ
|
142
|
+
(function () {
|
143
|
+
var Base64 = {
|
144
|
+
_keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
|
145
|
+
};
|
146
|
+
// public method for encoding
|
147
|
+
Base64.encode = function (input) {
|
148
|
+
var output = "";
|
149
|
+
var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
|
150
|
+
var i = 0;
|
151
|
+
|
152
|
+
input = Base64._utf8_encode(input);
|
153
|
+
|
154
|
+
while (i < input.length) {
|
155
|
+
|
156
|
+
chr1 = input.charCodeAt(i++);
|
157
|
+
chr2 = input.charCodeAt(i++);
|
158
|
+
chr3 = input.charCodeAt(i++);
|
159
|
+
|
160
|
+
enc1 = chr1 >> 2;
|
161
|
+
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
|
162
|
+
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
|
163
|
+
enc4 = chr3 & 63;
|
164
|
+
|
165
|
+
if (isNaN(chr2)) {
|
166
|
+
enc3 = enc4 = 64;
|
167
|
+
} else if (isNaN(chr3)) {
|
168
|
+
enc4 = 64;
|
169
|
+
}
|
170
|
+
output = output +
|
171
|
+
Base64._keyStr.charAt(enc1) + Base64._keyStr.charAt(enc2) +
|
172
|
+
Base64._keyStr.charAt(enc3) + Base64._keyStr.charAt(enc4);
|
173
|
+
|
174
|
+
}
|
175
|
+
return output;
|
176
|
+
};
|
177
|
+
Base64.decode = function (input) {
|
178
|
+
var output = "";
|
179
|
+
var chr1, chr2, chr3;
|
180
|
+
var enc1, enc2, enc3, enc4;
|
181
|
+
var i = 0;
|
182
|
+
|
183
|
+
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
|
184
|
+
|
185
|
+
while (i < input.length) {
|
186
|
+
|
187
|
+
enc1 = Base64._keyStr.indexOf(input.charAt(i++));
|
188
|
+
enc2 = Base64._keyStr.indexOf(input.charAt(i++));
|
189
|
+
enc3 = Base64._keyStr.indexOf(input.charAt(i++));
|
190
|
+
enc4 = Base64._keyStr.indexOf(input.charAt(i++));
|
191
|
+
|
192
|
+
chr1 = (enc1 << 2) | (enc2 >> 4);
|
193
|
+
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
|
194
|
+
chr3 = ((enc3 & 3) << 6) | enc4;
|
195
|
+
|
196
|
+
output = output + String.fromCharCode(chr1);
|
197
|
+
|
198
|
+
if (enc3 != 64) {
|
199
|
+
output = output + String.fromCharCode(chr2);
|
200
|
+
}
|
201
|
+
if (enc4 != 64) {
|
202
|
+
output = output + String.fromCharCode(chr3);
|
203
|
+
}
|
204
|
+
|
205
|
+
}
|
206
|
+
|
207
|
+
output = Base64._utf8_decode(output);
|
208
|
+
|
209
|
+
return output;
|
210
|
+
};
|
211
|
+
Base64._utf8_encode = function (string) {
|
212
|
+
//REGEX_2: /\r\n/g NEWLINE: "\n"
|
213
|
+
string = string.replace(eval("/\\r\\n/g"),eval("String('\\n')"));
|
214
|
+
var utftext = "";
|
215
|
+
|
216
|
+
for (var n = 0; n < string.length; n++) {
|
217
|
+
|
218
|
+
var c = string.charCodeAt(n);
|
219
|
+
|
220
|
+
if (c < 128) {
|
221
|
+
utftext += String.fromCharCode(c);
|
222
|
+
}
|
223
|
+
else if ((c > 127) && (c < 2048)) {
|
224
|
+
utftext += String.fromCharCode((c >> 6) | 192);
|
225
|
+
utftext += String.fromCharCode((c & 63) | 128);
|
226
|
+
}
|
227
|
+
else {
|
228
|
+
utftext += String.fromCharCode((c >> 12) | 224);
|
229
|
+
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
|
230
|
+
utftext += String.fromCharCode((c & 63) | 128);
|
231
|
+
}
|
232
|
+
|
233
|
+
}
|
234
|
+
|
235
|
+
return utftext;
|
236
|
+
};
|
237
|
+
Base64._utf8_decode = function (utftext) {
|
238
|
+
var string = "";
|
239
|
+
var i = 0;
|
240
|
+
var c = c1 = c2 = 0;
|
241
|
+
|
242
|
+
while (i < utftext.length) {
|
243
|
+
|
244
|
+
c = utftext.charCodeAt(i);
|
245
|
+
|
246
|
+
if (c < 128) {
|
247
|
+
string += String.fromCharCode(c);
|
248
|
+
i++;
|
249
|
+
}
|
250
|
+
else if ((c > 191) && (c < 224)) {
|
251
|
+
c2 = utftext.charCodeAt(i + 1);
|
252
|
+
string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
|
253
|
+
i += 2;
|
254
|
+
}
|
255
|
+
else {
|
256
|
+
c2 = utftext.charCodeAt(i + 1);
|
257
|
+
c3 = utftext.charCodeAt(i + 2);
|
258
|
+
string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
|
259
|
+
i += 3;
|
260
|
+
}
|
261
|
+
|
262
|
+
}
|
263
|
+
return string;
|
264
|
+
};
|
265
|
+
Retreaver.Base.Base64 = Base64;
|
266
|
+
})();;(function () {
|
267
|
+
// Dependencies
|
268
|
+
var Base = Retreaver.Base;
|
269
|
+
/**
|
270
|
+
* @constructor
|
271
|
+
* @memberof Retreaver.Base
|
272
|
+
* @param {Object} config - Configuration hash
|
273
|
+
* @param {String} config.type - The data type
|
274
|
+
* @param {Numeric} config.primary_key - The primary_key
|
275
|
+
*/
|
276
|
+
var Data = function (config) {
|
277
|
+
|
278
|
+
function initialize() {
|
279
|
+
Base.assert_required_keys(config, 'type', 'primary_key');
|
280
|
+
if (typeof Retreaver.Base.Data._store[config.type] === 'undefined') {
|
281
|
+
Retreaver.Base.Data._store[config.type] = {};
|
282
|
+
}
|
283
|
+
if (typeof Retreaver.Base.Data._store[config.type][config.primary_key] === 'undefined') {
|
284
|
+
Retreaver.Base.Data._store[config.type][config.primary_key] = {};
|
285
|
+
}
|
286
|
+
}
|
287
|
+
|
288
|
+
var self = this;
|
289
|
+
|
290
|
+
/**
|
291
|
+
* Request data from the host
|
292
|
+
* @memberOf Retreaver.Base.Data
|
293
|
+
* @function get
|
294
|
+
* @instance
|
295
|
+
* @param {String} key - The key to retrieve
|
296
|
+
* @returns {*}
|
297
|
+
*/
|
298
|
+
self.get = function () {
|
299
|
+
var output = {};
|
300
|
+
if (typeof arguments[0] === 'undefined') {
|
301
|
+
output = Retreaver.Base.Data._store[config.type][config.primary_key];
|
302
|
+
} else if (arguments.length === 1) {
|
303
|
+
output = Retreaver.Base.Data._store[config.type][config.primary_key][arguments[0]];
|
304
|
+
} else {
|
305
|
+
for (var i = 0; i < arguments.length; i++) {
|
306
|
+
var key = arguments[i];
|
307
|
+
output[key] = Retreaver.Base.Data._store[config.type][config.primary_key][key];
|
308
|
+
}
|
309
|
+
}
|
310
|
+
return output;
|
311
|
+
};
|
312
|
+
|
313
|
+
/**
|
314
|
+
* Request data from the host
|
315
|
+
* @memberOf Retreaver.Base.Data
|
316
|
+
* @function set
|
317
|
+
* @instance
|
318
|
+
* @param {String} key - The key to retrieve
|
319
|
+
* @param {String} value - The value to assign
|
320
|
+
* @returns {*}
|
321
|
+
*/
|
322
|
+
self.set = function (key, value) {
|
323
|
+
Retreaver.Base.Data._store[config.type][config.primary_key][key] = value;
|
324
|
+
return value;
|
325
|
+
};
|
326
|
+
|
327
|
+
/**
|
328
|
+
* Merge data
|
329
|
+
* @memberOf Retreaver.Base.Data
|
330
|
+
* @function set
|
331
|
+
* @instance
|
332
|
+
* @param {String} object - The object to merge
|
333
|
+
* @returns {*}
|
334
|
+
*/
|
335
|
+
self.merge = function (object) {
|
336
|
+
for (var key in object) {
|
337
|
+
Retreaver.Base.Data._store[config.type][config.primary_key][key] = object[key];
|
338
|
+
}
|
339
|
+
return object;
|
340
|
+
};
|
341
|
+
|
342
|
+
initialize();
|
343
|
+
};
|
344
|
+
Data._store = {};
|
345
|
+
Retreaver.Base.Data = Data;
|
346
|
+
})();;(function () {
|
347
|
+
// Dependencies
|
348
|
+
var Base = Retreaver.Base;
|
349
|
+
var Data = Retreaver.Base.Data;
|
350
|
+
|
351
|
+
/**
|
352
|
+
* @constructor
|
353
|
+
* @memberof Retreaver.Base
|
354
|
+
*/
|
355
|
+
var Model = function () {
|
356
|
+
|
357
|
+
this.api_host_uri = '/api/v1/';
|
358
|
+
this.type = 'model';
|
359
|
+
|
360
|
+
this.primary_key = function (primary_key) {
|
361
|
+
return Model.primary_key(this.type, primary_key);
|
362
|
+
};
|
363
|
+
|
364
|
+
this.store = function (data) {
|
365
|
+
// do we have data to store?
|
366
|
+
if (typeof(data) !== 'undefined') {
|
367
|
+
// does the data contain the required primary_key?
|
368
|
+
var key = this.primary_key();
|
369
|
+
if (typeof(data[key]) === 'undefined') {
|
370
|
+
throw("ArgumentError: Expected to receive primary_key " + key);
|
371
|
+
}
|
372
|
+
// has a store been initialized?
|
373
|
+
else if (typeof(this._store) === 'undefined') {
|
374
|
+
this._store = new Retreaver.Base.Data({type: this.type, primary_key: data[key] });
|
375
|
+
}
|
376
|
+
// merge the data
|
377
|
+
this._store.merge(data);
|
378
|
+
// update visitor is token present
|
379
|
+
Model.update_visitor_id(data);
|
380
|
+
}
|
381
|
+
return this._store;
|
382
|
+
};
|
383
|
+
|
384
|
+
this.get_data = function (path, callback) {
|
385
|
+
return this.connection().getJSON(this.api_host_uri + path, null, [Model.update, callback], this);
|
386
|
+
};
|
387
|
+
|
388
|
+
this.post_data = function (path, data, callback) {
|
389
|
+
return this.connection().postJSON(this.api_host_uri + path, data, [Model.update, callback], this);
|
390
|
+
};
|
391
|
+
|
392
|
+
this.set = function () {
|
393
|
+
if (typeof(this["set_" + arguments[0]]) === 'function') {
|
394
|
+
arguments[1] = this["set_" + arguments[0]].apply(this, [arguments[1]]);
|
395
|
+
}
|
396
|
+
return this._store.set.apply(this, arguments);
|
397
|
+
};
|
398
|
+
this.get = function () {
|
399
|
+
return this._store.get.apply(this, arguments);
|
400
|
+
};
|
401
|
+
this.connection = function () {
|
402
|
+
return Retreaver.Base.Request.connection();
|
403
|
+
};
|
404
|
+
};
|
405
|
+
Model.inflections = {
|
406
|
+
'number': 'numbers',
|
407
|
+
'campaign': 'campaigns'
|
408
|
+
};
|
409
|
+
Model.update = function (data) {
|
410
|
+
for (var key in data) {
|
411
|
+
var type = key;
|
412
|
+
var value = data[key];
|
413
|
+
if (typeof Model.inflections[key] !== 'undefined') {
|
414
|
+
type = Model.inflections[key];
|
415
|
+
}
|
416
|
+
if (typeof Data._store[type] !== 'undefined') {
|
417
|
+
if (Base.isArray(value)) {
|
418
|
+
for (var i = 0; i < value.length; i++) {
|
419
|
+
Model.update_record(type, value[i]);
|
420
|
+
}
|
421
|
+
} else {
|
422
|
+
Model.update_record(type, value[i]);
|
423
|
+
}
|
424
|
+
}
|
425
|
+
}
|
426
|
+
return data;
|
427
|
+
};
|
428
|
+
Model.update_record = function (type, record) {
|
429
|
+
// update visitor is token present
|
430
|
+
Model.update_visitor_id(record);
|
431
|
+
// update data store
|
432
|
+
if (typeof record.id !== 'undefined') {
|
433
|
+
var primary_key = Model.primary_key(type);
|
434
|
+
for (var key in record) {
|
435
|
+
Retreaver.Base.Data._store[type][record[primary_key]][key] = record[key];
|
436
|
+
}
|
437
|
+
return true
|
438
|
+
} else {
|
439
|
+
return false
|
440
|
+
}
|
441
|
+
return record;
|
442
|
+
};
|
443
|
+
Model.update_visitor_id = function (record) {
|
444
|
+
if (typeof(record) !== 'undefined' && typeof(record.visitor_id) !== 'undefined') {
|
445
|
+
Retreaver.Base.Cookies.set('CallPixels-vid', record.visitor_id);
|
446
|
+
}
|
447
|
+
};
|
448
|
+
Model.primary_key = function (type, primary_key) {
|
449
|
+
if (typeof(Model.primary_keys) === 'undefined') Model.primary_keys = {};
|
450
|
+
// default key
|
451
|
+
if (typeof(Model.primary_keys[type]) === 'undefined') Model.primary_keys[type] = 'id';
|
452
|
+
// assign key if passed
|
453
|
+
if (typeof(primary_key) !== 'undefined') Model.primary_keys[type] = primary_key;
|
454
|
+
// return value
|
455
|
+
return Model.primary_keys[type];
|
456
|
+
};
|
457
|
+
Retreaver.Base.Model = Model;
|
458
|
+
})();;(function () {
|
459
|
+
// Dependencies
|
460
|
+
var Base = window.Retreaver.Base;
|
461
|
+
var Cookies = window.Retreaver.Base.Cookies;
|
462
|
+
/**
|
463
|
+
* @constructor
|
464
|
+
* @memberof Retreaver.Base
|
465
|
+
* @param {String} options.http_prefix - The http type (http || https).
|
466
|
+
* @param {String} options.addr - The api hostname.
|
467
|
+
* @param {String} options.urlregex - The url regex validator.
|
468
|
+
*/
|
469
|
+
var Request = function (options) {
|
470
|
+
|
471
|
+
function initialize(options) {
|
472
|
+
// assert required keys and assign if valid
|
473
|
+
config = Base.assert_required_keys(options, 'http_prefix', 'addr', 'urlregex');
|
474
|
+
}
|
475
|
+
|
476
|
+
// INIT
|
477
|
+
var self = this;
|
478
|
+
var config = {};
|
479
|
+
|
480
|
+
/**
|
481
|
+
* Request data from the host
|
482
|
+
* @memberOf Retreaver.Base.Request
|
483
|
+
* @function getJSON
|
484
|
+
* @instance
|
485
|
+
* @param {String} request_url - The request uri
|
486
|
+
* @param {Object} payload - Post object
|
487
|
+
* @param {*} [callbacks] - Array or Function to be called after request
|
488
|
+
* @param {*} [context] - Context applied to callback
|
489
|
+
* @returns {Object} json
|
490
|
+
*/
|
491
|
+
self.getJSON = function (request_url, payload, callbacks, context) {
|
492
|
+
// ensure callbacks are an array
|
493
|
+
if (typeof(callbacks) == "function") callbacks = [callbacks];
|
494
|
+
if (typeof(context) === 'undefined') context = self;
|
495
|
+
// request
|
496
|
+
var request = function () {
|
497
|
+
self.apiRequest(request_url, function (data) {
|
498
|
+
// parse
|
499
|
+
response = JSON.parse(data);
|
500
|
+
// fire callbacks
|
501
|
+
for (var i in callbacks) {
|
502
|
+
if (typeof callbacks[i] == "function") callbacks[i].apply(context, [response]);
|
503
|
+
}
|
504
|
+
}, payload)
|
505
|
+
};
|
506
|
+
if (Base.ieVersion() == 6 || Base.ieVersion() == 7) {
|
507
|
+
with_ie_scripts(request);
|
508
|
+
} else {
|
509
|
+
request();
|
510
|
+
}
|
511
|
+
};
|
512
|
+
|
513
|
+
// This is an alias for now to show intent
|
514
|
+
self.postJSON = function () {
|
515
|
+
return self.getJSON.apply(this, arguments);
|
516
|
+
};
|
517
|
+
|
518
|
+
/**
|
519
|
+
* Request data from the host
|
520
|
+
* @memberOf Retreaver.Base.Request
|
521
|
+
* @function apiRequest
|
522
|
+
* @instance
|
523
|
+
* @param {String} request_url - The request uri
|
524
|
+
* @param {Array} callbackFunctions - Array of callback functions
|
525
|
+
* @param {Object} payload - Post object
|
526
|
+
* @returns {String} string
|
527
|
+
*/
|
528
|
+
self.apiRequest = function (request_uri, callbackFunctions, payload) {
|
529
|
+
// configure
|
530
|
+
var http_prefix = config['http_prefix'];
|
531
|
+
var addr = config['addr'];
|
532
|
+
var urlregex = eval(config['urlregex']);
|
533
|
+
var request_url = http_prefix + '://' + addr + request_uri;
|
534
|
+
// configure
|
535
|
+
|
536
|
+
if (payload && typeof(Cookies.get('CallPixels-vid')) !== 'undefined' && Cookies.get('CallPixels-vid') !== 'null') {
|
537
|
+
payload['visitor_id'] = Cookies.get('CallPixels-vid');
|
538
|
+
}
|
539
|
+
|
540
|
+
if (typeof(callbackFunctions) == "function") {
|
541
|
+
callbackFunctions = [callbackFunctions];
|
542
|
+
}
|
543
|
+
|
544
|
+
function ignored() {
|
545
|
+
}
|
546
|
+
|
547
|
+
function runCallbacks(response) {
|
548
|
+
for (var i in callbackFunctions) {
|
549
|
+
if (typeof callbackFunctions[i] == "function") callbackFunctions[i](response);
|
550
|
+
}
|
551
|
+
}
|
552
|
+
|
553
|
+
function forwardResponse() {
|
554
|
+
runCallbacks(xdr.responseText);
|
555
|
+
}
|
556
|
+
|
557
|
+
function sendXdm() {
|
558
|
+
// create the rpc request
|
559
|
+
var remote = http_prefix + '://' + addr + '/ie_provider';
|
560
|
+
var swf = http_prefix + '://' + addr + "/easyxdm.swf";
|
561
|
+
var rpc = eval('new window.easyXDM.Rpc({ remote: "' + remote + '", swf: "' + swf + '"},{remote: {request: {}}});');
|
562
|
+
|
563
|
+
rpc['request']({
|
564
|
+
url: ('/' + request_url.match(urlregex)[1]),
|
565
|
+
method: "POST",
|
566
|
+
data: payload
|
567
|
+
}, function (response) {
|
568
|
+
runCallbacks(response.data);
|
569
|
+
});
|
570
|
+
}
|
571
|
+
|
572
|
+
if (window.XDomainRequest) {
|
573
|
+
// IE >= 8
|
574
|
+
// 1. Create XDR object
|
575
|
+
var xdr = new XDomainRequest();
|
576
|
+
|
577
|
+
xdr.onload = forwardResponse; //alertLoaded;
|
578
|
+
xdr.onprogress = ignored;
|
579
|
+
xdr.onerror = ignored;
|
580
|
+
xdr.ontimeout = ignored;
|
581
|
+
xdr.timeout = 30000;
|
582
|
+
|
583
|
+
// 2. Open connection with server using GET method
|
584
|
+
if (payload) {
|
585
|
+
xdr.open("post", request_url);
|
586
|
+
xdr.send(self.buildPost(payload));
|
587
|
+
} else {
|
588
|
+
xdr.open("get", request_url);
|
589
|
+
xdr.send();
|
590
|
+
}
|
591
|
+
|
592
|
+
// 3. Send string data to server
|
593
|
+
|
594
|
+
} else if (Base.ieVersion() == 6 || Base.ieVersion() == 7) {
|
595
|
+
with_ie_scripts(sendXdm);
|
596
|
+
} else {
|
597
|
+
var request = new XMLHttpRequest;
|
598
|
+
|
599
|
+
if (payload) {
|
600
|
+
request.open("POST", request_url, false);
|
601
|
+
request.setRequestHeader("Content-Type", "application/json");
|
602
|
+
request.send(JSON.stringify(payload));
|
603
|
+
} else {
|
604
|
+
request.open("GET", request_url, false);
|
605
|
+
request.send();
|
606
|
+
}
|
607
|
+
|
608
|
+
runCallbacks(request.responseText);
|
609
|
+
}
|
610
|
+
};
|
611
|
+
|
612
|
+
function with_ie_scripts(callback) {
|
613
|
+
if (Retreaver['easyxdm_loaded']) {
|
614
|
+
callback();
|
615
|
+
} else {
|
616
|
+
self.loadScript(http_prefix + '://cdn.jsdelivr.net/easyxdm/2.4.17.1/easyXDM.min.js', function () {
|
617
|
+
self.loadScript(http_prefix + '://cdn.jsdelivr.net/easyxdm/2.4.17.1/json2.js', function () {
|
618
|
+
Retreaver['easyxdm_loaded'] = true;
|
619
|
+
callback();
|
620
|
+
});
|
621
|
+
});
|
622
|
+
}
|
623
|
+
};
|
624
|
+
|
625
|
+
self.buildPost = function (obj) {
|
626
|
+
var post_vars = '';
|
627
|
+
for (var k in obj) {
|
628
|
+
post_vars += k + "=" + obj[k] + '&';
|
629
|
+
}
|
630
|
+
return post_vars;
|
631
|
+
};
|
632
|
+
|
633
|
+
self.loadScript = function (scriptUrl, afterCallback) {
|
634
|
+
var firstScriptElement = document.getElementsByTagName('script')[0];
|
635
|
+
var scriptElement = document.createElement('script');
|
636
|
+
scriptElement.type = 'text/javascript';
|
637
|
+
scriptElement.async = false;
|
638
|
+
scriptElement.src = scriptUrl;
|
639
|
+
|
640
|
+
var ieLoadBugFix = function (scriptElement, callback) {
|
641
|
+
if (scriptElement.readyState == 'loaded' || scriptElement.readyState == 'complete') {
|
642
|
+
callback();
|
643
|
+
} else {
|
644
|
+
setTimeout(function () {
|
645
|
+
ieLoadBugFix(scriptElement, callback);
|
646
|
+
}, 100);
|
647
|
+
}
|
648
|
+
};
|
649
|
+
|
650
|
+
if (typeof afterCallback === "function") {
|
651
|
+
if (typeof scriptElement.addEventListener !== "undefined") {
|
652
|
+
scriptElement.addEventListener("load", afterCallback, false)
|
653
|
+
} else {
|
654
|
+
scriptElement.onreadystatechange = function () {
|
655
|
+
scriptElement.onreadystatechange = null;
|
656
|
+
ieLoadBugFix(scriptElement, afterCallback);
|
657
|
+
}
|
658
|
+
}
|
659
|
+
}
|
660
|
+
firstScriptElement.parentNode.insertBefore(scriptElement, firstScriptElement);
|
661
|
+
};
|
662
|
+
initialize(options);
|
663
|
+
self.config = config;
|
664
|
+
};
|
665
|
+
Request.connection = function () {
|
666
|
+
if (typeof window.Retreaver._connection === 'undefined') {
|
667
|
+
window.Retreaver._connection = new Retreaver.Base.Request({addr: 'api.retreaver.com', http_prefix: 'http', urlregex: "/\\/\\/[^\\/]*\\/(.*)/" });
|
668
|
+
}
|
669
|
+
return window.Retreaver._connection;
|
670
|
+
};
|
671
|
+
Retreaver.Base.Request = Request;
|
672
|
+
})();;(function () {
|
673
|
+
// Dependencies
|
674
|
+
var Base = Retreaver.Base;
|
675
|
+
var Cookies = Retreaver.Base.Cookies;
|
676
|
+
var Base64 = Retreaver.Base.Base64;
|
677
|
+
var Request = Retreaver.Base.Request;
|
678
|
+
/**
|
679
|
+
* @constructor
|
680
|
+
* @memberof Retreaver.Base
|
681
|
+
* @param {Object} options
|
682
|
+
* @param {String} options.campaign_key - The campaign uuid.
|
683
|
+
* @param {Object} options.tags - The tags to search for.
|
684
|
+
* @param {String} [options.default_number_replacement]
|
685
|
+
* @param {String} [options.message_replacement]
|
686
|
+
* @param {Array} [options.target_map]
|
687
|
+
* @param {Array} [options.target_map_cs]
|
688
|
+
* @param {String} [options.timer_offset]
|
689
|
+
* @param {String} [options.timer_offset_cs]
|
690
|
+
*/
|
691
|
+
var RequestNumber = function (options) {
|
692
|
+
|
693
|
+
function initialize(options) {
|
694
|
+
// assert required keys and assign if valid
|
695
|
+
config = Base.assert_required_keys(options, 'campaign_key');
|
696
|
+
}
|
697
|
+
|
698
|
+
// INIT
|
699
|
+
var self = this;
|
700
|
+
var config = {};
|
701
|
+
var resource_url = '/api/v1/numbers?';
|
702
|
+
|
703
|
+
/**
|
704
|
+
* Request the number
|
705
|
+
* @memberOf Retreaver.Base.RequestNumber
|
706
|
+
* @function perform
|
707
|
+
* @instance
|
708
|
+
* @param {Function} callback - Callback to fire after request
|
709
|
+
*/
|
710
|
+
self.perform = function (callback) {
|
711
|
+
if (typeof callback !== 'function') {
|
712
|
+
throw "ArgumentError: Expected to receive a callback function"
|
713
|
+
}
|
714
|
+
var request_url = resource_url + '&campaign_key=' + config['campaign_key'];
|
715
|
+
|
716
|
+
// append configs to url if provided
|
717
|
+
if (config['default_number_replacement']) {
|
718
|
+
request_url = request_url + "&default_number=" + config['default_number_replacement'];
|
719
|
+
}
|
720
|
+
if (config['message_replacement']) {
|
721
|
+
request_url = request_url + "&message=" + config['message_replacement'];
|
722
|
+
}
|
723
|
+
|
724
|
+
var body = new Object();
|
725
|
+
|
726
|
+
var uri = document.location.href;
|
727
|
+
|
728
|
+
body['u'] = Base64.encode(uri);
|
729
|
+
body['st'] = Base64.encode(tags_to_script_tags(config.number_matching_tags));
|
730
|
+
|
731
|
+
var ou = Cookies.get('CallPixels-ou');
|
732
|
+
if (getParts([document.location.href])['cpreset'] || !ou) {
|
733
|
+
Cookies.set('CallPixels-ou', body['u']);
|
734
|
+
} else {
|
735
|
+
body['ou'] = ou;
|
736
|
+
}
|
737
|
+
|
738
|
+
function sendGARequest(ga_acct, ga_cookies) {
|
739
|
+
body['ga'] = Base64.encode(ga_acct);
|
740
|
+
body['c'] = Base64.encode(JSON.stringify(ga_cookies));
|
741
|
+
Request.connection().getJSON(request_url, body, callback);
|
742
|
+
}
|
743
|
+
|
744
|
+
|
745
|
+
var ga_acct = 'FAILED';
|
746
|
+
|
747
|
+
try {
|
748
|
+
_gaq.push(function () {
|
749
|
+
ga_acct = eval('_gat._getTrackerByName()._getAccount()');
|
750
|
+
|
751
|
+
sendGARequest(ga_acct, getGACookies());
|
752
|
+
});
|
753
|
+
|
754
|
+
} catch (e) {
|
755
|
+
|
756
|
+
try {
|
757
|
+
ga(function (tracker) {
|
758
|
+
var clientId = tracker.get('clientId');
|
759
|
+
var allTrackers = eval('ga.getAll()');
|
760
|
+
ga_acct = allTrackers[0].get('trackingId');
|
761
|
+
|
762
|
+
var ga_cookies = {};
|
763
|
+
ga_cookies['__utma'] = clientId;
|
764
|
+
ga_cookies['mp'] = 'yes';
|
765
|
+
sendGARequest(ga_acct, ga_cookies);
|
766
|
+
});
|
767
|
+
|
768
|
+
} catch (f) {
|
769
|
+
// Post back with failed ga_acct.
|
770
|
+
Request.connection().getJSON(request_url, body, callback);
|
771
|
+
}
|
772
|
+
}
|
773
|
+
|
774
|
+
};
|
775
|
+
|
776
|
+
function getParts(urls) {
|
777
|
+
var all_parts = {};
|
778
|
+
for (var i = 0; i < urls.length; i++) {
|
779
|
+
var url_parts = getUrlParts(urls[i]);
|
780
|
+
for (var attrname in url_parts) {
|
781
|
+
all_parts[attrname] = url_parts[attrname];
|
782
|
+
}
|
783
|
+
}
|
784
|
+
return all_parts;
|
785
|
+
}
|
786
|
+
|
787
|
+
function getUrlParts(url) {
|
788
|
+
// url contains your data.
|
789
|
+
var objURL = new Object();
|
790
|
+
try {
|
791
|
+
//REGEX_1: /\?(.*)/
|
792
|
+
url = url.match(eval("/\\?(.*)/"))[0];
|
793
|
+
} catch (e) {
|
794
|
+
return objURL;
|
795
|
+
//Ignored
|
796
|
+
}
|
797
|
+
|
798
|
+
// Use the String::replace method to iterate over each
|
799
|
+
// name-value pair in the query string. Location.search
|
800
|
+
// gives us the query string (if it exists).
|
801
|
+
url.replace(
|
802
|
+
new RegExp("([^?=&]+)(=([^&]*))?", "g"),
|
803
|
+
|
804
|
+
// For each matched query string pair, add that
|
805
|
+
// pair to the URL struct using the pre-equals
|
806
|
+
// value as the key.
|
807
|
+
function ($0, $1, $2, $3) {
|
808
|
+
objURL[ $1.toLowerCase() ] = $3;
|
809
|
+
}
|
810
|
+
);
|
811
|
+
|
812
|
+
return objURL;
|
813
|
+
}
|
814
|
+
|
815
|
+
function getGACookies() {
|
816
|
+
var ga_cookies = ['__utma', '__utmb', '__utmc', '__utmz', '__utmv'];
|
817
|
+
var cookies = new Object();
|
818
|
+
for (var i in ga_cookies) {
|
819
|
+
var cookie_val = extractCookie(ga_cookies[i]);
|
820
|
+
|
821
|
+
if (cookie_val || i > 0) {
|
822
|
+
if (cookie_val) cookies[ga_cookies[i]] = cookie_val;
|
823
|
+
} else {
|
824
|
+
break;
|
825
|
+
}
|
826
|
+
}
|
827
|
+
return cookies;
|
828
|
+
}
|
829
|
+
|
830
|
+
function extractCookie(name) {
|
831
|
+
var regex = new RegExp(name + '=([^;]*)', 'g');
|
832
|
+
try {
|
833
|
+
return regex.exec(document.cookie)[1];
|
834
|
+
} catch (e) {
|
835
|
+
return false;
|
836
|
+
}
|
837
|
+
}
|
838
|
+
|
839
|
+
function findOne(all_parts, var_arr) {
|
840
|
+
for (var look_for in var_arr) {
|
841
|
+
for (var attrname in all_parts) {
|
842
|
+
if (attrname == var_arr[look_for]) {
|
843
|
+
return all_parts[attrname];
|
844
|
+
}
|
845
|
+
}
|
846
|
+
}
|
847
|
+
return false
|
848
|
+
}
|
849
|
+
|
850
|
+
initialize(options);
|
851
|
+
};
|
852
|
+
|
853
|
+
function tags_to_script_tags(tags) {
|
854
|
+
var script_tags = '';
|
855
|
+
for (var key in tags) {
|
856
|
+
var value = tags[key];
|
857
|
+
script_tags = script_tags + '&' + key + '=' + value
|
858
|
+
}
|
859
|
+
return script_tags;
|
860
|
+
}
|
861
|
+
|
862
|
+
Retreaver.Base.RequestNumber = RequestNumber;
|
863
|
+
})();
|
864
|
+
|
865
|
+
;window.Retreaver.Cache = {};;(function () {
|
866
|
+
// Dependencies
|
867
|
+
var Base = Retreaver.Base;
|
868
|
+
/**
|
869
|
+
* @constructor
|
870
|
+
* @memberOf Retreaver
|
871
|
+
* @param {Object} attributes - Attributes
|
872
|
+
* @property {Object} attributes
|
873
|
+
* @property {Number} attributes.id - The CallPixels internal number ID.
|
874
|
+
* @property {String} attributes.formatted_number - Nationally formatted phone number.
|
875
|
+
* @property {String} attributes.number - E.164 formatted phone number.
|
876
|
+
* @property {String} attributes.plain_number - The unformatted phone number digits.
|
877
|
+
* @property {Boolean} attributes.target_open - Whether there is an open, available target.
|
878
|
+
*/
|
879
|
+
Retreaver.Number = function (options) {
|
880
|
+
|
881
|
+
var self = this;
|
882
|
+
self.type = 'numbers';
|
883
|
+
|
884
|
+
function initialize(data) {
|
885
|
+
self.store(data);
|
886
|
+
self.set('is_active', 'true');
|
887
|
+
}
|
888
|
+
|
889
|
+
/**
|
890
|
+
* Add tags to a number.
|
891
|
+
* @memberOf Retreaver.Number
|
892
|
+
* @function add_tags
|
893
|
+
* @instance
|
894
|
+
* @param {Object} tags - A collection of tags {key: 'value', tag2: 'value2'}
|
895
|
+
* @param {Function} callback - Callback that will be fired after request.
|
896
|
+
* @throws Will throw an error if attempting to modify tags on a number that doesn't belong to a number pool
|
897
|
+
* with per-visitor numbers enabled.
|
898
|
+
*/
|
899
|
+
self.add_tags = function (tags, callback) {
|
900
|
+
ensure_is_per_visitor();
|
901
|
+
self.post_data('numbers/tag', tags_payload(tags), callback);
|
902
|
+
};
|
903
|
+
|
904
|
+
/**
|
905
|
+
* Remove tags from a number.
|
906
|
+
* @memberOf Retreaver.Number
|
907
|
+
* @function remove_tags
|
908
|
+
* @instance
|
909
|
+
* @param {Object} tags - A collection of tags {key: 'value', tag2: 'value2'}
|
910
|
+
* @param {Function} callback - Callback that will be fired after request.
|
911
|
+
* @throws Will throw an error if attempting to modify tags on a number that doesn't belong to a number pool
|
912
|
+
* with per-visitor numbers enabled.
|
913
|
+
*/
|
914
|
+
self.remove_tags = function (tags, callback) {
|
915
|
+
ensure_is_per_visitor();
|
916
|
+
self.post_data('numbers/untag', tags_payload(tags), callback);
|
917
|
+
};
|
918
|
+
|
919
|
+
/**
|
920
|
+
* Removes all tags with given keys from a number.
|
921
|
+
* @memberOf Retreaver.Number
|
922
|
+
* @function remove_tags_by_keys
|
923
|
+
* @instance
|
924
|
+
* @param {Array} keys - An array of keys to remove. eg: ['key1', 'key2']
|
925
|
+
* @param {Function} callback - Callback that will be fired after request.
|
926
|
+
* @throws Will throw an error if attempting to modify tags on a number that doesn't belong to a number pool
|
927
|
+
* with per-visitor numbers enabled.
|
928
|
+
*/
|
929
|
+
self.remove_tags_by_keys = function (keys, callback) {
|
930
|
+
ensure_is_per_visitor();
|
931
|
+
if (typeof(keys) === 'string') keys = keys.split(',');
|
932
|
+
var payload = {
|
933
|
+
tag_keys: keys,
|
934
|
+
ids: [ get('id') ],
|
935
|
+
campaign_key: get('campaign_key')
|
936
|
+
};
|
937
|
+
self.post_data('numbers/untag/keys', payload, callback);
|
938
|
+
};
|
939
|
+
|
940
|
+
/**
|
941
|
+
* Clear all tags from a number.
|
942
|
+
* @memberOf Retreaver.Number
|
943
|
+
* @function clear_tags
|
944
|
+
* @instance
|
945
|
+
* @param {Function} callback - Callback that will be fired after request.
|
946
|
+
* @throws Will throw an error if attempting to modify tags on a number that doesn't belong to a number pool
|
947
|
+
* with per-visitor numbers enabled.
|
948
|
+
*/
|
949
|
+
self.clear_tags = function (callback) {
|
950
|
+
ensure_is_per_visitor();
|
951
|
+
var payload = {
|
952
|
+
ids: [ get('id') ],
|
953
|
+
campaign_key: get('campaign_key'),
|
954
|
+
all: 'true'
|
955
|
+
};
|
956
|
+
self.post_data('numbers/untag', payload, callback);
|
957
|
+
};
|
958
|
+
|
959
|
+
/**
|
960
|
+
* Release number back to pool.
|
961
|
+
* @memberOf Retreaver.Number
|
962
|
+
* @function release
|
963
|
+
* @instance
|
964
|
+
*/
|
965
|
+
self.release = function () {
|
966
|
+
self.set('is_active', 'false');
|
967
|
+
};
|
968
|
+
|
969
|
+
/**
|
970
|
+
* Start a call immediately by having a campaign target dial the visitor.
|
971
|
+
* @memberOf Retreaver.Number
|
972
|
+
* @function initiate_call
|
973
|
+
* @instance
|
974
|
+
* @param {String} dial - The number to call.
|
975
|
+
* @param {Object} payload - A collection of tags as key-value pairs and optional secure override properties.
|
976
|
+
* @param {string} [payload.target_map] - A string mapping a placeholder number to a phone number.
|
977
|
+
* @param {string} [payload.target_map_cs] - A SHA1 checksum of the target_map concatenated with your CallPixels API
|
978
|
+
* key.
|
979
|
+
* @param {number} [payload.timer_offset] - Number of seconds to offset the "connect" duration timers by.
|
980
|
+
* @param {string} [payload.timer_offset_cs] - An SHA1 checksum of the timer_offset concatenated with your
|
981
|
+
* CallPixels API key.
|
982
|
+
* @param {(string|number)} [payload.*] - Key value pairs treated as tags.
|
983
|
+
* @param {Function} callback - Callback that will be fired after request.
|
984
|
+
* @example
|
985
|
+
* number.initiate_call('4166686980', {company_name: 'CallPixels'}, function (call) {
|
986
|
+
* alert('Call started with UUID ' + call.uuid)
|
987
|
+
* });
|
988
|
+
*/
|
989
|
+
self.initiate_call = function (dial, payload, callback) {
|
990
|
+
if (typeof(payload) === 'undefined') payload = {};
|
991
|
+
// assign dial to payload
|
992
|
+
payload.dial = dial;
|
993
|
+
// merge payload into payload
|
994
|
+
payload = Base.merge(self.get('id', 'campaign_key'), payload);
|
995
|
+
// post the payload
|
996
|
+
self.post_data('numbers/initiate_call', payload, callback);
|
997
|
+
};
|
998
|
+
|
999
|
+
function tags_payload(tags) {
|
1000
|
+
if (typeof(tags) === 'string') tags = Retreaver.Number.extract_tags_from_string(tags);
|
1001
|
+
return {
|
1002
|
+
tag_values: tags,
|
1003
|
+
ids: [ get('id') ],
|
1004
|
+
campaign_key: get('campaign_key')
|
1005
|
+
};
|
1006
|
+
}
|
1007
|
+
|
1008
|
+
function get(key) {
|
1009
|
+
return self.get(key);
|
1010
|
+
}
|
1011
|
+
|
1012
|
+
function ensure_is_per_visitor() {
|
1013
|
+
if (self.get('is_per_visitor') === false) {
|
1014
|
+
throw "Error: Tried to add tags to non per-visitor number.";
|
1015
|
+
}
|
1016
|
+
}
|
1017
|
+
|
1018
|
+
initialize(options);
|
1019
|
+
};
|
1020
|
+
|
1021
|
+
Retreaver.Number.extract_tags_from_string = function (tags) {
|
1022
|
+
var output = {};
|
1023
|
+
var tags = tags.split(",");
|
1024
|
+
for (var i = 0; i < tags.length; i++) {
|
1025
|
+
var tag = tags[i].split(":");
|
1026
|
+
output[tag[0]] = tag[1]
|
1027
|
+
}
|
1028
|
+
return output;
|
1029
|
+
};
|
1030
|
+
|
1031
|
+
Retreaver.Number.prototype = new Retreaver.Base.Model();
|
1032
|
+
|
1033
|
+
function ping_active_numbers(callback) {
|
1034
|
+
if (typeof(Retreaver.Base.Data._store) !== 'undefined') {
|
1035
|
+
// get numbers
|
1036
|
+
var numbers = Retreaver.Base.Data._store['numbers'];
|
1037
|
+
// for each number
|
1038
|
+
if (typeof(numbers) !== 'undefined') {
|
1039
|
+
// group number_ids by campaign_key
|
1040
|
+
var grouped = {};
|
1041
|
+
for (var primary_key in numbers) {
|
1042
|
+
var number = numbers[primary_key];
|
1043
|
+
if (number.is_active === 'true') {
|
1044
|
+
if (typeof(grouped[number.campaign_key]) === 'undefined') {
|
1045
|
+
grouped[number.campaign_key] = [];
|
1046
|
+
grouped[number.campaign_key]['ids'] = [];
|
1047
|
+
grouped[number.campaign_key]['hashes'] = [];
|
1048
|
+
}
|
1049
|
+
grouped[number.campaign_key]['ids'].push(number.id);
|
1050
|
+
grouped[number.campaign_key]['hashes'].push(number.id_checksum);
|
1051
|
+
}
|
1052
|
+
}
|
1053
|
+
// ping each group of number_ids
|
1054
|
+
for (var campaign_key in grouped) {
|
1055
|
+
var payload = {
|
1056
|
+
ids: grouped[campaign_key].ids,
|
1057
|
+
hashes: grouped[campaign_key].hashes
|
1058
|
+
};
|
1059
|
+
Retreaver.Base.Request.connection().postJSON('/api/v1/numbers/ping', payload, [Retreaver.Base.Model.update, callback], this);
|
1060
|
+
}
|
1061
|
+
}
|
1062
|
+
}
|
1063
|
+
// call recursively
|
1064
|
+
setTimeout(ping_active_numbers, 15000);
|
1065
|
+
}
|
1066
|
+
|
1067
|
+
// always ping active numbers
|
1068
|
+
ping_active_numbers();
|
1069
|
+
|
1070
|
+
})();;(function () {
|
1071
|
+
// Dependencies
|
1072
|
+
var RequestNumber = Retreaver.Base.RequestNumber;
|
1073
|
+
/**
|
1074
|
+
* @constructor
|
1075
|
+
* @memberOf Retreaver
|
1076
|
+
* @param {Object} options
|
1077
|
+
* @param {String} options.campaign_key - Campaign key
|
1078
|
+
* @example
|
1079
|
+
* var campaign = new Retreaver.Campaign({ campaign_key: '67d9fb1917ae8f4eaff36831b41788c3' });
|
1080
|
+
*/
|
1081
|
+
var Campaign = function (options) {
|
1082
|
+
|
1083
|
+
function initialize(data) {
|
1084
|
+
// initialize data store
|
1085
|
+
self.store(data);
|
1086
|
+
}
|
1087
|
+
|
1088
|
+
var self = this;
|
1089
|
+
self.type = 'campaigns';
|
1090
|
+
self.primary_key('campaign_key');
|
1091
|
+
self.numbers = [];
|
1092
|
+
|
1093
|
+
/**
|
1094
|
+
* Fetch a campaign number.
|
1095
|
+
* @memberOf Retreaver.Campaign
|
1096
|
+
* @function request_number
|
1097
|
+
* @instance
|
1098
|
+
* @param {Object} tags - A collection of tags as key-value pairs. The number returned will match these tags.
|
1099
|
+
* @param {getNumberCallback} callback - Callback fired if the request completes successfully.
|
1100
|
+
* @param {Function} error_callback - Callback fired if the request raises an error.
|
1101
|
+
* @example
|
1102
|
+
* campaign.request_number({calling_about: 'support'}, function (number) {
|
1103
|
+
* alert(number.get('number'))
|
1104
|
+
* }, function(response){
|
1105
|
+
* alert('something went wrong: ' + response);
|
1106
|
+
* };
|
1107
|
+
*/
|
1108
|
+
self.request_number = function (tags, callback, error_callback) {
|
1109
|
+
// if the first argument is a function, the user has decided to skip passing tags
|
1110
|
+
// therefore cascade the arguments upwards so that everything works as expected
|
1111
|
+
if (typeof(tags) === 'function') {
|
1112
|
+
// argument 3 becomes argument 2
|
1113
|
+
error_callback = callback;
|
1114
|
+
// argument 2 becomes argument 1
|
1115
|
+
callback = tags;
|
1116
|
+
// argument 1 becomes an empty tags object
|
1117
|
+
tags = {};
|
1118
|
+
}
|
1119
|
+
// assign the tags (this is important since it runs it through set_number_matching_tags)
|
1120
|
+
self.set('number_matching_tags', tags);
|
1121
|
+
// request the number
|
1122
|
+
new RequestNumber(self.get('campaign_key', 'number_matching_tags')).perform(function (data) {
|
1123
|
+
// did retreaver return a valid number?
|
1124
|
+
if (typeof(data) !== 'undefined' && typeof(data.number) !== 'undefined' && data.number !== '') {
|
1125
|
+
// initialize number
|
1126
|
+
var number = new Retreaver.Number(data.number);
|
1127
|
+
// call callback
|
1128
|
+
callback.apply(self, [number]);
|
1129
|
+
}
|
1130
|
+
// otherwise fire the error callback
|
1131
|
+
else if (typeof(error_callback) === 'function') {
|
1132
|
+
error_callback.apply(self, [data]);
|
1133
|
+
}
|
1134
|
+
});
|
1135
|
+
};
|
1136
|
+
/**
|
1137
|
+
* Retreaver.Campaign#request_number callback fired after the request completes.
|
1138
|
+
* @callback getNumberCallback
|
1139
|
+
* @param {Retreaver.Number} - The number that was returned
|
1140
|
+
*/
|
1141
|
+
|
1142
|
+
self.numbers = function () {
|
1143
|
+
var output = [];
|
1144
|
+
if (typeof(Retreaver.Base.Data._store) !== 'undefined') {
|
1145
|
+
// get numbers
|
1146
|
+
var numbers = Retreaver.Base.Data._store['numbers'];
|
1147
|
+
// present?
|
1148
|
+
if (typeof(numbers) !== 'undefined') {
|
1149
|
+
// collect numbers matching this campaign
|
1150
|
+
for (var primary_key in numbers) {
|
1151
|
+
var number = numbers[primary_key];
|
1152
|
+
if (self.get('campaign_key') == number.campaign_key) {
|
1153
|
+
output.push(new Retreaver.Number(number));
|
1154
|
+
}
|
1155
|
+
}
|
1156
|
+
}
|
1157
|
+
}
|
1158
|
+
return output;
|
1159
|
+
};
|
1160
|
+
|
1161
|
+
self.set_number_matching_tags = function (tags) {
|
1162
|
+
if (typeof(tags) === 'string') {
|
1163
|
+
tags = Retreaver.Number.extract_tags_from_string(tags);
|
1164
|
+
}
|
1165
|
+
if (tags && (typeof tags === "object") && !(tags instanceof Array)) {
|
1166
|
+
return tags
|
1167
|
+
}
|
1168
|
+
else {
|
1169
|
+
throw "ArgumentError: Expected number_matching_tags to be an object. eg: {tag: 'value'}";
|
1170
|
+
}
|
1171
|
+
};
|
1172
|
+
|
1173
|
+
initialize(options);
|
1174
|
+
};
|
1175
|
+
Campaign.prototype = new Retreaver.Base.Model();
|
1176
|
+
Retreaver.Campaign = Campaign;
|
1177
|
+
})();;(function (context) {
|
1178
|
+
context.Callpixels = window.Retreaver;
|
1179
|
+
})(window);
|