From 76067ae95edc2348605a1c677fb0db6027da2743 Mon Sep 17 00:00:00 2001 From: uKit Date: Mon, 5 Sep 2016 12:03:13 +0300 Subject: [PATCH 1/2] Add OfflineConversionFeedService for offline import of conversion --- index.js | 2 +- services/offlineConversionFeedService.js | 85 ++++++++++++++++++++++++ types/offlineConversionFeed.js | 33 +++++++++ 3 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 services/offlineConversionFeedService.js create mode 100644 types/offlineConversionFeed.js diff --git a/index.js b/index.js index ab5b04f..2daf299 100755 --- a/index.js +++ b/index.js @@ -60,7 +60,7 @@ module.exports = { FeedItemService: null, FeedMappingService: null, FeedService: null, - OfflineConversionFeedService: null, + OfflineConversionFeedService: require('./services/offlineConversionFeedService'), // Optimization ExperimentService: null, diff --git a/services/offlineConversionFeedService.js b/services/offlineConversionFeedService.js new file mode 100644 index 0000000..8294257 --- /dev/null +++ b/services/offlineConversionFeedService.js @@ -0,0 +1,85 @@ +var + _ = require('lodash'), + async = require('async'), + soap = require('soap'); + +var AdWordsService = require('./adWordsService'); +var types = require('../types/offlineConversionFeed'); + +function Service(options) { + var self = this; + AdWordsService.call(self, options); + self.Collection = types.collection; + self.Model = types.model; + //self.operatorKey = 'cm:operator'; + + self.parseGetResponse = function(response) { + if (self.validateOnly) { + return { + labels: null + }; + } else if (response.rval) { + return { + labels: response.rval.labels || [], + }; + } else { + return {}; + } + }; + + self.parseMutateResponse = function(response) { + return self.parseGetResponse(response); + }; + + self.mutateAddList = function(clientCustomerId, operand, done) { + var operands = operand.map(function (operand) { + if (!operand.isValid()) return done(operand.validationError); + var operation = {}; + operation[self.operatorKey] = 'ADD'; + operation.operand = operand; + return operation; + }); + + self.mutate( + { + clientCustomerId: clientCustomerId, + mutateMethod: 'mutate', + operations: operands, + parseMethod: self.mutateAddListResponse + }, + done + ); + }; + + self.mutateAddListResponse = function(response) { + if (self.validateOnly) { + return { + links: null + }; + } else if (response.rval) { + return { + links: response.rval.links || [] + }; + } else { + return {}; + } + }; + + // https://developers.google.com/adwords/api/docs/reference/v201607/OfflineConversionFeedService.OfflineConversionFeed + self.selectable = [ + 'googleClickId', + 'conversionName', + 'conversionTime', + 'conversionValue', + 'conversionCurrencyCode' + ]; + + self.xmlns = 'https://adwords.google.com/api/adwords/cm/' + self.version; + self.wsdlUrl = self.xmlns + '/OfflineConversionFeedService?wsdl'; +} + +Service.prototype = _.create(AdWordsService.prototype, { + constructor: Service +}); + +module.exports = Service; diff --git a/types/offlineConversionFeed.js b/types/offlineConversionFeed.js new file mode 100644 index 0000000..e2b24da --- /dev/null +++ b/types/offlineConversionFeed.js @@ -0,0 +1,33 @@ +var _ = require('lodash'), + Backbone = require('backbone'); + + +var conversionTimeR = new RegExp('[0-9]{8} [0-9]{6} [a-zA-Z\/]{2,30}'), +//var conversionTimeR = new RegExp('[0-9]{2}/[0-9]{2}/[0-9]{4} [0-9]{2}:[0-9]{2}:[0-9]{2} [a-zA-Z\/]{2,30}'), + conversionCurrencyCodeR = new RegExp('[A-Z]{2,10}'); + + +var AccountLabel = Backbone.Model.extend({ + validate: function(attrs, options) { + var validationErrors = []; + + if ( ! attrs.googleClickId || attrs.googleClickId.length == 0 ) validationErrors.push(Error('googleClickId is empty')); + if ( ! attrs.googleClickId || attrs.googleClickId.length == 0 ) validationErrors.push(Error('conversionName is empty')); + if ( ! (attrs.conversionTime && attrs.conversionTime.match(conversionTimeR)) ) validationErrors.push(Error('conversionTime is invalid')); + if (attrs.conversionValue && _.isNumber(attrs.conversionValue) === false ) validationErrors.push(Error('conversionValue is invalid')); + if (attrs.conversionCurrencyCode && attrs.conversionCurrencyCode.match(conversionCurrencyCodeR) === null ) validationErrors.push(Error('conversionCurrencyCode is invalid')); + + if (validationErrors.length > 0) return validationErrors; + } +}); + + +var AccountLabelCollection = Backbone.Collection.extend({ + model: AccountLabel +}); + + +module.exports = { + collection: AccountLabelCollection, + model: AccountLabel +}; From fcce4f4c8654ea464dfce660c0400e99949ebd40 Mon Sep 17 00:00:00 2001 From: uKit Date: Mon, 5 Sep 2016 12:19:09 +0300 Subject: [PATCH 2/2] Change package.json --- package.json | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index 9856e4a..dfec727 100755 --- a/package.json +++ b/package.json @@ -1,24 +1,26 @@ { - "name": "adwords-api", - "version": "0.0.7", - "description": "Unofficial SDK for Google Adwords API", + "name": "google-adwords-conversion", + "version": "1.0.0", + "description": "Fork: https://www.npmjs.com/package/adwords-api. Added import of offline conversion", "main": "index.js", "keywords": [ "adwords", "google ads", "api", - "sdk" + "sdk", + "offline", + "conversion" ], "scripts": { "test": "gulp test" }, "repository": { "type": "git", - "url": "git+https://github.com/fallentech/adwords-api.git" + "url": "git+https://github.com/TimonKK/adwords-api.git" }, - "author": "Talha Asad ", + "author": "berezhnov@ucoz-team.net", "license": "MIT", - "homepage": "https://github.com/fallentech/adwords-api", + "homepage": "https://github.com/TimonKK/adwords-api.git", "devDependencies": { "chai": "3.5.0", "dotenv": "2.0.0",