11

When making this request:

// Subscribe a new account holder to a MailChimp list
function subscribeSomeoneToMailChimpList()
{
  var options =
  {
    "apikey": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "id": "xxxxxx",
    "email":
    {
      "email": "me@example.com"
    },
    "send_welcome": false
  };
  var mcSubscribeRequest = UrlFetchApp.fetch("https://us4.api.mailchimp.com/2.0/lists/subscribe.json", options);
  var mcListObject = Utilities.jsonParse(mcSubscribeRequest.getContentText());
}

This response is returned:

Request failed for https://us4.api.mailchimp.com/2.0/lists/subscribe.json returned code 500. Truncated server response: {"status":"error","code":-100,"name":"ValidationError","error":"You must specify a apikey value"} (use muteHttpExceptions option to examine full response) (line 120, file "v2")

Line 120 is the line on which UrlFetchApp.fetch is called.

The API key is valid (I have tested with simpler API calls that don't include associative arrays). When I append the API key directly to the base URL and remove it from the options, I get an error saying that the list ID is invalid. When I then append the list ID directly to the base URL and remove it from options, I get an error saying that the email address must be in associative array form.

My question is: Using the above format, how does one send requests that contain associative arrays?

The relevant API documentation can be found here.

barryedmund
  • 612
  • 2
  • 9
  • 18
  • 5
    Bad idea to expose your API key in your client side code :( – Maxim Feb 13 '14 at 23:54
  • @Maxim, this code is used in a private Google Script. Is that still risky? – barryedmund Feb 18 '14 at 01:47
  • I'm not sure how Google protect it but I guest it's good enough. It all depends on how much security do you need. In some cases I would even encrypt the password in my server side code. – Maxim Feb 18 '14 at 21:27
  • 3
    The title of this question is more accurately Google App Script + MailChimp API. Otherwise, someone newer to Javascript may end up using the answer in client- side code, thus exposing their MailChimp API. – makstaks Feb 07 '19 at 03:41

3 Answers3

21

After further research & tinkering, I was able to solve this:

https://<dc>.api.mailchimp.com/2.0/lists/subscribe.json?apikey=<my_api_key>&id=<my_list_id>&email[email]=test@test.com&merge_vars[FNAME]=John&merge_vars[LNAME]=Doe&double_optin=false&send_welcome=false

Where <dc> should be replaced with the portion after the dash in your API Key. e.g. "us1", "us2", "uk1", etc.

Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
barryedmund
  • 612
  • 2
  • 9
  • 18
8

Doing this in javascript exposes your API key to the world. If someone has your key, he/she can make changes to or gain access to your account.

John Proestakes
  • 317
  • 2
  • 5
0

I think I figured out what is going on after reading through the UrlFetchApp.fetch Docs. https://developers.google.com/apps-script/reference/url-fetch/url-fetch-app?csw=1#fetch(String)

It looks like you should be using some of the extra params to do the request such as payload and method. Your options variable should look like this.

  var payload =   {
    "apikey": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "id": "xxxxxx",
    "email": {
      "email": "me@example.com"
    },
    "send_welcome": false
  };
  payload = Utilities.jsonStringify(payload); // the payload needs to be sent as a string, so we need this
  var options = {
     method: "post",
     contentType: "application/json", // contentType property was mistyped as ContentType - case matters
     payload: payload
  }; 
  var result = UrlFetchApp.fetch("https://<dc>.api.mailchimp.com/2.0/lists/subscribe.json", options);

Where <dc> should be replaced with the portion after the dash in your API Key. e.g. "us1", "us2", "uk1", etc.

The issue is that your options variable is suppose to be used as JSON and not as a GET url parameter. Also mailchimp specifies that it is better to use POST instead of GET. So over all you should make sure to set you method to "post" and make sure your payload is valid JSON.

maresmar
  • 1,449
  • 14
  • 21
jjbskir
  • 8,474
  • 9
  • 40
  • 53