使用Mailchimp的API v3将订阅者添加到列表中

68

我想把用户添加到我在Mailchimp创建的列表中,但我无法在任何地方找到代码示例。我尝试弄清楚如何使用API,但我非常希望能够“查看示例并学习”。

我尝试使用API的2.0版本,但是尽管从网上和Mailchimp的示例中工作,但似乎什么也不起作用,而且Mailchimp在其网站上关于早期版本API的说明如下:

2.0版本及更早版本已过时。对于这些版本,只提供最低限度的支持 - bug修复,安全补丁。

更新1:根据TooMuchPete的答案有关管理订阅者链接的进一步研究,我修改了一些代码,我在这里找到了一些代码,但它不起作用,因为函数http_build_query()不能处理嵌套数组。我不确定如何处理添加订阅者的'merge_fields'部分。我的当前代码如下:

$postdata = http_build_query(
                    array(
                        'apikey'        => $apikey,
                        'email_address' => $email,
                        'status'        => 'subscribed',
                        'merge_fields'  => array(
                            'FNAME' => $name
                        )
                    )
                );

                $opts = array('http' =>
                    array(
                        'method'  => 'POST',
                        'header'  => 'Content-type: application/x-www-form-urlencoded',
                        'content' => $postdata
                    )
                );

                $context  = stream_context_create($opts);

                $result = file_get_contents('https://us2.api.mailchimp.com/3.0/lists/<list_id>/members/', false, $context);

                var_dump($result);
                die('Mailchimp executed');

更新2:我现在已经转而使用curl,并成功地实现了几乎可以工作的内容。数据已通过发送至Mailchimp,但是我收到了错误"Your request did not include an API key."。我猜测我需要进行身份验证,就像在这里所提到的一样。我尝试将其添加到HTTP头中,但并没有起作用。请参见下面的代码:

$apikey = '<api_key>';
                $auth = base64_encode( 'user:'.$apikey );

                $data = array(
                    'apikey'        => $apikey,
                    'email_address' => $email,
                    'status'        => 'subscribed',
                    'merge_fields'  => array(
                        'FNAME' => $name
                    )
                );
                $json_data = json_encode($data);

                $ch = curl_init();
                curl_setopt($ch, CURLOPT_URL, 'https://us2.api.mailchimp.com/3.0/lists/<list_id>/members/');
                curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json/r/n
                                                            Authorization: Basic '.$auth));
                curl_setopt($ch, CURLOPT_USERAGENT, 'PHP-MCAPI/2.0');
                curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
                curl_setopt($ch, CURLOPT_TIMEOUT, 10);
                curl_setopt($ch, CURLOPT_POST, true);
                curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
                curl_setopt($ch, CURLOPT_POSTFIELDS, $json_data);                                                                                                                  

                $result = curl_exec($ch);

                var_dump($result);
                die('Mailchimp executed');

v2.0仍然绝对可用。实际上,v1.3也是如此--但如果您正在寻找API v3.0示例,我建议您查看这个GitHub存储库。现在它只有Python,但这可能足以让您朝着正确的方向前进。文档中还有一个关于管理订阅者的页面,这是一步远离实际代码示例,但仍可能有所帮助。 - TooMuchPete
谢谢@TooMuchPete。我已经更新了我的问题,并提供了代码示例。我觉得我慢慢地接近答案了。 - VenomRush
我正在寻找Python中API v3.0的示例,而不仅仅是基本的GET请求。那个GitHub存储库中的示例很糟糕,抱歉。 - Colin 't Hart
GET请求和POST请求在实质上并没有太大的区别。一个有主体,一个没有。结合Python Requests文档,我不确定其他人需要什么才能开始。这些示例绝对不是为那些寻找复制粘贴解决方案或库的人准备的。 - TooMuchPete
MailChimp目前表示他们将在2016年之后停止支持3.0版本之前的版本。 - William Turrell
6个回答

136

根据列表成员实例文档,最简单的方法是使用一个PUT请求,根据文档的说明,它可以"添加新的列表成员或者如果邮箱已经存在于列表中则更新成员"

此外,apikey明确不是json模式的一部分,在您的json请求中包含它是没有意义的。

如@TooMuchPete的评论中所述,您可以使用CURLOPT_USERPWD进行基本的HTTP认证,如下所示。

我正在使用以下函数来添加和更新列表成员。根据您的列表参数,您可能需要包含略微不同的merge_fields集合。

$data = [
    'email'     => 'johndoe@example.com',
    'status'    => 'subscribed',
    'firstname' => 'john',
    'lastname'  => 'doe'
];

syncMailchimp($data);

function syncMailchimp($data) {
    $apiKey = 'your api key';
    $listId = 'your list id';

    $memberId = md5(strtolower($data['email']));
    $dataCenter = substr($apiKey,strpos($apiKey,'-')+1);
    $url = 'https://' . $dataCenter . '.api.mailchimp.com/3.0/lists/' . $listId . '/members/' . $memberId;

    $json = json_encode([
        'email_address' => $data['email'],
        'status'        => $data['status'], // "subscribed","unsubscribed","cleaned","pending"
        'merge_fields'  => [
            'FNAME'     => $data['firstname'],
            'LNAME'     => $data['lastname']
        ]
    ]);

    $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, 'PUT');
    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);

    return $httpCode;
}

1
感谢@billynoah。我只是接受了自己的答案,因为这是我设法让它工作的方式,没有其他人提供一个可行的例子。 - VenomRush
4
好的,您仍然可以使用POST方式,但是需要在不同的端点上进行(没有ID)。根据API文档:通过向/lists/{list_id}/members发送POST请求或向/lists/{list_id}/members/{id}发送PUT请求创建一个新记录。通过向/lists/{list_id}/members/{id}发送DELETE请求删除一条记录。 - aborted
1
@ToniMichelCaubet - 据我所知,文档中没有提供一种同时更新或添加多个成员的方法。我认为您需要为每个要添加/编辑的成员发送单独的请求。 - But those new buttons though..
3
如果您收到404错误(请求的资源无法找到),则可能使用了错误的列表ID(请记住它不是浏览器URL中的那个,但包含字母和数字)。如果您收到400错误,则应检查数据数组。也许状态字段不包含字符串? - Stefan
1
如果您不更改“johndoe”邮件,您也将收到400错误。 - HaReL
显示剩余9条评论

26

我搞定了。我之前是错误地把身份验证添加到了页眉中:

$apikey = '<api_key>';
            $auth = base64_encode( 'user:'.$apikey );

            $data = array(
                'apikey'        => $apikey,
                'email_address' => $email,
                'status'        => 'subscribed',
                'merge_fields'  => array(
                    'FNAME' => $name
                )
            );
            $json_data = json_encode($data);

            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, 'https://us2.api.mailchimp.com/3.0/lists/<list_id>/members/');
            curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json',
                                                        'Authorization: Basic '.$auth));
            curl_setopt($ch, CURLOPT_USERAGENT, 'PHP-MCAPI/2.0');
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_TIMEOUT, 10);
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $json_data);                                                                                                                  

            $result = curl_exec($ch);

            var_dump($result);
            die('Mailchimp executed');

2
太酷了!你也可以像这样进行身份验证: url_setopt($ch, CURLOPT_USERPWD, "user:" . $apikey); - TooMuchPete
这是否进行了base64编码?Mailchimp要求进行编码。 - VenomRush
1
MailChimp API v3.0使用HTTP基本身份验证,这就是cURL选项的作用。 Base64编码只是基本身份验证的一部分。 - TooMuchPete
1
我已经使用提供的代码,但仍然没有成功,我总是得到一个“资源未找到”的错误。有人可以让这个工作吗? - Federico Vezzoli
4
如果有人试图使用@VenomRush的代码但出现问题了,可能需要针对你的账户调整数据中心(在CURLOPT_URL行中以us2表示)。可以通过查看API密钥的最后一部分来获取账户的数据中心。更多信息请参考:http://developer.mailchimp.com/documentation/mailchimp/guides/get-started-with-mailchimp-api-3/#resources - ScottD
显示剩余4条评论

9
这些都是好的答案,但是缺少一个完整的答案来介绍如何让表单发送数据并处理响应。这将演示如何通过jquery .ajax()从HTML页面使用API v3.0向列表中添加成员。
在Mailchimp中:
  1. 获取您的API密钥列表ID
  2. 确保设置好您的列表以及想要使用的自定义字段。在这种情况下,我在进行API调用之前已经将zipcode设置为列表中的自定义字段。
  3. 查看关于添加列表成员的API文档。我们使用的是需要使用HTTP POST请求的create方法。此处还有其他选项,如果您想要能够修改/删除订阅者,则需要使用PUT
HTML:
<form id="pfb-signup-submission" method="post">
  <div class="sign-up-group">
    <input type="text" name="pfb-signup" id="pfb-signup-box-fname" class="pfb-signup-box" placeholder="First Name">
    <input type="text" name="pfb-signup" id="pfb-signup-box-lname" class="pfb-signup-box" placeholder="Last Name">
    <input type="email" name="pfb-signup" id="pfb-signup-box-email" class="pfb-signup-box" placeholder="youremail@example.com">
    <input type="text" name="pfb-signup" id="pfb-signup-box-zip" class="pfb-signup-box" placeholder="Zip Code">
  </div>
  <input type="submit" class="submit-button" value="Sign-up" id="pfb-signup-button"></a>
  <div id="pfb-signup-result"></div>
</form>

关键点:

  1. 给你的<form>一个唯一的ID,并不要忘记添加method="post"属性,以便表单正常工作。
  2. 注意最后一行#signup-result是你将从PHP脚本中获取反馈的地方。

PHP:

<?php
  /*
   * Add a 'member' to a 'list' via mailchimp API v3.x
   * @ http://developer.mailchimp.com/documentation/mailchimp/reference/lists/members/#create-post_lists_list_id_members
   *
   * ================
   * BACKGROUND
   * Typical use case is that this code would get run by an .ajax() jQuery call or possibly a form action
   * The live data you need will get transferred via the global $_POST variable
   * That data must be put into an array with keys that match the mailchimp endpoints, check the above link for those
   * You also need to include your API key and list ID for this to work.
   * You'll just have to go get those and type them in here, see README.md
   * ================
   */

  // Set API Key and list ID to add a subscriber
  $api_key = 'your-api-key-here';
  $list_id = 'your-list-id-here';

  /* ================
   * DESTINATION URL
   * Note: your API URL has a location subdomain at the front of the URL string
   * It can vary depending on where you are in the world
   * To determine yours, check the last 3 digits of your API key
   * ================
   */
  $url = 'https://us5.api.mailchimp.com/3.0/lists/' . $list_id . '/members/';

  /* ================
   * DATA SETUP
   * Encode data into a format that the add subscriber mailchimp end point is looking for
   * Must include 'email_address' and 'status'
   * Statuses: pending = they get an email; subscribed = they don't get an email
   * Custom fields go into the 'merge_fields' as another array
   * More here: http://developer.mailchimp.com/documentation/mailchimp/reference/lists/members/#create-post_lists_list_id_members
   * ================
   */
  $pfb_data = array(
    'email_address' => $_POST['emailname'],
    'status'        => 'pending',
    'merge_fields'  => array(
      'FNAME'       => $_POST['firstname'],
      'LNAME'       => $_POST['lastname'],
      'ZIPCODE'     => $_POST['zipcode']
    ),
  );

  // Encode the data
  $encoded_pfb_data = json_encode($pfb_data);

  // Setup cURL sequence
  $ch = curl_init();

  /* ================
   * cURL OPTIONS
   * The tricky one here is the _USERPWD - this is how you transfer the API key over
   * _RETURNTRANSFER allows us to get the response into a variable which is nice
   * This example just POSTs, we don't edit/modify - just a simple add to a list
   * _POSTFIELDS does the heavy lifting
   * _SSL_VERIFYPEER should probably be set but I didn't do it here
   * ================
   */
  curl_setopt($ch, CURLOPT_URL, $url);
  curl_setopt($ch, CURLOPT_USERPWD, 'user:' . $api_key);
  curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($ch, CURLOPT_TIMEOUT, 10);
  curl_setopt($ch, CURLOPT_POST, 1);
  curl_setopt($ch, CURLOPT_POSTFIELDS, $encoded_pfb_data);
  curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

  $results = curl_exec($ch); // store response
  $response = curl_getinfo($ch, CURLINFO_HTTP_CODE); // get HTTP CODE
  $errors = curl_error($ch); // store errors

  curl_close($ch);

  // Returns info back to jQuery .ajax or just outputs onto the page

  $results = array(
    'results' => $result_info,
    'response' => $response,
    'errors' => $errors
  );

  // Sends data back to the page OR the ajax() in your JS
  echo json_encode($results);
?>

关键点:

  1. CURLOPT_USERPWD 处理 API 密钥,而 Mailchimp 并没有提供详细说明。
  2. CURLOPT_RETURNTRANSFER 以一种我们可以使用 .ajax()success 处理程序将其响应发送回 HTML 页面的方式进行返回。
  3. 对接收到的数据使用 json_encode 进行编码。

JS:

// Signup form submission
$('#pfb-signup-submission').submit(function(event) {
  event.preventDefault();

  // Get data from form and store it
  var pfbSignupFNAME = $('#pfb-signup-box-fname').val();
  var pfbSignupLNAME = $('#pfb-signup-box-lname').val();
  var pfbSignupEMAIL = $('#pfb-signup-box-email').val();
  var pfbSignupZIP = $('#pfb-signup-box-zip').val();

  // Create JSON variable of retreived data
  var pfbSignupData = {
    'firstname': pfbSignupFNAME,
    'lastname': pfbSignupLNAME,
    'email': pfbSignupEMAIL,
    'zipcode': pfbSignupZIP
  };

  // Send data to PHP script via .ajax() of jQuery
  $.ajax({
    type: 'POST',
    dataType: 'json',
    url: 'mailchimp-signup.php',
    data: pfbSignupData,
    success: function (results) {
      $('#pfb-signup-box-fname').hide();
      $('#pfb-signup-box-lname').hide();
      $('#pfb-signup-box-email').hide();
      $('#pfb-signup-box-zip').hide();
      $('#pfb-signup-result').text('Thanks for adding yourself to the email list. We will be in touch.');
      console.log(results);
    },
    error: function (results) {
      $('#pfb-signup-result').html('<p>Sorry but we were unable to add you into the email list.</p>');
      console.log(results);
    }
  });
});

关键要点:

  1. JSON 数据在传输过程中非常敏感。在这里,我将其放入数组中,看起来很简单。如果您遇到问题,可能是由于您的 JSON 数据结构有问题。请检查一下!
  2. 您的 JSON 数据的键将成为您在 PHP _POST 全局变量中引用的内容。在此示例中,它将是_POST['email']_POST['firstname']等等。但您可以随意命名它们 - 只要记住您命名的 JSON 传输数据部分的键名是如何在 PHP 中访问它们的。
  3. 显然,这需要使用 jQuery ;)。

你好,伙计。我按照你的代码示例操作,但是在我的项目中无法运行。你介意我们联系一下,让我从你那里得到一些帮助吗?谢谢! - York Wang
制作一个Gist,我会查看它。 - serraosays

3

BATCH LOAD - 好的,所以之前我的回复因为使用了链接被删除了,现在我已经更新了代码并使其正常工作。非常感谢任何人能够简化/更正/改进/加入功能等,因为我仍在学习这些东西,但是我成功实现了批量成员列表添加 :)

$apikey = "whatever-us99";                            
$list_id = "12ab34dc56";

$email1 = "jack@email.com";
$fname1 = "Jack";
$lname1 = "Black";

$email2 = "jill@email.com";
$fname2 = "Jill";
$lname2 = "Hill";

$auth = base64_encode( 'user:'.$apikey );

$data1 = array(
    "apikey"        => $apikey,
    "email_address" => $email1,
    "status"        => "subscribed",
    "merge_fields"  => array(                
            'FNAME' => $fname1,
            'LNAME' => $lname1,
    )
);

$data2 = array(
    "apikey"        => $apikey,
    "email_address" => $email2,
    "status"        => "subscribed",                
    "merge_fields"  => array(                
            'FNAME' => $fname2,
            'LNAME' => $lname2,
    )
);

$json_data1 = json_encode($data1);
$json_data2 = json_encode($data2);

$array = array(
    "operations" => array(
        array(
            "method" => "POST",
            "path" => "/lists/$list_id/members/",
            "body" => $json_data1
        ),
        array(
            "method" => "POST",
            "path" => "/lists/$list_id/members/",
            "body" => $json_data2
        )
    )
);

$json_post = json_encode($array);

$ch = curl_init();

$curlopt_url = "https://us99.api.mailchimp.com/3.0/batches";
curl_setopt($ch, CURLOPT_URL, $curlopt_url);

curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json',
'Authorization: Basic '.$auth));
curl_setopt($ch, CURLOPT_USERAGENT, 'PHP-MCAPI/3.0');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, $json_post);

print_r($json_post . "\n");
$result = curl_exec($ch);

var_dump($result . "\n");
print_r ($result . "\n");

1
如果有帮助的话,以下是我使用Python中的Python Requests库而不是CURL得到的工作结果。
如@staypuftman所解释的那样,您需要从MailChimp获取API密钥和列表ID,并确保您的API密钥后缀和URL前缀(即us5)匹配。
Python:
#########################################################################################
# To add a single contact to MailChimp (using MailChimp v3.0 API), requires:
#   + MailChimp API Key
#   + MailChimp List Id for specific list
#   + MailChimp API URL for adding a single new contact
#
# Note: the API URL has a 3/4 character location subdomain at the front of the URL string. 
# It can vary depending on where you are in the world. To determine yours, check the last 
# 3/4 characters of your API key. The API URL location subdomain must match API Key 
# suffix e.g. us5, us13, us19 etc. but in this example, us5.
# (suggest you put the following 3 values in 'settings' or 'secrets' file)
#########################################################################################
MAILCHIMP_API_KEY = 'your-api-key-here-us5'
MAILCHIMP_LIST_ID = 'your-list-id-here'
MAILCHIMP_ADD_CONTACT_TO_LIST_URL = 'https://us5.api.mailchimp.com/3.0/lists/' + MAILCHIMP_LIST_ID + '/members/'

    # Create new contact data and convert into JSON as this is what MailChimp expects in the API
    # I've hardcoded some test data but use what you get from your form as appropriate
    new_contact_data_dict = {
        "email_address": "test@testing.com",              # 'email_address' is a mandatory field
        "status": "subscribed",                           # 'status' is a mandatory field
        "merge_fields": {                                 # 'merge_fields' are optional:
            "FNAME": "John",                  
            "LNAME": "Smith"
        }
    }
    new_contact_data_json = json.dumps(new_contact_data_dict)

    # Create the new contact using MailChimp API using Python 'Requests' library
    req = requests.post(
        MAILCHIMP_ADD_CONTACT_TO_LIST_URL,
        data=new_contact_data_json,
        auth=('user', MAILCHIMP_API_KEY),
        headers={"content-type": "application/json"}
    )

    # debug info if required - .text and .json also list the 'merge_fields' names for use in contact JSON above
    # print req.status_code
    # print req.text
    # print req.json()

    if req.status_code == 200:
        # success - do anything you need to do
    else:
        # fail - do anything you need to do - but here is a useful debug message
        mailchimp_fail = 'MailChimp call failed calling this URL: {0}\n' \
                         'Returned this HTTP status code: {1}\n' \
                         'Returned this response text: {2}' \
                         .format(req.url, str(req.status_code), req.text)

0
如果你想使用Mailchimp API运行列表上的批量订阅,那么你可以使用下面的函数。
    /**
     * Mailchimp API- List Batch Subscribe added function
     *
     * @param array  $data   Passed you data as an array format.
     * @param string $apikey your mailchimp api key.
     *
     * @return mixed
     */
    function batchSubscribe(array $data, $apikey)
    {
        $auth          = base64_encode('user:' . $apikey);
        $json_postData = json_encode($data);
        $ch            = curl_init();
        $dataCenter    = substr($apikey, strpos($apikey, '-') + 1);
        $curlopt_url   = 'https://' . $dataCenter . '.api.mailchimp.com/3.0/batches/';
        curl_setopt($ch, CURLOPT_URL, $curlopt_url);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json',
            'Authorization: Basic ' . $auth));
        curl_setopt($ch, CURLOPT_USERAGENT, 'PHP-MCAPI/3.0');
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 10);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $json_postData);
        $result = curl_exec($ch);
        return $result;
    }

批量操作的函数使用和数据格式:

<?php
$apikey  = 'Your MailChimp Api Key';
$list_id = 'Your list ID';
$servername = 'localhost';
$username   = 'Youre DB username';
$password   = 'Your DB password';
$dbname     = 'Your DB Name';
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
    die('Connection failed: ' . $conn->connect_error);
}
$sql       = 'SELECT * FROM emails';// your SQL Query goes here
$result    = $conn->query($sql);
$finalData = [];
if ($result->num_rows > 0) {
    // output data of each row
    while ($row = $result->fetch_assoc()) {
        $individulData = array(
            'apikey'        => $apikey,
            'email_address' => $row['email'],
            'status'        => 'subscribed',
            'merge_fields'  => array(
                'FNAME' => 'eastwest',
                'LNAME' => 'rehab',
            )
        );
        $json_individulData        = json_encode($individulData);
        $finalData['operations'][] =
            array(
                "method" => "POST",
                "path"   => "/lists/$list_id/members/",
                "body"   => $json_individulData
            );
    }
}
$api_response = batchSubscribe($finalData, $apikey);
print_r($api_response);
$conn->close();

此外,您可以在我的 Github Gist 中找到此代码。GithubGist 链接

参考文档:官方文档


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接