Skip to content

Commit

Permalink
Merge pull request #1071 from DoSomething/feature/autoReply
Browse files Browse the repository at this point in the history
Consolidate content type helper configs into contentfulEntry config
  • Loading branch information
aaronschachter committed Aug 8, 2018
2 parents 56ddb71 + 94a4c39 commit 84b33be
Show file tree
Hide file tree
Showing 12 changed files with 193 additions and 130 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,50 @@ module.exports = {
contentTypes: {
askYesNo: {
type: 'askYesNo',
broadcastable: true,
templates: [
'saidYes',
'saidNo',
'invalidAskYesNoResponse',
'autoReply',
],
},
autoReplyBroadcast: {
type: 'autoReplyBroadcast',
autoReply: {
type: 'autoReply',
templates: [
'autoReply',
],
},
autoReplyBroadcast: {
type: 'autoReplyBroadcast',
broadcastable: true,
},
defaultTopicTrigger: {
type: 'defaultTopicTrigger',
},
message: {
type: 'message',
},
photoPostConfig: {
type: 'photoPostConfig',
postType: 'photo',
},
textPostConfig: {
type: 'textPostConfig',
postType: 'text',
},
// Legacy types:
// Ideally we'd backfill all legacy entries as their new types, but we likely can't change the
// the type of a Contentful entry without changing its id (if that's the case - we'd need to
// bulk update all documents in the Conversations messages DB)
legacy: {
// This externalPostConfig type will deprecated by an autoReply:
externalPostConfig: {
type: 'externalPostConfig',
postType: 'external',
},
legacyBroadcast: {
type: 'broadcast',
templates: [],
broadcastable: true,
},
},
};
3 changes: 0 additions & 3 deletions config/lib/helpers/defaultTopicTrigger.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,4 @@

module.exports = {
allDefaultTopicTriggersCacheKey: 'all',
contentTypes: [
'defaultTopicTrigger',
],
};
30 changes: 0 additions & 30 deletions config/lib/helpers/topic.js
Original file line number Diff line number Diff line change
@@ -1,34 +1,5 @@
'use strict';

// @see documentation/endpoints/topics
const contentTypes = {
askYesNo: {
type: 'askYesNo',
isBroadcast: true,
postType: null,
},
autoReplyBroadcast: {
type: 'autoReplyBroadcast',
isBroadcast: true,
postType: null,
},
externalPostConfig: {
type: 'externalPostConfig',
isBroadcast: false,
postType: 'external',
},
photoPostConfig: {
type: 'photoPostConfig',
isBroadcast: false,
postType: 'photo',
},
textPostConfig: {
type: 'textPostConfig',
isBroadcast: false,
postType: 'text',
},
};

const defaultText = {
declined: 'Text MENU if you\'d like to find a different action to take.',
invalidInput: 'Sorry, I didn\'t get that.',
Expand All @@ -49,7 +20,6 @@ const photoPostDefaultText = {

module.exports = {
allTopicsCacheKey: 'all',
contentTypes,
defaultPostType: 'photo',
/*
* Maps each content type with a map of templateNames and its corresponding field name and
Expand Down
37 changes: 5 additions & 32 deletions lib/helpers/broadcast.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,13 @@
const logger = require('winston');
const contentful = require('../contentful');
const helpers = require('../helpers');
const config = require('../../config/lib/helpers/broadcast');

/**
* @return {Array}
*/
function getContentTypes() {
const contentTypeConfigs = Object.values(config.contentTypes);
return contentTypeConfigs.map(contentTypeConfig => contentTypeConfig.type);
const configs = Object.values(helpers.contentfulEntry.getContentTypeConfigs());
return configs.filter(config => config.broadcastable).map(config => config.type);
}

/**
Expand Down Expand Up @@ -66,20 +65,17 @@ function getById(broadcastId, resetCache = false) {
*/
function parseBroadcastFromContentfulEntry(contentfulEntry) {
const contentType = contentful.getContentTypeFromContentfulEntry(contentfulEntry);
const contentTypeConfigs = config.contentTypes;

// A nice to have TODO is migrating all legacy broadcast entries into the respective new type, so
// we can remove check and the function it calls entirely.
if (contentType === contentTypeConfigs.legacy.type) {
const contentTypeConfigs = helpers.contentfulEntry.getContentTypeConfigs();
if (contentType === contentTypeConfigs.legacyBroadcast.type) {
return module.exports.parseLegacyBroadcastFromContentfulEntry(contentfulEntry);
}

const data = helpers.contentfulEntry.getSummaryFromContentfulEntry(contentfulEntry);
const message = module.exports
.parseBroadcastMessageFromContentfulEntryAndTemplateName(contentfulEntry, contentType);
const fieldNames = contentTypeConfigs[contentType].templates;
const templates = module.exports
.parseTemplatesFromContentfulEntryAndFieldNames(contentfulEntry, fieldNames);
const templates = helpers.contentfulEntry.getMessageTemplatesFromContentfulEntry(contentfulEntry);

return Promise.resolve(Object.assign(data, { message, templates }));
}
Expand Down Expand Up @@ -132,28 +128,6 @@ function parseBroadcastMessageFromContentfulEntryAndTemplateName(contentfulEntry
.getMessageTemplateFromContentfulEntryAndTemplateName(broadcastMessageEntry, templateName);
}

/**
* @param {Object}
* @param {String}
* @return {Object}
*/
function parseTemplatesFromContentfulEntryAndFieldNames(contentfulEntry, fieldNames) {
const data = {};
if (!contentfulEntry) {
return data;
}

fieldNames.forEach((fieldName) => {
const messageEntry = contentfulEntry.fields[fieldName];
if (!messageEntry) {
return;
}
data[fieldName] = helpers.contentfulEntry
.getMessageTemplateFromContentfulEntryAndTemplateName(messageEntry, fieldName);
});
return data;
}

module.exports = {
fetch,
fetchById,
Expand All @@ -162,5 +136,4 @@ module.exports = {
parseBroadcastFromContentfulEntry,
parseBroadcastMessageFromContentfulEntryAndTemplateName,
parseLegacyBroadcastFromContentfulEntry,
parseTemplatesFromContentfulEntryAndFieldNames,
};
56 changes: 55 additions & 1 deletion lib/helpers/contentfulEntry.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@
const logger = require('winston');
const contentful = require('../contentful');
const helpers = require('../helpers');
const config = require('../../config/lib/helpers/contentfulEntry');

/**
* @return {Array}
*/
function getContentTypeConfigs() {
return config.contentTypes;
}

/**
* @param {String} contentfulId
Expand Down Expand Up @@ -69,6 +77,48 @@ function getMessageTemplateFromContentfulEntryAndTemplateName(contentfulEntry, t
};
}

/**
* @param {Object}
* @param {String}
* @return {Object}
*/
function getMessageTemplatesFromContentfulEntry(contentfulEntry) {
const contentType = contentful.getContentTypeFromContentfulEntry(contentfulEntry);
const fieldNames = config.contentTypes[contentType].templates;
const result = {};

if (!contentfulEntry || !fieldNames) {
return result;
}

fieldNames.forEach((fieldName) => {
const messageEntry = contentfulEntry.fields[fieldName];
if (!messageEntry) {
return;
}
result[fieldName] = module.exports
.getMessageTemplateFromContentfulEntryAndTemplateName(messageEntry, fieldName);
});
return result;
}

/**
* @param {Object} contentfulEntry
* @return {Boolean}
*/
function isAutoReply(contentfulEntry) {
return contentful.isContentType(contentfulEntry, config.contentTypes.autoReply.type);
}

/**
* @param {Object} contentfulEntry
* @return {Boolean}
*/
function isBroadcastable(contentfulEntry) {
const contentType = contentful.getContentTypeFromContentfulEntry(contentfulEntry);
return config.contentTypes[contentType].broadcastable;
}

/**
* @param {Object} contentfulEntry
* @return {Boolean}
Expand All @@ -82,13 +132,17 @@ function isDefaultTopicTrigger(contentfulEntry) {
* @return {Boolean}
*/
function isMessage(contentfulEntry) {
return contentful.isContentType(contentfulEntry, 'message');
return contentful.isContentType(contentfulEntry, config.contentTypes.message.type);
}

module.exports = {
getById,
getContentTypeConfigs,
getMessageTemplateFromContentfulEntryAndTemplateName,
getMessageTemplatesFromContentfulEntry,
getSummaryFromContentfulEntry,
isAutoReply,
isBroadcastable,
isDefaultTopicTrigger,
isMessage,
parseContentfulEntry,
Expand Down
3 changes: 2 additions & 1 deletion lib/helpers/defaultTopicTrigger.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ const config = require('../../config/lib/helpers/defaultTopicTrigger');
* @return {Array}
*/
function getContentTypes() {
return config.contentTypes;
const configs = helpers.contentfulEntry.getContentTypeConfigs();
return [configs.defaultTopicTrigger.type];
}

/**
Expand Down
41 changes: 25 additions & 16 deletions lib/helpers/topic.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,14 @@ const config = require('../../config/lib/helpers/topic');
* @return {Array}
*/
function getContentTypes() {
const contentTypeConfigs = Object.values(config.contentTypes);
return contentTypeConfigs.map(contentTypeConfig => contentTypeConfig.type);
const configs = Object.values(helpers.contentfulEntry.getContentTypeConfigs());
// Return any configs that have templates set, or a postType.
// We'll eventually refactor this config to only check for existence of templates, with each item
// corresponding to a reference field to a message or changeTopicMessage entry, like how it does
// in an askYesNo or autoReply topic (vs a textPostConfig or photoPostConfig, where we're using
// text fields and the fieldName map defined in the topic helper config).
return configs.filter(typeConfig => typeConfig.templates || typeConfig.postType)
.map(typeConfig => typeConfig.type);
}

/**
Expand Down Expand Up @@ -155,16 +161,22 @@ function parseTemplateFromContentfulEntryAndTemplateName(contentfulEntry, templa
* @param {Object} entry
* @return {Object}
*/
function parseTemplatesFromContentfulEntryAndCampaign(entry, campaign) {
function parseTemplatesFromContentfulEntryAndCampaign(contentfulEntry, campaign) {
if (helpers.contentfulEntry.isAutoReply(contentfulEntry)) {
return helpers.contentfulEntry.getMessageTemplatesFromContentfulEntry(contentfulEntry);
}
const contentType = contentful.getContentTypeFromContentfulEntry(contentfulEntry);
const data = {};
const contentType = contentful.getContentTypeFromContentfulEntry(entry);
const templateNames = Object.keys(config.templatesByContentType[contentType]);
templateNames.forEach((templateName) => {
data[templateName] = module.exports
.parseTemplateFromContentfulEntryAndTemplateName(entry, templateName);
data[templateName].rendered = helpers
.parseTemplateFromContentfulEntryAndTemplateName(contentfulEntry, templateName);
data[templateName].text = helpers
.replacePhoenixCampaignVars(data[templateName].raw, campaign);
// TODO: Remove rendered property once Gambit Conversations references text.
data[templateName].rendered = data[templateName].text;
});

return data;
}

Expand All @@ -173,26 +185,23 @@ function parseTemplatesFromContentfulEntryAndCampaign(entry, campaign) {
* @return {String}
*/
function getPostTypeFromContentType(contentType) {
return config.contentTypes[contentType].postType;
const contentTypeConfigs = helpers.contentfulEntry.getContentTypeConfigs();
return contentTypeConfigs[contentType].postType;
}

/**
* @param {Object} contentfulEntry
* @return {Promise}
*/
function parseTopicFromContentfulEntry(contentfulEntry) {
const topicId = contentful.getContentfulIdFromContentfulEntry(contentfulEntry);
logger.debug('parseTopicFromContentfulEntry', { topicId });
const contentType = contentful.getContentTypeFromContentfulEntry(contentfulEntry);
if (config.contentTypes[contentType].isBroadcast) {

if (helpers.contentfulEntry.isBroadcastable(contentfulEntry)) {
return helpers.broadcast.parseBroadcastFromContentfulEntry(contentfulEntry);
}
const data = {
id: topicId,
name: contentful.getNameTextFromContentfulEntry(contentfulEntry),
type: contentType,
postType: module.exports.getPostTypeFromContentType(contentType),
};

const data = helpers.contentfulEntry.getSummaryFromContentfulEntry(contentfulEntry);
data.postType = module.exports.getPostTypeFromContentType(contentType);
const campaignConfigEntry = contentfulEntry.fields.campaign;
let promise = Promise.resolve(null);
let campaignId;
Expand Down
Loading

0 comments on commit 84b33be

Please sign in to comment.