Andrew Newby
Andrew Newby

Reputation: 5197

Mailchimp v3.0 API, using Perl Curl

I'm trying to find a way to do a Curl request to MailChimps new API v3.0, that will subscribe a user to a given list. Here is what I have thus far:

use warnings;
use WWW::Curl::Easy;
use JSON;

my $apikey = 'xxxx';
my $listid = 'xxxx';
my $email = '[email protected]';
my $endpoint = "https://us6.api.mailchimp.com/3.0/lists";

my $json = JSON::encode_json([
    'email_address' => $email,
    'status'        => 'pending',
    'merge_fields'  => [
        'FNAME'     => "andy",
        'LNAME'     => "newby"
    ]
]);

my $curl = WWW::Curl::Easy->new;

my $url = "$endpoint/$listid/members/" . Digest::MD5::md5(lc($email));

$curl->setopt(CURLOPT_HEADER,1);
$curl->setopt(CURLOPT_URL, $endpoint);

$curl->setopt(CURLOPT_USERPWD, 'user:' . $apikey);
$curl->setopt(CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
$curl->setopt(CURLOPT_TIMEOUT, 10);
$curl->setopt(CURLOPT_CUSTOMREQUEST, 'PUT');
$curl->setopt(CURLOPT_SSL_VERIFYPEER, 0);
$curl->setopt(CURLOPT_POSTFIELDS, $json);

my $response_body;
$curl->setopt(CURLOPT_WRITEDATA,\$response_body);

# Starts the actual request
my $retcode = $curl->perform;

# Looking at the results...
if ($retcode == 0) {
        print("Transfer went ok\n");
        my $response_code = $curl->getinfo(CURLINFO_HTTP_CODE);
        print "Received response: $response_body\n";
} else {
        # Error code, type of error, error message
        print "An error happened: $retcode ".$curl->strerror($retcode)." ".$curl->errbuf."\n";
}

The documentation is pretty scarce, due to it being a new API. Has anyone had any success with the MailChimp v3 API, for subscribing someone in Perl? (I'm also open to suggestions for command line curl requests... but everything I tried with regards to that, failed with "internal server errors" coming back from MailChimp, which wasn't very helpful)

UPDATE: As suggested below, I enabled verbose, and it now spits out:

  • Hostname was NOT found in DNS cache
  • Trying 184.86.100.251...
  • Connected to us6.api.mailchimp.com (184.86.100.251) port 443 (#0)
  • successfully set certificate verify locations:
  • CAfile: none CApath: /etc/ssl/certs
  • SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
  • Server certificate:
  • subject: C=US; ST=GA; L=Atlanta; O=ROCKET SCIENCE GROUP; OU=Rocket Science Group; CN=*.api.mailchimp.com
  • start date: 2015-09-22 14:39:14 GMT
  • expire date: 2016-09-22 14:39:13 GMT
  • subjectAltName: us6.api.mailchimp.com matched
  • issuer: C=NL; L=Amsterdam; O=Verizon Enterprise Solutions; OU=Cybertrust; CN=Verizon Akamai SureServer CA G14-SHA2
  • SSL certificate verify ok.
  • Server auth using Basic with user 'user'

    PUT /3.0/lists HTTP/1.1 Authorization: Basic xxxx Host: us6.api.mailchimp.com Accept: / Content-Type: application/json Content-Length: 108

  • upload completely sent off: 108 out of 108 bytes < HTTP/1.1 405 Method Not Allowed

  • Server nginx is not blacklisted < Server: nginx < Content-Type: application/problem+json; charset=utf-8 < Content-Length: 253 < X-Request-Id: 5f6ab08f-69e7-4c9b-b22a-91714331d5b7 < Link: https://us6.api.mailchimp.com/schema/3.0/ProblemDetailDocument.json; rel="describedBy" < Allow: GET, POST < Date: Tue, 13 Oct 2015 11:24:32 GMT < Connection: close < Set-Cookie: _AVESTA_ENVIRONMENT=prod; path=/ <
  • Closing connection 0 Transfer went ok Received response: HTTP/1.1 405 Method Not Allowed Server: nginx Content-Type: application/problem+json; charset=utf-8 Content-Length: 253 X-Request-Id: 5f6ab08f-69e7-4c9b-b22a-91714331d5b7 Link: https://us6.api.mailchimp.com/schema/3.0/ProblemDetailDocument.json; rel="describedBy" Allow: GET, POST Date: Tue, 13 Oct 2015 11:24:32 GMT Connection: close Set-Cookie: _AVESTA_ENVIRONMENT=prod; path=/

{"type":"http://kb.mailchimp.com/api/error-docs/405-method-not-allowed","title":"Method Not Allowed","status":405,"detail":"The requested method and resource are not compatible. See the Allow header for this resource's available methods.","instance":""}

I'm not really sure what to make of that though :/

Working code: Thanks to TooMuchPete, I managed to get it going. For anyone who may come across this while trying to use the MailChimp API (3.0) in Perl, below is a working sample (you just need to replace the values of the email, name, api key, and list id);

    use WWW::Curl::Easy;
    use JSON;
    use Digest::MD5;

    my $apikey = 'xxxx-us6';
    my $listid = 'xxxx';
    my $email = '[email protected]';
    my $endpoint = "https://us6.api.mailchimp.com/3.0/lists";

    my $json = JSON::encode_json({
        'email_address' => $email,
        'status'        => 'pending',
        'merge_fields'  => {
            'FNAME'     => "andy",
            'LNAME'     => "newby"
        }
    });

    my $curl = WWW::Curl::Easy->new;

    my $url = "$endpoint/$listid/members/" . Digest::MD5::md5(lc($email));

    $curl->setopt(CURLOPT_HEADER,1);
    $curl->setopt(CURLOPT_URL, $url);

    $curl->setopt(CURLOPT_VERBOSE, 1);
    $curl->setopt(CURLOPT_USERPWD, 'user:' . $apikey);
    $curl->setopt(CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
    $curl->setopt(CURLOPT_TIMEOUT, 10);
    $curl->setopt(CURLOPT_CUSTOMREQUEST, 'PUT');
    $curl->setopt(CURLOPT_SSL_VERIFYPEER, 0);
    $curl->setopt(CURLOPT_POSTFIELDS, $json);

    # A filehandle, reference to a scalar or reference to a typeglob can be used here.
    my $response_body;
    $curl->setopt(CURLOPT_WRITEDATA,\$response_body);

    # Starts the actual request
    my $retcode = $curl->perform;

    # Looking at the results...
    if ($retcode == 0) {
            print("Transfer went ok\n");
            my $response_code = $curl->getinfo(CURLINFO_HTTP_CODE);
            # judge result and next action based on $response_code
            print "Received response: $response_body\n";
    } else {
            # Error code, type of error, error message
            print "An error happened: $retcode ".$curl->strerror($retcode)." ".$curl->errbuf."\n";
    }

I hope this saves someone the grief I had :)

Upvotes: 2

Views: 2120

Answers (2)

Scott Hillman
Scott Hillman

Reputation: 11

I received an illegal characters response from MailChimp using the code above until I switched to the md5_base64() call.

Upvotes: 0

TooMuchPete
TooMuchPete

Reputation: 4643

You're attempting to connect to $endpoint instead of $url.

my $url = "$endpoint/$listid/members/" . Digest::MD5::md5(lc($email));

$curl->setopt(CURLOPT_HEADER,1);
$curl->setopt(CURLOPT_URL, $endpoint);

should be:

my $url = "$endpoint/$listid/members/" . Digest::MD5::md5(lc($email));

$curl->setopt(CURLOPT_HEADER,1);
$curl->setopt(CURLOPT_URL, $url);

Upvotes: 2

Related Questions