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/getContactByEmail.js b/src/server/services/crmService/getContactByEmail.js new file mode 100644 index 00000000..d4f504c3 --- /dev/null +++ b/src/server/services/crmService/getContactByEmail.js @@ -0,0 +1,5 @@ +import {default as fetchCRM} from './util' + +export default async function getContactByEmail(email) { + 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 6f81b18d..4b628694 100644 --- a/src/server/services/crmService/index.js +++ b/src/server/services/crmService/index.js @@ -1,15 +1,6 @@ -import fetch from 'isomorphic-fetch' - -import config from 'src/config' - -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 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 @@ -19,61 +10,5 @@ const paths = { export default { getContactByEmail, 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) - - 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') - } + updateContactProperties, } diff --git a/src/server/services/crmService/notifyContactSignedUp.js b/src/server/services/crmService/notifyContactSignedUp.js new file mode 100644 index 00000000..5d009c23 --- /dev/null +++ b/src/server/services/crmService/notifyContactSignedUp.js @@ -0,0 +1,19 @@ +import {default as fetchCRM} from './util' +import {default as getContactByEmail} from './getContactByEmail' + +export default async function notifyContactSignedUp(email) { + const contact = await getContactByEmail(email) + + await fetchCRM(`/contacts/v1/contact/vid/${contact.vid}/profile`, { + method: 'POST', + body: JSON.stringify({ + properties: [{ + property: 'signed_up_for_echo', + value: true, + }] + }) + }) + + // API returns statusCode 204 with no body + return 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 +} 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') + } +}