chillywilly
chillywilly

Reputation: 424

Mailchimp API 3.0 how to detect already unsubscribed

The Mailchimp API returns error 400 if I try to subscribe a user that is already subscribed. Then I found that if I unsubscribe and attempt to resubscribe again I also get error 400. Is there a way to differentiate between these cases?

Mailchimp's error documentation says that 400 is returned for different reasons (bad request, invalid resource, invalid action, JSON parse exception). There doesn't seem to be a way to get more specific messages, and certainly no way to determine whether the issue is that user is already subscribed vs. recently unsubscribed.

Any idea how to return more useful error messages?

Here is my test code (based on this reference):

<?php
$statusMsg = '';

if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['subscribe'])) {
  if (!empty($_POST['email']) && !filter_var($_POST['email'], FILTER_VALIDATE_EMAIL) === false) {
    // input sanitation
    array_walk_recursive($_POST, function(&$value) {
      $value = htmlspecialchars(stripslashes(trim($value)));
    });

    $fname = $_POST['fname'];
    $lname = $_POST['lname'];
    $email = $_POST['email'];

    // MailChimp API credentials
    $apiKey = '<my test API key>';
    $listId = '<my list id>';

    // MailChimp API URL
    $dataCenter = substr($apiKey,strpos($apiKey,'-') + 1);
    $url = 'https://' . $dataCenter . '.api.mailchimp.com/3.0/lists/' . $listId . '/members/';

    // member information
    $json = json_encode([
      'email_address' => $email,
      'status' => 'subscribed',
      'merge_fields' => [
        'FNAME' => $fname,
        'LNAME' => $lname
      ]
    ]);

    // send a HTTP POST request with curl
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_USERPWD, 'user:' . $apiKey);
    curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, 10);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
    $result = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    // store the status message based on response code
    if ($httpCode == 200) {
      $statusMsg = '<p style="color: #34A853">You have successfully subscribed.</p>';
    } else {
      switch ($httpCode) {
        case 400: // problem: this also happens when user is unsubscribed
          $msg = 'You are already subscribed.';
          break;
        default:
          $msg = 'Some problem occurred, please try again. Error code ' . $httpCode . '.';
          break;
      }
      $statusMsg = '<p style="color: red;">'.$msg.'</p>';
    }
  } else {
    $statusMsg = '<p style="color: red;">Please enter valid email address.</p>';
  }
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Mailchimp API Test</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main>
    <div id="container">
      <h1>Subscribe to our Newsletter</h1>
      <?php echo $statusMsg; ?>
      <form method="post">
        <input type="text" name="subscribe" value="subscribe" aria-hidden="true" readonly hidden>
        <p><label for="fname"> First Name:</label><br>
        <input id="fname" type="text" name="fname" /></p>
        <p><label for="lname"> Last Name:</label><br>
        <input id="lname" type="text" name="lname" /></p>
        <p><label for="email"> Email address:</label><br>
        <input id="email" type="text" name="email" /></p>
        <input type="submit" value="Submit" />
      </form>
    </div>
  </main>
</body>
</html>

Upvotes: 1

Views: 235

Answers (0)

Related Questions