diff --git a/.gitignore b/.gitignore
index 140aebc..56da4fe 100644
--- a/.gitignore
+++ b/.gitignore
@@ -65,4 +65,5 @@ package-lock.json
# build directories
build
-bin
\ No newline at end of file
+bin
+lib
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a6c0921..966d4c4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,11 @@
+# 0.3.0
+- major rewrite of incoming and outgoing traffic
+- add integration tests
+- upgrade NodeJS to LTS 8.x
+- change bablejs configuration to use native code
+- upgrade hull-node to 0.13.14
+
# 0.2.0
- upgrade hull-node to 0.11.6
-- add local in memory cache to avoid duplicates to be sent to Nutshell. Only works in single process mode.
\ No newline at end of file
+- add local in memory cache to avoid duplicates to be sent to Nutshell. Only works in single process mode.
diff --git a/assets/logo.jpg b/assets/logo.jpg
index aa0b848..a3ec040 100644
Binary files a/assets/logo.jpg and b/assets/logo.jpg differ
diff --git a/assets/logo.png b/assets/logo.png
index eb109de..63ee8eb 100644
Binary files a/assets/logo.png and b/assets/logo.png differ
diff --git a/assets/logo.svg b/assets/logo.svg
index c1a3f82..42f9b89 100644
--- a/assets/logo.svg
+++ b/assets/logo.svg
@@ -1,28 +1 @@
-
+
\ No newline at end of file
diff --git a/assets/logo@2x.jpg b/assets/logo@2x.jpg
index c2e38b2..769d3cc 100644
Binary files a/assets/logo@2x.jpg and b/assets/logo@2x.jpg differ
diff --git a/assets/logo@2x.png b/assets/logo@2x.png
index b5b2bfa..8e0a457 100644
Binary files a/assets/logo@2x.png and b/assets/logo@2x.png differ
diff --git a/assets/picture.jpg b/assets/picture.jpg
index 5e1e244..9ab0b3f 100644
Binary files a/assets/picture.jpg and b/assets/picture.jpg differ
diff --git a/assets/picture.png b/assets/picture.png
index c6fc1bc..b00e513 100644
Binary files a/assets/picture.png and b/assets/picture.png differ
diff --git a/assets/picture.svg b/assets/picture.svg
index e81af94..611c6c1 100644
--- a/assets/picture.svg
+++ b/assets/picture.svg
@@ -1,29 +1 @@
-
+
\ No newline at end of file
diff --git a/assets/picture@2x.jpg b/assets/picture@2x.jpg
index 1eed7b3..88b47a7 100644
Binary files a/assets/picture@2x.jpg and b/assets/picture@2x.jpg differ
diff --git a/assets/picture@2x.png b/assets/picture@2x.png
index af1515f..22c0b68 100644
Binary files a/assets/picture@2x.png and b/assets/picture@2x.png differ
diff --git a/lib/actions/fields-account.js b/lib/actions/fields-account.js
deleted file mode 100644
index 38ce248..0000000
--- a/lib/actions/fields-account.js
+++ /dev/null
@@ -1,38 +0,0 @@
-"use strict";
-
-var Agent = require("../lib/agent");
-
-var cacheManager = require("cache-manager");
-
-var Cache = cacheManager.caching({ store: "memory", max: 100, ttl: 60 });
-
-function fieldsAccountAction(req, res) {
- var _req$hull = req.hull,
- client = _req$hull.client,
- ship = _req$hull.ship,
- metric = _req$hull.metric;
-
- var _client$configuration = client.configuration(),
- secret = _client$configuration.secret;
-
- var cacheKey = [ship.id, ship.updated_at, secret, "af"].join("/");
- var agent = new Agent(client, ship, metric);
-
- if (!agent.isAuthenticationConfigured()) {
- return res.json({ ok: false, error: "The connector is not or not properly authenticated to Nutshell.", options: [] });
- }
-
- return Cache.wrap(cacheKey, function () {
- return agent.getAccountFields();
- }).then(function (ls) {
- var fields = (ls || []).map(function (s) {
- return { value: s.value, label: s.label };
- });
- return res.json({ options: fields });
- }).catch(function (err) {
- client.logger.error("connector.metadata.error", { status: err.status, message: err.message, type: "/fields-lead" });
- return res.json({ ok: false, error: err.message, options: [] });
- });
-}
-
-module.exports = fieldsAccountAction;
\ No newline at end of file
diff --git a/lib/actions/index.js b/lib/actions/index.js
deleted file mode 100644
index 9c4fd14..0000000
--- a/lib/actions/index.js
+++ /dev/null
@@ -1,9 +0,0 @@
-"use strict";
-
-var fieldsAccount = require("./fields-account");
-var statusCheck = require("./status-check");
-
-module.exports = {
- fieldsAccount: fieldsAccount,
- statusCheck: statusCheck
-};
\ No newline at end of file
diff --git a/lib/actions/status-check.js b/lib/actions/status-check.js
deleted file mode 100644
index b0f6b64..0000000
--- a/lib/actions/status-check.js
+++ /dev/null
@@ -1,40 +0,0 @@
-"use strict";
-
-var _express = require("express");
-
-var _ = require("lodash");
-
-var Agent = require("../lib/agent");
-
-function statusCheckAction(req, res) {
- if (req.hull && req.hull.ship && req.hull.ship.private_settings) {
- var _req$hull = req.hull,
- _req$hull$ship = _req$hull.ship,
- ship = _req$hull$ship === undefined ? {} : _req$hull$ship,
- _req$hull$client = _req$hull.client,
- client = _req$hull$client === undefined ? {} : _req$hull$client,
- _req$hull$metric = _req$hull.metric,
- metric = _req$hull$metric === undefined ? {} : _req$hull$metric;
-
- var messages = [];
- var status = "ok";
- var agent = new Agent(client, ship, metric);
-
- if (agent.isAuthenticationConfigured() === false) {
- status = "error";
- messages.push("API Key is not configured. Connector cannot communicate with external service.");
- }
-
- if (_.isEmpty(_.get(ship, "private_settings.synchronized_segments", []))) {
- status = "error";
- messages.push("No users will be synchronized because no segments are whitelisted.");
- }
-
- res.json({ status: status, messages: messages });
- client.put(ship.id + "/status", { status: status, messages: messages });
- }
-
- res.status(404).json({ status: 404, messages: ["Request doesn't contain data about the connector"] });
-}
-
-module.exports = statusCheckAction;
\ No newline at end of file
diff --git a/lib/index.js b/lib/index.js
deleted file mode 100644
index fcf0960..0000000
--- a/lib/index.js
+++ /dev/null
@@ -1,27 +0,0 @@
-"use strict";
-
-var _express = require("express");
-
-var _express2 = _interopRequireDefault(_express);
-
-var _hull = require("hull");
-
-var _hull2 = _interopRequireDefault(_hull);
-
-var _server = require("./server");
-
-var _server2 = _interopRequireDefault(_server);
-
-function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-
-var config = {
- hostSecret: process.env.SECRET,
- port: process.env.PORT || 8082,
- devMode: process.env.NODE_ENV === "development"
-};
-
-var connector = new _hull2.default.Connector(config);
-var app = (0, _express2.default)();
-
-connector.setupApp(app);
-(0, _server2.default)(app);
\ No newline at end of file
diff --git a/lib/lib/agent.js b/lib/lib/agent.js
deleted file mode 100644
index 43a9edf..0000000
--- a/lib/lib/agent.js
+++ /dev/null
@@ -1,76 +0,0 @@
-"use strict";
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-var _shared = require("./shared");
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-var _ = require("lodash");
-var Promise = require("bluebird");
-var NutshellClient = require("./nutshell-client");
-
-var Agent = function () {
- function Agent(hullClient, connector, metricClient) {
- _classCallCheck(this, Agent);
-
- this.connector = connector;
- this.synchronizedSegments = connector.private_settings.synchronized_segments;
- this.hullClient = hullClient;
- this.logger = hullClient.logger;
- this.metricClient = metricClient;
- }
-
- /**
- * Returns the fields for Nutshell accounts.
- *
- * @returns {Promise>} The list of account fields.
- * @memberof Agent
- */
-
-
- _createClass(Agent, [{
- key: "getAccountFields",
- value: function getAccountFields() {
- // TODO: compose proper options
- var options = {
- host: "app.nutshell.com",
- requestId: "hull"
- };
-
- var defaultFields = [{ value: "name", label: "Name" }, { value: "description", label: "Description" }, { value: "industryId", label: "Industry (ID)" }, { value: "accountTypeId", label: "Account Type (ID)" }, { value: "territoryId", label: "Territory (ID)" }, { value: "url", label: "Url" }, { value: "phone", label: "Phone" }];
- return this.nutshellClient.findCustomFields(options).then(function (opsResult) {
- var customFields = _.map(opsResult.result.Accounts, function (field) {
- return { value: field.name, label: field.name };
- });
-
- return _.concat(defaultFields, customFields);
- });
- }
-
- /**
- * Checks whether the API key and User ID are provided at all and hypothetically valid.
- *
- * @returns {boolean} True if both are present and hypothetically valid; otherwise false.
- * @memberof Agent
- */
-
- }, {
- key: "isAuthenticationConfigured",
- value: function isAuthenticationConfigured() {
- if (_.get(this.connector, "private_settings.auth_userid", "n/a") === "n/a") {
- return false;
- }
-
- if (_.get(this.connector, "private_settings.auth_apikey", "n/a") === "n/a") {
- return false;
- }
-
- return true;
- }
- }]);
-
- return Agent;
-}();
-
-module.exports = Agent;
\ No newline at end of file
diff --git a/lib/lib/nutshell-client.js b/lib/lib/nutshell-client.js
deleted file mode 100644
index 7cde7d3..0000000
--- a/lib/lib/nutshell-client.js
+++ /dev/null
@@ -1,291 +0,0 @@
-"use strict";
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-var _shared = require("./shared");
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-var Promise = require("bluebird");
-var rpc = require("jayson");
-var shared = require("./shared");
-
-function _initHttpsClient(options) {
- var auth = Buffer.from(options.userId + ":" + options.apiKey).toString("base64");
- var client = rpc.client.https({
- hostname: options.host,
- path: "/api/v1/json",
- headers: {
- authorization: "Basic " + auth
- }
- });
- return client;
-}
-
-var NutshellClient = function () {
- /**
- * Gets or sets the user name or identifier.
- *
- * @type {string}
- * @memberof NutshellClient
- */
- function NutshellClient(options) {
- _classCallCheck(this, NutshellClient);
-
- this.userId = options.userId;
- this.apiKey = options.apiKey;
- }
-
- /**
- * Discovers the endpoint that should be used to communicate.
- * Response shall be cached between 10-90 minutes.
- *
- * @returns {Promise} The discovery result.
- * @memberof NutshellClient
- */
-
-
- /**
- * Gets or sets the API key to authenticate against the Nutshell.
- *
- * @type {string}
- * @memberof NutshellClient
- */
-
-
- _createClass(NutshellClient, [{
- key: "discoverEndpoint",
- value: function discoverEndpoint() {
- var _this = this;
-
- return new Promise(function (resolve, reject) {
- var client = rpc.client.http(shared.DISCOVERY_ENDPOINT);
-
- client.request("getApiForUsername", { username: _this.userId }, "apeye", function (err, result) {
- if (err) {
- return reject(err);
- }
- return resolve(result);
- });
- });
- }
-
- /**
- * Creates a new contact in Nutshell.
- *
- * @param {Object} data The contact data.
- * @param {INutshellOperationOptions} options The options for the operation.
- * @returns {Promise} The result of the operation.
- * @memberof NutshellClient
- */
-
- }, {
- key: "createContact",
- value: function createContact(data, options) {
- var _this2 = this;
-
- return new Promise(function (resolve, reject) {
- var client = _initHttpsClient({ userId: _this2.userId, apiKey: _this2.apiKey, host: options.host });
- client.request("newContact", { contact: data }, options.requestId, function (err, result) {
- if (err) {
- return reject(err);
- }
- return resolve(result);
- });
- });
- }
-
- /**
- * Creates a new account in Nutshell.
- *
- * @param {Object} data The account data.
- * @param {INutshellOperationOptions} options The options for the operation.
- * @returns {Promise} The result of the operation.
- * @memberof NutshellClient
- */
-
- }, {
- key: "createAccount",
- value: function createAccount(data, options) {
- var _this3 = this;
-
- return new Promise(function (resolve, reject) {
- var client = _initHttpsClient({ userId: _this3.userId, apiKey: _this3.apiKey, host: options.host });
- client.request("newAccount", { account: data }, options.requestId, function (err, result) {
- if (err) {
- return reject(err);
- }
- return resolve(result);
- });
- });
- }
-
- /**
- * Edit a contact.
- *
- * Warning: Fields which allow multiples (phone, email, URL, etc.) will be completely replaced by
- * whatever data you supply, if you supply any data for the field. (Eg. the new phone array replaces
- * all previously known phone numbers.) If you are updating a multi-value field, you must include all
- * values you wish to keep (not just the new values) for the field.
- *
- * If a note is specified, it will be added to the existing notes (preexisting notes are not affected).
- *
- * @param {string} id The contact ID to update.
- * @param {string} rev The revision number.
- * @param {Object} data The updated contact information.
- * @param {INutshellOperationOptions} options The options for the operation.
- * @returns {Promise} The result of the operation.
- * @memberof NutshellClient
- */
-
- }, {
- key: "editContact",
- value: function editContact(id, rev, data, options) {
- var _this4 = this;
-
- return new Promise(function (resolve, reject) {
- var client = _initHttpsClient({ userId: _this4.userId, apiKey: _this4.apiKey, host: options.host });
- client.request("editContact", { contactId: id, rev: rev, contact: data }, options.requestId, function (err, result) {
- if (err) {
- return reject(err);
- }
- return resolve(result);
- });
- });
- }
-
- /**
- * Edit an account.
- *
- * Warning: Fields which allow multiples (phone, email, URL, etc.) will be completely replaced by
- * whatever data you supply, if you supply any data for the field. (Eg. the new phone array replaces
- * all previously known phone numbers.) If you are updating a multi-value field, you must include
- * all values you wish to keep (not just the new values) for the field.
- *
- * If a note is specified, it will be added to the existing notes (preexisting notes are not affected).
- *
- * @param {string} id The account ID to edit.
- * @param {string} rev The revision number.
- * @param {Object} data The updated account information
- * @param {INutshellOperationOptions} options The options for the operation.
- * @returns {Promise} The result of the operation.
- * @memberof NutshellClient
- */
-
- }, {
- key: "editAccount",
- value: function editAccount(id, rev, data, options) {
- var _this5 = this;
-
- return new Promise(function (resolve, reject) {
- var client = _initHttpsClient({ userId: _this5.userId, apiKey: _this5.apiKey, host: options.host });
- client.request("editAccount", { accountId: id, rev: rev, account: data }, options.requestId, function (err, result) {
- if (err) {
- return reject(err);
- }
- return resolve(result);
- });
- });
- }
-
- /**
- * Gets all of the custom fields available for Leads, Accounts and Contacts, including appropriate meta-information.
- *
- * @param {INutshellOperationOptions} options The options for the operation.
- * @returns {Promise} The result of the operation.
- * @memberof NutshellClient
- *
- * @example
- * The result property contains an object of the following shape if the operation succeeded:
- * {
- * "Leads": [ EntityAttribute, ... ],
- * "Contacts": [ EntityAttribute, ... ],
- * "Accounts": [ EntityAttribute, ... ]
- * }
- *
- */
-
- }, {
- key: "findCustomFields",
- value: function findCustomFields(options) {
- var _this6 = this;
-
- return new Promise(function (resolve, reject) {
- var client = _initHttpsClient({ userId: _this6.userId, apiKey: _this6.apiKey, host: options.host });
- client.request("findCustomFields", [], options.requestId, function (err, result) {
- if (err) {
- return reject(err);
- }
- return resolve(result);
- });
- });
- }
-
- /**
- * Return a list of Account stubs matching a given search string.
- *
- * @param {string} query The string to search for.
- * @param {number} limit The maximum number of entities returned.
- * @param {INutshellOperationOptions} options The options for the operation.
- * @returns {Promise} The result of the operation.
- * @memberof NutshellClient
- *
- * @example
- * The result property contains an array of matching account objects.
- */
-
- }, {
- key: "searchAccounts",
- value: function searchAccounts(query, limit, options) {
- var _this7 = this;
-
- return new Promise(function (resolve, reject) {
- var client = _initHttpsClient({ userId: _this7.userId, apiKey: _this7.apiKey, host: options.host });
- client.request("searchAccounts", { string: query, limit: limit }, options.requestId, function (err, result) {
- if (err) {
- return reject(err);
- }
- return resolve(result);
- });
- });
- }
-
- /**
- * Searches accounts and contacts by email address and returns
- * up to 5 account or contact stubs with the specified email address.
- * Results are organized by entity type.
- *
- * @param {string} emailAddress The email address to search for.
- * @param {INutshellOperationOptions} options The options for the operation.
- * @returns {Promise} The result of the operation.
- * @memberof NutshellClient
- *
- * @example
- * The result property will contain an object of the following shape when successful:
- * {
- * "contacts": [ Contact, ... ],
- * "accounts": [ Account, ... ]
- * }
- */
-
- }, {
- key: "searchByEmail",
- value: function searchByEmail(emailAddress, options) {
- var _this8 = this;
-
- return new Promise(function (resolve, reject) {
- var client = _initHttpsClient({ userId: _this8.userId, apiKey: _this8.apiKey, host: options.host });
- client.request("searchByEmail", { emailAddressString: emailAddress }, options.requestId, function (err, result) {
- if (err) {
- return reject(err);
- }
- return resolve(result);
- });
- });
- }
- }]);
-
- return NutshellClient;
-}();
-
-module.exports = NutshellClient;
\ No newline at end of file
diff --git a/lib/lib/shared.js b/lib/lib/shared.js
deleted file mode 100644
index 84d2566..0000000
--- a/lib/lib/shared.js
+++ /dev/null
@@ -1,8 +0,0 @@
-"use strict";
-
-var DISCOVERY_ENDPOINT = "http://api.nutshell.com/v1/json";
-
-
-module.exports = {
- DISCOVERY_ENDPOINT: DISCOVERY_ENDPOINT
-};
\ No newline at end of file
diff --git a/lib/server.js b/lib/server.js
deleted file mode 100644
index 6096890..0000000
--- a/lib/server.js
+++ /dev/null
@@ -1,34 +0,0 @@
-"use strict";
-
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-exports.default = Server;
-
-var _utils = require("hull/lib/utils");
-
-var _updateUser = require("./update-user");
-
-var _updateUser2 = _interopRequireDefault(_updateUser);
-
-function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-
-var NotifyHandler = (0, _utils.notifHandler)({
- handlers: {
- "user:update": function userUpdate(_ref) {
- var ship = _ref.ship,
- hull = _ref.client;
- var messages = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
-
- return Promise.all(messages.map(function (message) {
- return (0, _updateUser2.default)({ message: message }, { ship: ship, hull: hull });
- }));
- }
- }
-});
-
-function Server(app) {
- app.post("/batch", NotifyHandler);
- app.post("/notify", NotifyHandler);
- return app;
-}
\ No newline at end of file
diff --git a/lib/update-user.js b/lib/update-user.js
deleted file mode 100644
index 7125397..0000000
--- a/lib/update-user.js
+++ /dev/null
@@ -1,146 +0,0 @@
-"use strict";
-
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-exports.default = updateUser;
-
-var _lodash = require("lodash");
-
-var _lodash2 = _interopRequireDefault(_lodash);
-
-var _request = require("request");
-
-var _request2 = _interopRequireDefault(_request);
-
-var _hogan = require("hogan.js");
-
-var _hogan2 = _interopRequireDefault(_hogan);
-
-var _bluebird = require("bluebird");
-
-var _bluebird2 = _interopRequireDefault(_bluebird);
-
-var _bottleneck = require("bottleneck");
-
-var _bottleneck2 = _interopRequireDefault(_bottleneck);
-
-var _lruCache = require("lru-cache");
-
-var _lruCache2 = _interopRequireDefault(_lruCache);
-
-function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-
-var Limiter = new _bottleneck2.default(1, 1000);
-
-var cache = (0, _lruCache2.default)({ max: 1000, maxAge: 24 * 3600 * 1000 }); // Max age 1 day
-
-function createUser(url, form) {
- return new _bluebird2.default(function (resolve, reject) {
- _request2.default.post({ url: url, form: form }, function (err, res) {
- if (!err && res.statusCode < 400) {
- resolve(res);
- } else {
- var error = err || new Error(res.body);
- reject(error);
- }
- });
- });
-}
-
-// return updateUser({ message }, { ship, hull });
-function updateUser(_ref, _ref2) {
- var _ref$message = _ref.message,
- message = _ref$message === undefined ? {} : _ref$message;
- var _ref2$ship = _ref2.ship,
- ship = _ref2$ship === undefined ? {} : _ref2$ship,
- hull = _ref2.hull,
- _ref2$force = _ref2.force,
- force = _ref2$force === undefined ? false : _ref2$force;
- // eslint-disable-line consistent-return
- hull.logger.debug("nutshell.user.update", message);
-
- var _message$user = message.user,
- user = _message$user === undefined ? {} : _message$user,
- _message$segments = message.segments,
- segments = _message$segments === undefined ? [] : _message$segments;
-
-
- if (!ship || !user || !user.id) {
- return hull.logger.debug("nutshell.user.error", { message: "missing data", ship: ship, user: user });
- }
-
- // User has already been pushed to nutshell
- if (!force && cache.get(user.id)) {
- return hull.logger.warn("nutshell.user.skip", { message: "id in cache", id: user.id, email: user.email });
- }
- // if (!force && user[`traits_nutshell/created_at`]) return hull.logger.warn("nutshell.user.skip",{ message: "already imported", id: user.id, email: user.email, nutshell_created_at: user[`traits_nutshell/created_at`] });
-
- // Ignore if form_api_url is not present
-
- var _ref3 = ship.private_settings || {},
- form_api_url = _ref3.form_api_url,
- synchronized_segments = _ref3.synchronized_segments,
- mapping = _ref3.mapping;
-
- if (!form_api_url) return hull.logger.error("nutshell.error.credentials", { message: "missing form_api_url" });
-
- if (!force && synchronized_segments.length > 0 && !_lodash2.default.intersection(_lodash2.default.map(segments, "id"), synchronized_segments).length) {
- return hull.logger.warn("nutshell.user.skip", { message: "not matching any segments", user: user.id });
- }
-
- // Ignore if mapping is not defined
- if (!mapping || !mapping.length) {
- return hull.logger.info("nutshell.user.skip", { message: "no mapping defined", mapping: mapping });
- }
-
- var missingField = false;
- var form = mapping.reduce(function (r, m) {
- // eslint-disable-line array-callback-return, consistent-return
- if (r) {
- var value = void 0;
- try {
- value = _hogan2.default.compile(m.hull).render(user);
- } catch (err) {
- hull.logger.error("nutshell.user.template.error ", err.message);
- }
-
- if (_lodash2.default.isEmpty(value)) {
- if (m.is_required) {
- missingField = m;
- return false;
- }
- return r;
- }
-
- return _lodash2.default.set(r, m.nutshell, value);
- }
- }, {});
-
- var formEmail = _lodash2.default.get(form, "contact.email");
-
- if (!force && formEmail && cache.get(formEmail)) {
- return hull.logger.warn("nutshell.user.skip", { message: "email in cache", id: user.id, email: formEmail });
- }
-
- if (!form) {
- return hull.logger.info("nutshell.user.skip", { message: "missing field", field: missingField, user: user });
- }
-
- hull.logger.warn("nutshell.user.create", { id: user.id, form: form });
-
- cache.set(user.id, new Date().getTime());
-
- if (formEmail) cache.set(formEmail, new Date().getTime());
-
- Limiter.schedule(createUser, form_api_url, form).then(function () {
- hull.logger.info("nutshell.user.create.success", { id: user.id, email: formEmail });
- return hull.asUser({ id: user.id }).traits({ created_at: new Date().toISOString() }, { source: "nutshell", sync: true });
- }, function (err) {
- cache.del(user.id);
- if (formEmail) {
- cache.del(formEmail);
- }
- hull.logger.warn("nutshell.user.create.error", { id: user.id, err: JSON.stringify(err) });
- });
-}
\ No newline at end of file
diff --git a/manifest.json b/manifest.json
index 4748de6..bae1205 100644
--- a/manifest.json
+++ b/manifest.json
@@ -3,6 +3,8 @@
"tags": ["outgoing","batch", "oneColumn", "smart-notifier"],
"description" : "Send Users as Leads or Contacts to Nutshell with custom mappings",
"version" : "0.3.0",
+ "source": "nutshell",
+ "logo": "logo.png",
"picture": "picture.png",
"ui": false,
"readme" : "readme.md",
diff --git a/package.json b/package.json
index 62c7dfe..4198b08 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "hull-nutshell",
- "version": "0.2.0",
+ "version": "0.3.0",
"description": "Hull Nutshell CRM integration",
"homepage": "https://github.com/hull-ships/hull-nutshell",
"repository": {
@@ -21,7 +21,7 @@
"engines": {
"node": "8.11.x",
"npm": "5.6.x",
- "yarn": "1.5.x"
+ "yarn": "1.6.x"
},
"scripts": {
"build": "yarn run clean && yarn run build:server",