-
-
Save skatkov/b524a6e60a5313acc4d299471a2a3902 to your computer and use it in GitHub Desktop.
MAILCHIMP_API_KEY="...-us19" | |
MAILCHIMP_LIST_ID="..." |
import { parse } from 'querystring' | |
const axios = require('axios'); | |
const mailChimpAPI = process.env.MAILCHIMP_API_KEY; | |
const mailChimpListID = process.env.MAILCHIMP_LIST_ID; | |
exports.handler = (event, context, callback) => { | |
let body = {} | |
console.log(event) | |
try { | |
body = JSON.parse(event.body) | |
} catch (e) { | |
body = parse(event.body) | |
} | |
if (!body.email) { | |
console.log('missing email') | |
return callback(null, { | |
statusCode: 400, | |
body: JSON.stringify({ | |
error: 'missing email' | |
}) | |
}) | |
} | |
if (!mailChimpAPI) { | |
console.log('missing mailChimpAPI key') | |
return callback(null, { | |
statusCode: 400, | |
body: JSON.stringify({ | |
error: 'missing mailChimpAPI key' | |
}) | |
}) | |
} | |
if (!mailChimpListID) { | |
console.log('missing mailChimpListID key') | |
return callback(null, { | |
statusCode: 400, | |
body: JSON.stringify({ | |
error: 'missing mailChimpListID key' | |
}) | |
}) | |
} | |
const data = { | |
email_address: body.email, | |
status: "pending", | |
merge_fields: {} | |
}; | |
const subscriber = JSON.stringify(data); | |
console.log("Sending data to mailchimp", subscriber); | |
// Subscribe an email | |
axios( | |
{ | |
method: 'post', | |
url: `https://us19.api.mailchimp.com/3.0/lists/${mailChimpListID}/members/`, //change region (us19) based on last values of ListId. | |
data: subscriber, | |
auth: { | |
username: 'apikey', // any value will work | |
password: mailChimpAPI | |
} | |
} | |
).then(function(response){ | |
console.log(`status:${response.status}` ) | |
console.log(`data:${response.data}` ) | |
console.log(`headers:${response.headers}` ) | |
if (response.headers['content-type'] === 'application/x-www-form-urlencoded') { | |
// Do redirect for non JS enabled browsers | |
return callback(null, { | |
statusCode: 302, | |
headers: { | |
Location: '/thanks.html', | |
'Cache-Control': 'no-cache', | |
}, | |
body: JSON.stringify({}) | |
}); | |
} | |
// Return data to AJAX request | |
return callback(null, { | |
statusCode: 200, | |
body: JSON.stringify({ emailAdded: true }) | |
}) | |
}).catch(function(error) { | |
if (error.response) { | |
// The request was made and the server responded with a status code | |
// that falls out of the range of 2xx | |
console.log(error.response.data); | |
console.log(error.response.status); | |
console.log(error.response.headers); | |
} else if (error.request) { | |
// The request was made but no response was received | |
console.log(error.request); | |
} else { | |
// Something happened in setting up the request that triggered an Error | |
console.log('Error', error.message); | |
} | |
console.log(error.config); | |
}); | |
}; |
{ | |
"scripts": { | |
"start": "netlify-lambda serve source/lambda", | |
"build": "netlify-lambda build source/lambda" | |
}, | |
"dependencies": { | |
"axios": "^0.19.0", | |
"dotenv": "^8.1.0", | |
"netlify-lambda": "^1.6.3" | |
} | |
} |
<div id="message"></div> | |
<form id="newsletter" class="subscribe" action="/.netlify/functions/form-handler" method="post"> | |
<input type="email" id="inputEmail" name='email' placeholder="Enter email to subscribe for FREE" class="email" required autofocus> | |
<button class="button" type="submit">Subscribe</button> | |
</form> | |
<script> | |
var form = document.getElementById('newsletter'); | |
form.addEventListener("submit", function(e) { | |
e.preventDefault(); | |
email = document.getElementById('inputEmail').value; | |
submitEmail(email) | |
}); | |
function submitEmail(email) { | |
fetch('/.netlify/functions/form-handler', { | |
method: 'post', | |
body: JSON.stringify({ | |
email: email | |
}) | |
}).then(function(response) { | |
return response.json(); | |
}).then(function(data) { | |
console.log('data from function', data); | |
messageDiv = document.getElementById('message'); | |
messageDiv.innerText = 'Confirmation email has been sent!' | |
}); | |
}; | |
</script> |
I'm trying to deploy this on Netlify and running into an error: "SyntaxError: Cannot use import statement outside a module" with the form-handler.js. From what I understand this means that my build is not transpiled using netlify-lambda.
What does your netlify.toml look like for this gist?
@dejardine changing it to const { parse } = require('querystring');
should work without having to transpile the code
This is great! Thanks! I wonder how you would go about handling errors?
Currently, when submitting [email protected]
or an already subscribed email address I get this in the browser console:
POST http://localhost:8888/.netlify/functions/form-handler 500 (Internal Server Error)
VM4085:1 Uncaught (in promise) SyntaxError: Unexpected token T in JSON at position 0
And, a timeout when viewing the logs when netlify dev
is running: Task timed out after 10.00 seconds
Thank you for the tutorial and this code, it's been really helpful.
I don't know if something has changed since you wrote it, or if it has to do with my setup (using Astro and netlify), but the test for disabled javascript: if (response.headers['content-type'] === 'application/x-www-form-urlencoded') { ... }
isn't working for me. I tried a lot of combinations, but with javascript disabled in the browser, response.headers
always had a content-type
of application/json
, same as when javascript was enabled.
In order to distinguish form data submitted by ajax, I had the javascript add a field to the form data:
body: JSON.stringify({
email: email,
"js-submit": true, // form-handler.js can use this to determine whether to return a 302 redirect or a 200
})
This function was open source from https://www.fbacatalog.com project.
To find more details on this code and our porject -- read up dev.to community post https://dev.to/skatkov/jamstack-progressive-mailchimp-sign-up-form-with-netlify-13m3
Thanks for your interest!