teamteama
teamteama

Reputation: 281

How to add "Tags" to mailchimp subscriber via the api

Looking to add tags to my mailing list members via the api. But I don't see where to pass in tags in the documentation. Can someone point to an example of how to update the tags associated with a member via the api?

Upvotes: 26

Views: 35872

Answers (8)

DuncanJ
DuncanJ

Reputation: 16

Working Example - How to add/remove tags on MailChimp using API v3 and PHP (2023)

Even with all the answers, this required an inordinate number of hours to get working.

As this is still a relevant question in 2023, here is an example that has been tested to work in 2023, step-by-step.

This is a somewhat complete answer in that not just the tags array format required by MailChimp is given, but all the steps necessary to correctly produce this array. Knowing the format of the array - but without knowing how to create it - was only half the battle, in my experience.

Scenario

  • A web page with an HTML form, on which is a series of checkboxes.
  • Each checkbox has an ID & name that matches a tag name e.g. BusinessEnglishPro (which in this example is just an online course name, stripped of spaces)

Web form

  • An onclick handler is assigned to each checkbox. It cycles through the checkboxes, creates an associative array of the checkbox name (the tag name) and its 'checked' status, then POSTs the form to our PHP handler. We'll see the array this creates later below.

That's the HTML and JavaScript part that allows us to get our list of tags.

PHP Processor

JavaScript will then POST the array above off to our PHP processor.

Note that in what follows, a MailChimp contact is presumed to exist and we simply wish to update their associated tags.

Let's include the MailChimp info we will need. The info below is, naturally, dummy and you'd insert your own here:

$mc_api = 'f1211112223334445550ffd-us21'; // MailChimp API Key
$mc_url_prefix = substr($mc_api,strpos($mc_api,'-')+1) ; // e.g.us21
$mc_audience_id = '654321abc'; // MailChimp Audience ID

First check we have some POST data and get hold of the array of tags (course names) and their associated form checkbox state:

 if ( $queryType == 'POST' )  {     
      $postdata= json_decode(file_get_contents('php://input'), true);   
      ...
 }

Here's what we'd receive as $postdata if Business English Free were ticked:

        (
            [BusinessEnglishFree] => 1
            [BusinessEnglishPro]  => 
        )

Code to verify/filter this data is omitted here but for our example we can assume it's all fine, was POSTed by our form, has passed our security checks and so on. You could add a WordPress nonse to the array, and if valid remove it from the array, for example to leave just an array of tags.

To answer the specific question of how to update tags, we need to convert this array to an array of tags that MailChimp likes. This is going to look like this:

        $tags_info = array(
            'tags' => array(    
                array('name' => 'BusinessEnglishFree', 'status' => 'active' ),
                array('name' => 'BusinessEnglishPro',  'status' => 'inactive' )
            )
        );

To create the correctly structured $tags_info array above, the following code can used to first create the 'innermost' array above.

      /* Create an empty inner array to hold the tags, each itself an array.  */
        $tags_inner_array = array();
        
        /* Create, too, a temp array that will hold info about just one tag */
        $tmp_tag_info = array();

        /* Now loop through our array of checkbox names (which are tag names) and their checked state */
        foreach ($postdata as $tagname => $chboxstate ){
            // Convert Boolean checkbox state to an 'active|inactive' string.  (test) ? value if true : value if false
            $chboxstate ? $tagstate = 'active'  :   $tagstate = 'inactive';         
            
            // Populate array with current tag info
            $tmp_tag_info['name']   =  $tagname  ;
            $tmp_tag_info['status'] =  $tagstate  ;

            // ... and add above tag info to the tags inner-array
            array_push($tags_inner_array, $tmp_tag_info);               
        }   

Now we can create the full $tags_info array easily like so:

$tags_info = array(
    'tags' =>   $tags_inner_array
);  

Finally, we can construct the argument that should be POSTed to MailChimp. Notice that we json_encode the $tags_info array above in the final line:

        $mailchimp_args = array(
            'headers'   => array(   
                'Authorization' => 'Basic ' . base64_encode( 'user:'. $mc_api ) 
            ),
            'Access-Control-Allow-Origin'   => '*',
            'timeout'                       => 6,
            'method'    => 'POST',
                'body'      => json_encode( $tags_info )
        );

To construct the URL to POST to, we use the following. Notice that it ends in '/tags':

    // Construct MailChimp Tags URL
    $mailchimp_URL  = 'https://' . $mc_url_prefix . '.api.mailchimp.com/3.0/lists/' . $mc_audience_id . '/members/' . md5(strtolower($user_email)) . '/tags';

POST it off to MailChimp and retrieve the response code. Here we're using WordPress functions to do this, but the key thing to note - if you do it another way - is the actual response code for success:

// Call MailChimp ...
$response       = wp_remote_get(    $mailchimp_URL , $mailchimp_args );
$response_code  = wp_remote_retrieve_response_code( $response ); // 204 is 'OK'

The 'success' response code is 204 - take note - and to finish our example we'll create an array $return_to_js to hold this:

 $return_to_js = array();
 if ( 204 === $response_code ) {                    
    $return_to_js['status'] = "All OK. Mailing preferences updated on MailChimp." ;                 
} 

You could check for errors and such too, but that code is omitted here.

Finally, if we have called our PHP processor script via a JavaScript AJAX call, we can pass on the status messsage that we created above by sending back the $return_to_js array:

return $return_to_js;

I hope this more complete answer is helpful, and that you too dance around the room when you manage to update your tags sucessfully.

Upvotes: 0

David Brossard
David Brossard

Reputation: 13834

It took me a while to also figure this one out. Their documentation isn't clear and it seems there are 2 ways to add tags, either via the tags endpoint using POST or via the update user via a PATCH. Here's an example of the POST in PHP:

function tagUser($email){
global $api_key;
global $listId;
$hashedEmail = md5(strtolower($email));
$args = array(
    'method' => 'POST',
    'headers' => array(
        'Authorization' => 'Basic ' . base64_encode( 'user:'. $api_key )
    ),
    'body' => json_encode(array(
        'tags' => array(['name'=>'healthy','status'=>'active'])
    ))
);
$response = wp_remote_post( 'https://usxx.api.mailchimp.com/3.0/lists/'.$listId.'/members/'.$hashedEmail.'/tags', $args );

$body = json_decode( $response['body'] );

}

Upvotes: 2

Thomas Parkinson
Thomas Parkinson

Reputation: 11

This is code for WordPress, but should help. I did get most of this from another answer but could not find it working anywhere else. Note this only work if the subscriber already exists on the list and then you can tag or untag them.

    $api_key = XXXXXXXXXXXXXXXXXXX-us20';
    $email = 'tom@gmail.com';
    $list_id = 'XXXXXXXX'; //This is the list /Audience id
    $tag_name_text = 'XXXXX'; //This can be whatever you want it to be. Mail chimp will add it to the tags if not already on the system

    //TAGS
    $args = array(
      'method' => 'POST',
        'headers' => array(
            'Authorization' => 'Basic ' . base64_encode( 'user:'. $api_key )
    ),
    'body' => json_encode(array(

            'tags' => array(
                    ['name' => $tag_name_text,
                    'status' => 'active']
            )




    ))
);
$response = wp_remote_post( 'https://' . substr($api_key,strpos($api_key,'-')+1) . '.api.mailchimp.com/3.0/lists/' . $list_id . '/members/'.md5(strtolower($email)).'/tags', $args );
if ($response['response']['code'] == 200 && $body->status == $status || $response['resp`enter code here`onse']['code'] == 204) {
    //echo 'The you have been successfully ' . $status . '. Please check your emails';

} else {
    echo '<b>' . $response['response']['code'] . $body->title . ':</b> ' . $body->detail;
}

Upvotes: 1

m_h
m_h

Reputation: 585

If you want to create a member AND add a tag while doing so you may specify the tag attribute the following way:

$data = array(
              'apikey'        => $api_key,
              'email_address' => $email,
              'status'     => $status,
              'tags'  => array('your-tag-name'),
              'merge_fields'  => array(
                    'FNAME' => $fname,
                    'LNAME' => $lname
                  )
            );

Even though MC API some places will tell you to fill out both a name and a status, it helped me to define tags as an array but ONLY pasting in the name of the tag.

Seefan's answer in this thread helped me out and I figured i wanted to help a person who spend days (like me) to figure out how the "tags" is specified: add tags to mailchimp subscriber created via api php

Upvotes: 17

Tyler Rafferty
Tyler Rafferty

Reputation: 3428

FULL EXAMPLE USING GRAILS TO ADD LIST OF TAGS BY NAME TO A LIST OF USERS BY EMAIL

Note you may want to setup some error checking to see if the MailChimp audience member exists.

BusinessLogicController.groovy

/* 
 * Add list of tags by name to list of members
 */
def addTagsByNameToUser(){
    List<string> tagNamesToAdd = ['foo', 'bar']
    def addResult = mailChimpService.addTagsToContactsByName(["foo@example.com", "bar@example.com"], tagNamesToAdd)
} 

MailChimpService.groovy

import grails.util.Holders
import groovyx.net.http.Method

class MailChimpService {

   def grailsApplication
   ApiConsumerService apiConsumerService

   final String AUTH = Holders.config.grails.mailChimp.auth
   final String BASEURL = "https://us19.api.mailchimp.com/3.0/"
   final String LISTID = "abc123"

   //Add list of tags by name to list of subscribers by email
   def addTagsToContactsByName(List emailAddresses, List tags = []) {
      tags.each { tagName ->
         addMembersToSegment(emailAddresses, tagName);
      }
   }

   //Add a tag to a subscriber by name
   def addMembersToSegment(List emailAddresses, String segmentName) {
      def segmentsByName = getAllSegmentsInList()

      String segmentId = segmentsByName["$segmentName"] as String

      return addMailChimpTagToUsers(emailAddresses, segmentId)
   }

   //Get information about all available segments for a specific list.
   def getAllSegmentsInList(Map query = [:]) {
      String path = "lists/"+LISTID+"/segments/"
      Map segments = [:]
      def segmentResults = apiConsumerService.getRequest(BASEURL, path, AUTH, query, Method.GET)
      segmentResults.segments.each { segment ->
         segments.put(segment.name, segment.id)
      }

      return segments
   }

   //Add list of tags to a list members. 
   def addMailChimpTagToUsers(List emailAddresses = [], String segmentId) {
      String path = "lists/LISTID/segments/" + segmentId

      apiConsumerService.postRequest(BASEURL, path, AUTH, ['members_to_add': emailAddresses], Method.POST)
    }    
}

ApiConsumerService.groovy

import grails.transaction.Transactional
import groovyx.net.http.ContentType
import groovyx.net.http.HTTPBuilder
import groovyx.net.http.Method

@Transactional
class ApiConsumerService {

   //POST REQUEST
   def postRequest(String baseUrl, String path, String auth, Map query = [:], Method method = Method.POST) {
      try {
         HTTPBuilder http = new HTTPBuilder(baseUrl)
         http.headers['Authorization'] = 'Basic ' + "${auth}".getBytes('iso-8859-1').encodeBase64()

         http.request(method, ContentType.JSON) { req ->
            uri.path = path
            if (method == Method.POST) {
                body = query
            } else {
                uri.query = query
            }

            headers.'Accept' = 'application/json'
            headers.'User-Agent' = "MyPetCerts/US19"
            response.success = { resp, json ->
                return json
            }

            response.failure = { resp, json ->
                println "POST response status: ${resp.statusLine}"
            }
         }
      } catch (groovyx.net.http.HttpResponseException ex) {
           ex.printStackTrace()
           return null
      } catch (java.net.ConnectException ex) {
           ex.printStackTrace()
           return null
      }
   }

   //GET Request
   def getRequest(String baseUrl, String path, String auth, Map query = [:], Method method = Method.GET) {
      return postRequest(baseUrl, path, auth, query, method)
   }
}

Upvotes: 0

Boris
Boris

Reputation: 306

This is the official way to add tags: https://developer.mailchimp.com/documentation/mailchimp/reference/lists/members/tags/ It works, except that in my testing, the response message is empty, even though the tag is added.

Here's sample code in Google Apps Script:

payload = '{\
  "tags": [\
    {\
     "name":"' + tagName + '",\
     "status":"' + tagStatus + '"\
    }\
   ]\
}'
;

params = {
  "method": "POST",
  "headers":MC_headers,
  "payload": payload,
  "muteHttpExceptions": true
};
url = MC_url + 'lists/' + MC_IDs.listId + '/members/' + sub_hash + '/tags';
response = UrlFetchApp.fetch(url, params);

Upvotes: 9

Ryan
Ryan

Reputation: 24083

Apparently Mailchimp "tags" are "segments".

I coded a couple functions that allow me to add tags by name (rather than by ID) to a member (i.e. subscriber) by email address.

/**
 * 
 * @param string $emailAddress
 * @param array $tags
 * @return void
 */
public function addTagsToContact($emailAddress, $tags) {
    $list_id = $this->getDefaultListId();
    foreach ($tags as $tag) {
        $this->addMemberToSegment($emailAddress, $list_id, $tag);
    }
}

/**
 * Add a tag to a subscriber (tags replaced segments https://stackoverflow.com/a/52315577/470749)
 * 
 * @param string $emailAddress
 * @param string $list_id
 * @param string $segment_name
 * @return array
 */
public function addMemberToSegment($emailAddress, $list_id, $segment_name) {
    $api = Newsletter::getApi();
    $segmentsByName = $this->getSegments($list_id);
    $segment_id = $segmentsByName[$segment_name]['id'];
    $response = $api->post("lists/$list_id/segments/$segment_id", [
        'members_to_add' => [$emailAddress]
    ]); //https://developer.mailchimp.com/documentation/mailchimp/reference/lists/segments/#create-post_lists_list_id_segments_segment_id
    return $response;
}

/**
 * 
 * @param string $list_id
 * @return array
 */
public function getSegments($list_id) {//https://developer.mailchimp.com/documentation/mailchimp/reference/lists/segments/#%20
    $segmentsByName = [];
    $api = Newsletter::getApi();
    $count = 50; //default is 10
    $offset = 0;
    do {
        $url = "lists/$list_id/segments/?" . http_build_query(['count' => $count, 'offset' => $offset]);
        Log::debug($url);
        $response = $api->get($url);
        $total_items = $response['total_items'];
        foreach ($response['segments'] as $segment) {
            $segmentsByName[$segment['name']] = $segment;
        }
        $offset += $count;
    } while (count($segmentsByName) < $total_items);
    //Log::debug(json_encode($segmentsByName));
    return $segmentsByName;
}

/**
 * 
 * @return string
 */
public function getDefaultListId() {
    return config('newsletter.lists.subscribers.id');
}

This relies on the https://github.com/spatie/laravel-newsletter library.

P.S. Thanks so much to @Jelan, whose answer got me on the right track!

Upvotes: 6

Gerald
Gerald

Reputation: 814

Tags replaced static segments. So, the endpoints used to create tags and add and remove tags from members are the same endpoints that were previously used to manage segments. Here is the documentation on the endpoints to use to manage your tags via the API that includes the request and response body parameters as well as example requests and responses:

http://developer.mailchimp.com/documentation/mailchimp/reference/lists/segments/

In order to add tags to your members, you need to include their email addresses in the 'static_segment' array parameter.

I hope that helps.

Upvotes: 12

Related Questions