From d76b68a1662dc040d0013da99fb3af6fb622bc99 Mon Sep 17 00:00:00 2001 From: je-lopez Date: Wed, 13 Sep 2017 13:51:14 -0700 Subject: [PATCH 1/4] moves getContactByEmail from index to its own file --- .../services/crmService/getContactByEmail.js | 33 +++++++++++++++++++ src/server/services/crmService/index.js | 19 +---------- 2 files changed, 34 insertions(+), 18 deletions(-) create mode 100644 src/server/services/crmService/getContactByEmail.js diff --git a/src/server/services/crmService/getContactByEmail.js b/src/server/services/crmService/getContactByEmail.js new file mode 100644 index 00000000..51742169 --- /dev/null +++ b/src/server/services/crmService/getContactByEmail.js @@ -0,0 +1,33 @@ +import fetch from 'isomorphic-fetch' +import config from 'src/config' + +export default async function getContactByEmail(email) { + const url = _crmURL(`/contacts/v1/contact/email/${encodeURIComponent(email)}/profile`) + + const resp = await fetch(url, { + method: 'GET', + headers: { + Accept: 'application/json', + } + }) + + if (!resp.ok) { + throw new Error(`Couldn't get contact by email: ${resp.statusText}`) + } + + return resp.json() +} + +function _crmURL(path) { + _assertEnvironment() + return `${config.server.crm.baseURL}${path}?hapikey=${config.server.crm.key}` +} + +function _assertEnvironment() { + if (!config.server.crm.baseURL) { + throw new Error('CRM base URL must be configured') + } + if (!config.server.crm.key) { + throw new Error('CRM API key must be configured') + } +} diff --git a/src/server/services/crmService/index.js b/src/server/services/crmService/index.js index 6f81b18d..ed27a0a2 100644 --- a/src/server/services/crmService/index.js +++ b/src/server/services/crmService/index.js @@ -1,6 +1,6 @@ import fetch from 'isomorphic-fetch' - import config from 'src/config' +import {default as getContactByEmail} from './getContactByEmail' const properties = { echoSignUp: 'signed_up_for_echo', @@ -21,23 +21,6 @@ export default { notifyContactSignedUp, } -async function getContactByEmail(email) { - const url = _crmURL(paths.contactProfileByEmail(encodeURIComponent(email))) - - const resp = await fetch(url, { - method: 'GET', - headers: { - Accept: 'application/json', - } - }) - - if (!resp.ok) { - throw new Error(`Couldn't get contact by email: ${resp.statusText}`) - } - - return resp.json() -} - async function notifyContactSignedUp(email) { const contact = await getContactByEmail(email) From 22252d4caf8d0beb588d56a88870e29bd696e565 Mon Sep 17 00:00:00 2001 From: je-lopez Date: Wed, 13 Sep 2017 14:58:23 -0700 Subject: [PATCH 2/4] moves notifyContactSignedUp from index to its own file --- src/server/services/crmService/index.js | 52 +------------------ .../crmService/notifyContactSignedUp.js | 47 +++++++++++++++++ 2 files changed, 48 insertions(+), 51 deletions(-) create mode 100644 src/server/services/crmService/notifyContactSignedUp.js diff --git a/src/server/services/crmService/index.js b/src/server/services/crmService/index.js index ed27a0a2..1c7b31b0 100644 --- a/src/server/services/crmService/index.js +++ b/src/server/services/crmService/index.js @@ -1,15 +1,5 @@ -import fetch from 'isomorphic-fetch' -import config from 'src/config' import {default as getContactByEmail} from './getContactByEmail' - -const properties = { - echoSignUp: 'signed_up_for_echo', -} - -const paths = { - contactProfileByEmail: email => `/contacts/v1/contact/email/${email}/profile`, - contactProfileByVID: vid => `/contacts/v1/contact/vid/${vid}/profile`, -} +import {default as notifyContactSignedUp} from './notifyContactSignedUp' /** * NOTE: this service's functions are exported the way they are to enable @@ -20,43 +10,3 @@ export default { getContactByEmail, notifyContactSignedUp, } - -async function notifyContactSignedUp(email) { - const contact = await getContactByEmail(email) - - const url = _crmURL(paths.contactProfileByVID(contact.vid)) - const resp = await fetch(url, { - method: 'POST', - headers: { - Accept: 'application/json', - 'Content-Type': 'application.json' - }, - body: JSON.stringify({ - properties: [{ - property: properties.echoSignUp, - value: true, - }] - }) - }) - - if (!resp.ok) { - throw new Error(`Couldn't notify that contact signed up: ${resp.statusText}`) - } - - // API returns statusCode 204 with no body - return true -} - -function _crmURL(path) { - _assertEnvironment() - return `${config.server.crm.baseURL}${path}?hapikey=${config.server.crm.key}` -} - -function _assertEnvironment() { - if (!config.server.crm.baseURL) { - throw new Error('CRM base URL must be configured') - } - if (!config.server.crm.key) { - throw new Error('CRM API key must be configured') - } -} diff --git a/src/server/services/crmService/notifyContactSignedUp.js b/src/server/services/crmService/notifyContactSignedUp.js new file mode 100644 index 00000000..5189587c --- /dev/null +++ b/src/server/services/crmService/notifyContactSignedUp.js @@ -0,0 +1,47 @@ +import fetch from 'isomorphic-fetch' +import config from 'src/config' +import {default as getContactByEmail} from './getContactByEmail' + +const properties = { + echoSignUp: 'signed_up_for_echo', +} + +export default async function notifyContactSignedUp(email) { + const contact = await getContactByEmail(email) + + const url = _crmURL(`/contacts/v1/contact/vid/${contact.vid}/profile`) + const resp = await fetch(url, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application.json' + }, + body: JSON.stringify({ + properties: [{ + property: properties.echoSignUp, + value: true, + }] + }) + }) + + if (!resp.ok) { + throw new Error(`Couldn't notify that contact signed up: ${resp.statusText}`) + } + + // API returns statusCode 204 with no body + return true +} + +function _crmURL(path) { + _assertEnvironment() + return `${config.server.crm.baseURL}${path}?hapikey=${config.server.crm.key}` +} + +function _assertEnvironment() { + if (!config.server.crm.baseURL) { + throw new Error('CRM base URL must be configured') + } + if (!config.server.crm.key) { + throw new Error('CRM API key must be configured') + } +} From 40e2d69237eabb340834027d5ff4018f7584ba58 Mon Sep 17 00:00:00 2001 From: je-lopez Date: Wed, 13 Sep 2017 15:35:22 -0700 Subject: [PATCH 3/4] extracts duplicate code from getContactByEmail and notifyContactSignedUp to util.js --- .../services/crmService/getContactByEmail.js | 32 +--------------- src/server/services/crmService/index.js | 2 + .../crmService/notifyContactSignedUp.js | 34 ++--------------- src/server/services/crmService/util.js | 37 +++++++++++++++++++ 4 files changed, 44 insertions(+), 61 deletions(-) create mode 100644 src/server/services/crmService/util.js diff --git a/src/server/services/crmService/getContactByEmail.js b/src/server/services/crmService/getContactByEmail.js index 51742169..d4f504c3 100644 --- a/src/server/services/crmService/getContactByEmail.js +++ b/src/server/services/crmService/getContactByEmail.js @@ -1,33 +1,5 @@ -import fetch from 'isomorphic-fetch' -import config from 'src/config' +import {default as fetchCRM} from './util' export default async function getContactByEmail(email) { - const url = _crmURL(`/contacts/v1/contact/email/${encodeURIComponent(email)}/profile`) - - const resp = await fetch(url, { - method: 'GET', - headers: { - Accept: 'application/json', - } - }) - - if (!resp.ok) { - throw new Error(`Couldn't get contact by email: ${resp.statusText}`) - } - - return resp.json() -} - -function _crmURL(path) { - _assertEnvironment() - return `${config.server.crm.baseURL}${path}?hapikey=${config.server.crm.key}` -} - -function _assertEnvironment() { - if (!config.server.crm.baseURL) { - throw new Error('CRM base URL must be configured') - } - if (!config.server.crm.key) { - throw new Error('CRM API key must be configured') - } + return fetchCRM(`/contacts/v1/contact/email/${encodeURIComponent(email)}/profile`) } diff --git a/src/server/services/crmService/index.js b/src/server/services/crmService/index.js index 1c7b31b0..4b628694 100644 --- a/src/server/services/crmService/index.js +++ b/src/server/services/crmService/index.js @@ -1,5 +1,6 @@ import {default as getContactByEmail} from './getContactByEmail' import {default as notifyContactSignedUp} from './notifyContactSignedUp' +import {default as updateContactProperties} from './updateContactProperties' /** * NOTE: this service's functions are exported the way they are to enable @@ -9,4 +10,5 @@ import {default as notifyContactSignedUp} from './notifyContactSignedUp' export default { getContactByEmail, notifyContactSignedUp, + updateContactProperties, } diff --git a/src/server/services/crmService/notifyContactSignedUp.js b/src/server/services/crmService/notifyContactSignedUp.js index 5189587c..5d009c23 100644 --- a/src/server/services/crmService/notifyContactSignedUp.js +++ b/src/server/services/crmService/notifyContactSignedUp.js @@ -1,47 +1,19 @@ -import fetch from 'isomorphic-fetch' -import config from 'src/config' +import {default as fetchCRM} from './util' import {default as getContactByEmail} from './getContactByEmail' -const properties = { - echoSignUp: 'signed_up_for_echo', -} - export default async function notifyContactSignedUp(email) { const contact = await getContactByEmail(email) - const url = _crmURL(`/contacts/v1/contact/vid/${contact.vid}/profile`) - const resp = await fetch(url, { + await fetchCRM(`/contacts/v1/contact/vid/${contact.vid}/profile`, { method: 'POST', - headers: { - Accept: 'application/json', - 'Content-Type': 'application.json' - }, body: JSON.stringify({ properties: [{ - property: properties.echoSignUp, + property: 'signed_up_for_echo', value: true, }] }) }) - if (!resp.ok) { - throw new Error(`Couldn't notify that contact signed up: ${resp.statusText}`) - } - // API returns statusCode 204 with no body return true } - -function _crmURL(path) { - _assertEnvironment() - return `${config.server.crm.baseURL}${path}?hapikey=${config.server.crm.key}` -} - -function _assertEnvironment() { - if (!config.server.crm.baseURL) { - throw new Error('CRM base URL must be configured') - } - if (!config.server.crm.key) { - throw new Error('CRM API key must be configured') - } -} diff --git a/src/server/services/crmService/util.js b/src/server/services/crmService/util.js new file mode 100644 index 00000000..206168df --- /dev/null +++ b/src/server/services/crmService/util.js @@ -0,0 +1,37 @@ +import fetch from 'isomorphic-fetch' + +import config from 'src/config' + +export default async function fetchCRM(path, fetchOptions = {}) { + const url = _crmURL(path) + + const options = { + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json' + }, + ...fetchOptions + } + + const resp = await fetch(url, options) + + if (!resp.ok) { + throw new Error(`Couldn't fetch from CRM service: ${resp.statusText}`) + } + + return resp.json() +} + +function _crmURL(path) { + _assertEnvironment() + return `${config.server.crm.baseURL}${path}?hapikey=${config.server.crm.key}` +} + +function _assertEnvironment() { + if (!config.server.crm.baseURL) { + throw new Error('CRM base URL must be configured') + } + if (!config.server.crm.key) { + throw new Error('CRM API key must be configured') + } +} From 5b8e182f3763ecf3725391b266e9f0f97909f399 Mon Sep 17 00:00:00 2001 From: je-lopez Date: Wed, 13 Sep 2017 16:40:40 -0700 Subject: [PATCH 4/4] adds functionality for updating contact on hubspot when their phase changes --- .../services/crmService/__tests__/index.test.js | 16 ++++++++++++++++ .../crmService/updateContactProperties.js | 14 ++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 src/server/services/crmService/updateContactProperties.js diff --git a/src/server/services/crmService/__tests__/index.test.js b/src/server/services/crmService/__tests__/index.test.js index 733e12f4..5c9aa9f3 100644 --- a/src/server/services/crmService/__tests__/index.test.js +++ b/src/server/services/crmService/__tests__/index.test.js @@ -10,6 +10,7 @@ import crmContact from 'src/test/helpers/hubSpotContact' import { getContactByEmail, notifyContactSignedUp, + updateContactProperties, } from '../index' const crmBaseUrl = config.server.crm.baseURL @@ -45,4 +46,19 @@ describe(testContext(__filename), function () { return expect(result).to.eventually.equal(true) }) }) + + describe('updateContactProperties()', function () { + beforeEach(function () { + nock(crmBaseUrl) + .get(`/contacts/v1/contact/email/${contactEmail}/profile?hapikey=${crmKey}`) + .reply(200, crmContact) + .post(`/contacts/v1/contact/vid/${crmContact.vid}/profile?hapikey=${crmKey}`) + .reply(204) + }) + + it('returns true on success', function () { + const result = updateContactProperties('tanner+test@learnersguild.org') + return expect(result).to.eventually.equal(true) + }) + }) }) diff --git a/src/server/services/crmService/updateContactProperties.js b/src/server/services/crmService/updateContactProperties.js new file mode 100644 index 00000000..cd39174d --- /dev/null +++ b/src/server/services/crmService/updateContactProperties.js @@ -0,0 +1,14 @@ +import {default as fetchCRM} from './util' +import {default as getContactByEmail} from './getContactByEmail' + +export default async function updateContactProperties(email, properties) { + const contact = await getContactByEmail(email) + + await fetchCRM(`/contacts/v1/contact/vid/${contact.vid}/profile`, { + method: 'POST', + body: JSON.stringify({properties}) + }) + + // API returns statusCode 204 with no body + return true +}