Skip to content

Instantly share code, notes, and snippets.

@paulcollett
Last active May 2, 2020 00:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save paulcollett/3952b55fba234c6051df3a70fed2cdc8 to your computer and use it in GitHub Desktop.
Save paulcollett/3952b55fba234c6051df3a70fed2cdc8 to your computer and use it in GitHub Desktop.
Mailchimp client-side ajax subscribe request, returns promise
/**
* Mailchimp client-side ajax subscribe request promise
* @param {object} options
* @param {string} options.action Mailchimp subscribe form action url <form action="URL">
* @param {string} options.email email address
* @returns {Promise.<string, Error>} promise of a success message or an Error containing message
* @example
mailchimpSubscribeRequest({
action: 'https://blabla.us6.list-manage.com/subscribe/post?u=61f5z352da53ba442da9cb35&amp;id=02435aaa99',
email: 'my@email.test'
})
.then(res => {
alert(res) // success message (or please confirm on opt in)
})
.catch(err => {
alert(`Error\n${err.message}`)
})
*/
const mailchimpSubscribeRequest = ({ action, email }) => {
return Promise.resolve(action)
.then(parseUrl)
.then(src => {
return jsonpRequest(src, 'c', {
EMAIL: email,
// FNAME
})
})
.then(res => {
if(res.result === 'success') {
return res.msg;
} else if(res.msg) {
/*
based on: https://github.com/scdoshi/jquery-ajaxchimp/blob/master/jquery.ajaxchimp.js
Codes:
1 - Please enter a value
2 - An email address must contain a single @
3 - The domain portion of the email address is invalid (the portion after the @: )
4 - The username portion of the email address is invalid (the portion before the @: )
5 - This email address looks fake or invalid. Please enter a real email address
*/
const [ code, message ] = res.msg.split(' - ')
throw Object.assign(new Error(message), { code })
} else {
throw Object.assign('Unknown Response', { code: 0 })
}
})
}
// Converts embedded form action endpoint to jsonp endpoint
// https://blabla.us6.list-manage.com/subscribe/post?u=61f5z352da53ba442da9cb35&amp;id=02435aaa99
// Get url at: audience > signup forms > embedded forms
const parseUrl = mailchimpActionUrl => {
const url = new URL(mailchimpActionUrl);
url.protocol = 'https:'
url.pathname = url.pathname.replace('/post', '/post-json')
return url;
}
const jsonpRequest = (url, callbackParam = 'callback', params = {}) => new Promise((res, rej) => {
const objectToParams = obj => Object.keys(obj).map(k => [k, obj[k]].map(encodeURIComponent).join('=')).join('&')
const teardown = () => {
delete window[globalCallbackName]
script.remove()
}
const globalCallbackName = `cb${Date.now()}`
window[globalCallbackName] = response => {
res(response);
teardown()
}
const paramString = objectToParams({
...params,
[callbackParam]: globalCallbackName,
_: Date.now() // cache bust
})
const script = document.createElement('script')
script.onerror = () => {
rej(new Error('Request Error'))
teardown()
}
const src = new URL(url);
src.search = src.search ? `${src.search}&${paramString}` : paramString
script.src = src.toString()
document.head.appendChild(script)
})
export default mailchimpSubscribeRequest
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment