Skip to content

Instantly share code, notes, and snippets.

@xdmorgan
Last active October 5, 2019 14:19
Show Gist options
  • Save xdmorgan/9eff1bad6aeb1fa4d9dda81f8a7b2146 to your computer and use it in GitHub Desktop.
Save xdmorgan/9eff1bad6aeb1fa4d9dda81f8a7b2146 to your computer and use it in GitHub Desktop.
const Mailchimp = require("mailchimp-api-v3");
const validate = require("./validations");
const { MAILCHIMP_API_KEY } = process.env;
exports.handler = async (event, context) => {
// require an API key or throw everytime
const [is_valid_env, invalid_env_response] = check_env(process.env);
if (!is_valid_env) return invalid_env_response;
// 0. validate request body
const [body, is_valid_body, invalid_body_response] = check_body(event.body);
// 0b. Return 400 - Bad request
if (!is_valid_body) return invalid_body_response;
// 0a. Continue;
const { email, list_id, interests = [] } = body;
// 1. Create API instance
const mc_api = new Mailchimp(MAILCHIMP_API_KEY);
// 2. Already a member?
const check_opts = { email, list_id };
const [is_member, is_subscribed, exists_response] = await check_member_exists(
check_opts,
mc_api
);
// 2a. If they are, are they subscribed status?
// 2aa. Great! DONE 200
if (is_member && is_subscribed) return exists_response;
// 2ab. PUT to update status as 'subscribed'. DONE 200
if (is_member && !is_subscribed) {
const update_opts = { email, list_id, status: "subscribed", interests };
const [updated_response] = await update_member(update_opts, mc_api);
return updated_response;
}
// 2b. If they're not, continue;
// 3. Create list member
const create_opts = { email, list_id, interests };
const [created, create_succeeded, create_failed] = await create_member(
create_opts,
mc_api
);
// 3a. If succeeds, DONE 200
return created ? create_succeeded : create_failed;
// 3b. If fails, return 500
};
function check_env({ MAILCHIMP_API_KEY } = {}) {
const is_valid = !!MAILCHIMP_API_KEY;
const response = { statusCode: 500, message: "missing env vars" };
return [is_valid, response];
}
function check_body(request_body) {
const body = JSON.parse(request_body);
const is_valid = true; // check email, check list_id
const response = { statusCode: 400, message: "invalid request" };
return [body, is_valid, response];
}
async function check_member_exists({ email, list_id }, api) {
const is_member = true;
const is_subscribed = false;
const response = { statusCode: 200, message: "already subscribed" };
return [is_member, is_subscribed, response];
}
async function update_member({ email, list_id, status, interests }, api) {
const request = create_request_body({ email, list_id, status, interests });
const response = { statusCode: 200, message: "subscription updated" };
return [response];
}
async function create_member({ email, list_id, status, interests }, api) {
const request = create_request_body({ email, list_id, status, interests });
const success_response = { statusCode: 200, message: "create succeeded" };
const error_response = { statusCode: 500, message: "create failed" };
return [success_response, error_response];
}
function create_request_body({
email = "",
interests = [],
status = "subscribed",
merge_fields = {}
} = {}) {
return {
email_address: email,
status,
merge_fields,
interests: interests.reduce((acc, cur) => ({ ...acc, [cur]: true }), {})
};
}
@xdmorgan
Copy link
Author

xdmorgan commented Oct 5, 2019

The general approach. For the implementation, see my Netlify functions repo: https://github.com/xdmorgan/netlify-functions/blob/master/functions/mailchimp-subscribe/README.md

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment