mailchimp-api icon indicating copy to clipboard operation
mailchimp-api copied to clipboard

batch-API facilities to fetch result from response_body_url

Open drzraf opened this issue 9 years ago • 5 comments

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.

drzraf avatar Jun 14 '16 03:06 drzraf

+1 for this feature.

Akshath0392 avatar Sep 08 '16 06:09 Akshath0392

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.

drewm avatar Sep 08 '16 10:09 drewm

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.

drzraf avatar Sep 08 '16 11:09 drzraf

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

jontro avatar Oct 17 '16 15:10 jontro

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;

drzraf avatar Oct 17 '16 16:10 drzraf