mailchimp-api
mailchimp-api copied to clipboard
batch-API facilities to fetch result from response_body_url
When using the batch API, fetching results is a bit cumbersome.
We first need to GET the json the given batch ID, then (if finished) fetch the response_body_url, then store that file, unpack it (it's tar gziped) then parse the "$batch-id.json" json file it contains then start using the result.
Facilitating this process would nicely fit the library.
Something like fetchBatchIfFinished($batch-id), returning the results would be highly appreciated feature.
+1 for this feature.
The purpose of the library is to ferry the messages back and forth. Processing the response is up to you.
It might be a nice idea to build a library with more of those features to sit on top of this one.
I understand the willingness to keep minimal the scope of the lib. But such function, highly MailChimp-specific, wouldn't fit well to yet-another-layer. Although composer ease the way we deal with multiples library (sub-)dependencies, it's still better having one rather than two. Having another class, or just another "level" of classes in the same package wouldn't hurt.
Side note: I understand this:
The purpose of the library is to ferry the messages back and forth. Processing the response is up to you.
but it only depends upon the definition (= the level) of "messages". A batch contains multiples responses. That could make sense as well to ease access to final message. And it fit the library since it's the only way to fetch batch-messages and is highly specific to MailChimp.
I would say this is out of the scope of this library. Also it was a little painful due to the phar class not being able to open the mailchimp tar files
Here is the solution I made for myself. It depends on Archive_Tar (pear/archive_tar in composer)
$Batch = $mc->new_batch($_GET['status']);
$result = $Batch->check_status();
if ($result['status'] === 'finished') {
$data = gzdecode(file_get_contents($result['response_body_url']));
$temp = tempnam("","") . ".tar";
file_put_contents($temp, $data);
$tar_object = new Archive_Tar($temp);
$v_list = $tar_object->listContent();
foreach ($v_list as $item) {
if (strpos($item["filename"], ".json") !== FALSE ) {
$contents = $tar_object->extractInString($item["filename"]);
}
}
unlink($temp);
echo $contents;
} else {
echo json_encode($result);
}
It will output the json if status is finished
Another one where only original gzip is stored and the rest is done in memory rather than with temporary files. (and handle when a > 1000 records responses is stored among multiple files)
PS: MailChimp has been notified about Phar incompatibility months ago. Feel free to ping them about this again, it couldn't hurt.
PS: please note that API v3 now allows pushing up to 500 subscribers without using the batch mode.
$file_destination = sprintf("batch-%s-%s.tar.gz", date('Ymd'), $batch_id);
$h = fopen($file_destination, 'w');
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $result['response_body_url']);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_FILE, $h);
curl_exec($ch);
fclose($h);
$results = json_decode(shell_exec("tar Ozxf $file_destination"));
if (! $results) {
$string = shell_exec("tar Ozxf $file_destination");
if (json_last_error() == 4 && preg_match("/\]\[/", $string)) {
$count;
$string = str_replace('][', ',', $string, $count);
syslog(LOG_WARNING, sprintf("mailchimp: %s. Combining %d JSON arrays (previous warning: %s)", $file_destination, $count+1, json_last_error_msg()));
$results = json_decode($string);
if ($results) {
return $results;
} else {
syslog(LOG_ERR, sprintf("mailchimp: %s combined JSON error: %s", $file_destination, json_last_error_msg()));
return FALSE;
}
}
syslog(LOG_ERR, sprintf("mailchimp: %s, JSON error: %s", $file_destination, json_last_error_msg()));
return FALSE;
}
return $results;