0

I am trying to update MailChimp members from Google Tag Manager, using MailChimp API v3.0, but I am having issues. This is my code, which I'm running from a real domain (not localhost), secured with a valid SSL certificate (if it matters).

const xmlHttp = new XMLHttpRequest();

xmlHttp.onreadystatechange = () => {
    try {
        if (xmlHttp.readyState !== 4) return;
        if (xmlHttp.status !== 200)
            throw new Error(
                xmlHttp.statusText || 'HTTP STATUS ' + xmlHttp.status
            );
        console.log(xmlHttp.responseText);
    } catch (err) {
        console.error(err);
    }
};

xmlHttp.open('POST', 'https://us12.api.mailchimp.com/3.0/lists/d5bed898ae/members/0740287eb1c63371a10d32ebf58391f9');
xmlHttp.setRequestHeader('Authorization', 'Basic ' + btoa('anystring' + ':' + 'my-api-key-here'));
xmlHttp.setRequestHeader('content-type', 'application/json');
xmlHttp.send('{"email_address":"user@example.com", "status":"subscribed", "member_rating":"4"}');

I get a CORS error:

Access to XMLHttpRequest at 'https://us12.api.mailchimp.com/3.0/lists/d5bed898ae/members/0740287eb1c63371a10d32ebf58391f9' from origin 'https://subdomain.example.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

What am I doing wrong?

UPDATE:

Note, I am not trying to add a new member, I am trying to update an existing one. Also, the API key is not visible, I am picking it up as a GTM variable. Also, the code is running on the domain, as GTM is loaded on the page.

Where am I supposed to run this code? On Mailchimp servers? What am I missing?

Ciprian
  • 872
  • 1
  • 10
  • 30

1 Answers1

2

First of all, EEK! You should never put a private API key in client-facing code, in this case in GTM. If a website visitor noticed, they could easily use your API key themselves to do pretty much whatever they wanted with your Mailchimp account, including deleting everything in it. From Mailchimp's docs:

API keys grant full access to your Mailchimp account and should be protected the same way you would protect your password.

If you have already put this code live, even just for a few minutes, you will want to immediately disable/revoke that API key and create a new one.


Second, the CORS error is because MailChimp specifically does not support API requests that originate in browsers from outside their own domain - e.g. Cross-Origin requests that require a proper CORS response header. The reason for this is the same as my warning above - you should not be making API calls from client-side code due to the inherent security risks. On the same MailChimp doc page, they repeat this warning:

Because of the potential security risks associated with exposing account API keys, Mailchimp does not support client-side implementation of our API using CORS requests or including API keys in mobile apps.

See this StackOverflow question for a similar discussion.


To address this, you need to have the actual API call come from actual server-side code. Most people would probably proxy the request through their own site - so if your site is example.com, you might have GTM make an AJAX call to example.com/mailchimp-proxy.php?action=update&list=d5bed898ae&user=0740287eb1c63371a10d32ebf58391f9&info=... and then that PHP script would in turn call the actual API endpoint of https://us12.api.mailchimp.com/3.0/... with the data. Because the code is running server-side, if you put your key in it properly, no one should be able to read it.

Another alternative is to use something like Zapier, or "serverless" functions, to proxy the request so you don't need to run your own server.

Joshua T
  • 2,439
  • 1
  • 10
  • 42
  • Thanks Joshua, I am not trying to add a new member, I am trying to update an existing one. Also, the API key is not visible, I am picking it up as a GTM variable. – Ciprian May 22 '19 at 09:01
  • Also, the code is running on the domain, as GTM is loaded on the page. Where am I supposed to run this code? On Mailchimp servers? What am I missing? – Ciprian May 22 '19 at 09:33
  • A) GTM variables are readable by anyone who loads the page the tag is on, just have to open inspector or another dev tool. and B) It was implied by my answer and the other SO answer I linked to, but I could be a little more explicit (I'll probably edit my answer above) - I think what you are missing is that you need to have the request come from an actual server. Most people would probably use their own server and "proxy" the request through it - so if your site is example.com, GTM requests example.com/updatemailchimp.php, which then in turn calls https://us12.api.mailchimp.com/3.0/ – Joshua T May 22 '19 at 17:51
  • I see. I can't use a proxy, as the server is C#. I'll pass this to the C# developer then. GTM variables are not readable by anyone outside GTM. You can declare a GTM variable from a data attribute or an API call, or an element on the page. GTM variables are only declared inside GTM, they do not exist outside. Thanks, I'll accept your answer. – Ciprian May 23 '19 at 11:17