Managing Duplicates, Custom Fields and Subscribers Using the API

Hi there,

Posted this in the troubleshooting forum but can't get it moved here. So here we go with a new thread!

Wondered if any of the Campaign Monitor API pros could spare a moment to offer some advice on what's the best solution for us. Here's the original posts:

Mitch :

What's the best way to manage importing duplicates?

We use CM and custom fields to send out a single weekly campaign which is customized with the details of the agent who refers a subscriber to the database.

The agents primarily gather email addresses during follow up phone calls and are typically adding only a few email addresses each a week.

We'd like to use the CM forms to allow them to add new subscribers, however the way CM handles silently overwrites anything in any custom field if someone is added more than once.

Given the unique nature of our campaigns - they're designed to be "from the agent," it is likely that from time-to-time people will consent to more than one agent to receive our email updates. To handle this, we've been running a first in, first served policy which can't be protected using the standard CM way of importing emails.

At the moment I've been doing a combination of manually adding / exporting the subscriber list, importing the new ones then re-importing the old list over the top to preserve the initial referring agent. Obviously this isn't a particularly sustainable way of doing things so if anyone could recommend an alternative solution that would be awesome!

Cheers

Mitch :

If I could get the CM subscriber form to do this, it would be perfect:

http://cooperandco.co.nz/images/misc/mail-chimp.jpg

So ideally what we're after is a way to keep add new subscribers without running the risk of overwriting the referring agent.

Preference is a PHP solution, but any help would be appreciated!

Ken Ken, 7 years ago

Hi Mitch,

A way to achieve what you want to do is by using the API method Subscribers.GetActive. When an agent tries to add a new subscriber, you can grab the current active subscribers from your list first by using Subscribers.GetActive, and then check to see if that subscriber already exists. If it doesn't, you add it with Subscriber.Add(WithCustomFields), and if it does, you ignore it/display and error message.

Since you can access the API with PHP, I reckon this will be perfect for you.


http://www.campaignmonitor.com
Mitch, 7 years ago

Hi Ken,

That's some great advice. Can anyone help me with searching the arrays?

I've got to this:

    $subscribers = $cm->subscribersGetActive($date = 0,$list_id);
    if (in_array("address@domain.com",$subscribers)) {
        echo "Success <br /><br />";
        }
    else {
        echo "Fail <br /><br />";
        }
    //Just to check the array is loading
    print_r($subscribers);

Which is definitely getting what I need from the API (the print_r function prints everything nicely in an array), but whatever I put in as the value to search I keep getting Fail returned.

I'm guessing I'm using the wrong function or not doing things right... so close though!

Mitch, 7 years ago

Woo! Cracked it, just need to flatten the array! :)

EDIT: Now can anyone help me get the custom fields from the array the API puts them in to populate a drop down box in a form?

Mitch, 7 years ago

OK, I've solved that one too. I've now moved to using this on an actual list with around 1,000 subscribers and it's *very* slow.

I'm guessing the in_array function, especially given the rather tactless approach to searching is rather inefficient. Can anyone recommend a better way?

Ken Ken, 7 years ago

Hi Mitch,

I'm glad you're making lots of head way. I'm surprised that the in_array function would be so slow. But since I'm not a PHP expert, I can't say if there is a better way to do what you want. Hopefully a PHP master will answer this post, otherwise you might have to search or post on a few PHP dedicated forums.


http://www.campaignmonitor.com
Mitch, 7 years ago

Yea, unfortunately it's very slow. Takes 5 - 10s to do the query, which isn't really practical.

Ken :

Hi Mitch,

I'm glad you're making lots of head way. I'm surprised that the in_array function would be so slow. But since I'm not a PHP expert, I can't say if there is a better way to do what you want. Hopefully a PHP master will answer this post, otherwise you might have to search or post on a few PHP dedicated forums.

I started a thread here a couple of days ago, general advice has been to try and run something server side which is obviously not possible. I'd like everything to be live so don't want to create to databases and try and keep them in sync.

Anyone got any ideas?

DahlinDev, 7 years ago

I've found the method: CampaignMonitorAPIWrapper.Subscribers.GetIsSubscribed(_apiKey, _listId, emailAddress) to work great for this situation.  I first call this method to see if the user is already subscribed. 

If not I then Add them.

Hope this helps, better than returning all subscribers and searching through them.

Mitch, 7 years ago

Thanks Dahlin - that's got to be the way forward!

I've had a look through the PHP wrapper and I think the following function should do it:

    /**
    * Given an array of lists, indicate whether the $email is subscribed to each of those lists.
    *
    * @param string $email User's email
    * @param mixed $lists An associative array of lists to check against. Each key should be a List ID
    * @param boolean $no_assoc If true, only returns an array where each value indicates that the user is subscribed
    *        to that particular list. Otherwise, returns a fully associative array of $list_id => true | false.
    * @return mixed An array corresponding to $lists where true means the user is subscribed to that particular list.
    */
    
    function checkSubscriptions( $email, $lists, $no_assoc = true )
    {
        $nlist = array();
        foreach ( $lists as $lid => $misc )
        {
            $val = $this->subscribersGetIsSubscribed( $email, $lid );
            $val = $val != 'False';
            if ( $no_assoc && $val ) $nlist[] = $lid;
            elseif ( !$no_assoc ) $nlist[$lid] = $val;
        }
        
        return $nlist;
    }
}

I've tried the following in my form:

    // Get info from form
    $name = $_POST["Field1"];            // Name
    $email_in = $_POST["Field2"];        // Raw email from form
    $email_out = strtolower($email_in); // Strip emails to lower case
    $ref = $_POST["Field109"];            // Referring Agent
    
    // Check if already subscribed, add if not, output error if is
    
    $var = $cm->checkSubscriptions($email_out, $list_id, $no_assoc = true );
    
    if ($var == TRUE) { }
        else { }

This results in following error and the subscriber is added to the database (even if already subscribed):

Warning: Invalid argument supplied for foreach() in /home/www/domain.com/web/api/CMBase.php on line 550
DahlinDev, 7 years ago

Mitch

It looks like you're on the right path. Sorry I don't know php though. Good luck.

Ben Ben, 7 years ago
Mitch :

Warning: Invalid argument supplied for foreach() in /home/www/domain.com/web/api/CMBase.php on line 550

I'm guessing that you are passing in $list_id as a string instead of an array.

Mitch, 7 years ago

Well thanks to some great help from the CampaignMonitor support team and the folks over at PHP Freaks we cracked this!

We've put together a tutorial and posted it here in case anyone else is looking for a similar solution!

Thanks again to everyone who helped us out.

Join 200,000 companies around the world that use Campaign Monitor to run email marketing campaigns that deliver results for their business.

Get started for free
1-888-533-8098