Skip to content

Instantly share code, notes, and snippets.

@WesleyDRobinson
Created August 4, 2017 20:08
Show Gist options
  • Save WesleyDRobinson/3063e9f20a177ce254dec5bcb794674e to your computer and use it in GitHub Desktop.
Save WesleyDRobinson/3063e9f20a177ce254dec5bcb794674e to your computer and use it in GitHub Desktop.
mailchimp segment mapper.js
'use strict'
/**
* Module dependencies.
*/
var object = require('obj-case')
var reject = require('reject')
var extend = require('extend')
var uncase = require('to-no-case')
var is = require('is')
/**
* Map `identify`.
*
* @param {Identify} track
* @return {Object}
* @api private
*/
exports.identify = function (identify) {
var opts = identify.options(this.name) || {}
var id = identify.userId()
var payload = {
settings: {
listId: opts.listId || this.settings.listId,
apiKey: this.settings.apiKey
},
userTraits: {
email_address: identify.email(),
merge_fields: formatTraits(identify)
}
}
// check if there is a custom subscription status provided
if (opts.subscriptionStatus) {
var validStatuses = ['pending', 'subscribed', 'unsubscribed', 'cleaned']
if (validStatuses.indexOf(opts.subscriptionStatus) !== -1) {
payload.userTraits.status = opts.subscriptionStatus
}
}
// https://us1.api.mailchimp.com/schema/3.0/Lists/Members/Instance.json
// unique identifier for email across Mailchimp
if (id) payload.userTraits.unique_email_id = id
// http://developer.mailchimp.com/documentation/mailchimp/reference/lists/members/
// set the default language
if (identify.proxy('context.locale')) {
payload.userTraits.language = language(identify.proxy('context.locale'))
}
return payload
}
/**
* Format the traits from the identify
*
* @param {Identify} identify
* @return {Object}
* @api private
*/
function formatTraits (identify) {
var traits = identify.traits() || {}
// http://kb.mailchimp.com/article/all-the-merge-tags-cheatsheet
extend(traits, {
FNAME: identify.firstName(),
LNAME: identify.lastName()
})
// :( https://github.com/segmentio/integration-mailchimp/issues/4
// MC merge fields key must be under 10 chars
// Boolean values are not handled well by MC so send as strings
traits = Object.keys(traits).reduce(function (ret, trait) {
var formattedKey = _case(trait)
var formattedValue = stringify(traits[trait])
formattedKey.length < 10
? ret[formattedKey] = formattedValue
: ret[formattedKey.substring(0, 10)] = formattedValue
return ret
}, {})
// Remove possible duplicate properties.
object.del(traits, 'firstName')
object.del(traits, 'lastName')
object.del(traits, 'email')
object.del(traits, 'ID')
for (var key in traits) {
if (traits.hasOwnProperty(key)) {
if (Array.isArray(traits[key])) traits[key] = JSON.stringify(traits[key])
}
}
// remove nested objects
return reject.type(traits, 'object')
}
/**
* Returns the language part of a locale
*/
function language (locale) {
if (!locale) return
return locale.substring(0, 2)
}
/**
* Case correctly for mailchimp merge tags
* Strip all spaces and punctuation
*/
function _case (trait) {
return uncase(trait.replace(/\s+/g, ''))
.replace(/\s+/g, '')
.toUpperCase()
}
/**
* Turn boolean types or null objects to strings
*
* @param {string,boolean,null} trait
* @return {string} [trait]
*/
function stringify (trait) {
return is.boolean(trait) || trait === null ? String(trait) : trait
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment