Как вернуть ошибки из пакетной операции MailChimp API v3.0

Я борюсь с новым MailChimp API и пакетной функциональностью, в частности, с тем, как вернуть любые ошибки из базовых операций, которые были пакетными, а не из самой пакетной операции.

Мой код ниже и работает, чтобы добавить двух тестовых подписчиков. Ответ показывает только успех для всей партии:

[errored_operations] => 0

Если я запущу его снова, он вернет аналогичный ответ, но с двумя ошибками:

[errored_operations] => 2

Кроме этого, нет никаких указаний на то, что не удалось или почему. В этом случае мы знаем, что это потому, что пользователи уже подписаны. Если я попытаюсь добавить одного пользователя без пакетного вызова, используя POST /lists/{list_id}/members, я получу ответ с подробным описанием того, что именно не удалось.

stdClass Object
(
    [type] => http://developer.mailchimp.com/documentation/mailchimp/guides/error-glossary/
    [title] => Member Exists
    [status] => 400
    [detail] => [email protected] is already a list member. Use PUT to insert or update list members.
    [instance] => 
)

Как я могу зафиксировать отдельные ошибки при добавлении (или обновлении или удалении) сотен подписчиков?

Я пробовал просто перебирать пользователей, делая несколько отдельных вызовов, и это работает: он добавляет пользователей и/или предоставляет подробные отчеты об ошибках. Но кажется глупым делать 500 вызовов, когда API настроен на обработку всего этого за один вызов. Спасибо за любые идеи!

Вот мой код:

$list_id = 'xyz123';
$subscribers = array(
    array(
        'email'     => '[email protected]',
        'status'    => 'subscribed',
        'firstname' => 'Jeff',
        'lastname'  => 'Jackson'
    ),
    array(
        'email'     => '[email protected]',
        'status'    => 'subscribed',
        'firstname' => 'Mary',
        'lastname'  => 'Jackson'
    )
);

$add_subs_batch = add_subs_batch($list_id, $subscribers);
echo '<pre>add_subs_batch: ';
print_r($add_subs_batch);
echo '</pre>';

function add_subs_batch($list_id, $data) {
    $method = 'POST'; 
    $batch_path = 'lists/' . $list_id . '/members';
    $result = mc_request_batch($method, $batch_path, $data);
    if($result && $result->id) {
        $batch_id = $result->id;
        $batch_status = get_batch_status($batch_id);
        return $batch_status;
    }
    else {
        return $result;
    }
}
function get_batch_status($batch_id, $i=1) {
    $method = 'GET'; 
    $target = 'batches/'.$batch_id;
    $result = mc_request($method, $target, $data);
    sleep(1); // wait 1 second and try
    if($result->status == 'finished' ) {
        return $result;
    }
    else {
        return get_batch_status($batch_id, $i+1);
    }
}
function mc_request_batch( $method, $batch_path, $data = false ) {
    $api_key = '12345-us1';
    $dataCenter = substr($api_key,strpos($api_key,'-')+1);
    $url = 'https://' . $dataCenter . '.api.mailchimp.com/3.0/';
    $target = 'batches';

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url . $target );
    curl_setopt($ch, CURLOPT_USERPWD, 'user:' . $api_key);
    curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST' );
    curl_setopt($ch, CURLOPT_TIMEOUT, 10 );
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true );
    curl_setopt($ch, CURLOPT_USERAGENT, 'YOUR-USER-AGENT' );
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); 

    if( $data ) {
        $batch_data = new stdClass();
        $batch_data->operations = array();
            foreach ($data as $item) {
                $batch = new stdClass();
                $batch->method = $method;
                $batch->path = $batch_path;
                $batch->body = json_encode( array(
                    'email_address' => $item['email'],
                    'status'        => $item['status'],
                    'merge_fields'  => array( 
                        'FNAME' => $item['firstname'],
                        'LNAME' => $item['lastname']
                    )
                ) );
                $batch_data->operations[] = $batch;
            }

        $batch_data = json_encode($batch_data);
        curl_setopt($ch, CURLOPT_POSTFIELDS,  $batch_data  );
        $response = curl_exec( $ch );
    }
    curl_close( $ch );
    return json_decode($response);
}

person Stace    schedule 19.10.2016    source источник
comment
FWIW, моему приложению не нужна строка CURLOPT_USERAGENT.   -  person mickmackusa    schedule 04.02.2020


Ответы (1)


Вы получите id в ответ на пакетную операцию. Это «Идентификатор пакета», представляющий собой строку, которая однозначно идентифицирует пакетный запрос.

Чтобы получить статус пакетного запроса, вы должны вызвать запрос GET к URL-адресу /batches/{batch_id}.

В ответе вы можете найти URL-адрес в поле response_body_url, который содержит gzip-архив результатов всех операций в пакетном вызове.

Справка:

Примечание

Из соображений безопасности response_body_url действителен только в течение 10 минут. Через 10 минут сгенерируйте еще один с вызовом GET для /3.0/batches/{batch_id}.

После отправки запроса на пакетную операцию результаты доступны в течение 7 дней.

person Mûhámmàd Yäsår K    schedule 20.10.2016
comment
Спасибо, что нашли время ответить. Как я могу получить доступ к этому архивному файлу gzip в моем коде? Есть ли еще место, где я могу получить доступ к этим данным с помощью PHP? - person Stace; 20.10.2016
comment
Вы можете написать код 1. Загрузите файл на свой сервер Ref. 2. Прочтите информацию из загруженного gzip-файла Ref. Пожалуйста, дайте нам знать, если у вас есть какие-либо препятствия для этого. Спасибо. :) - person Mûhámmàd Yäsår K; 21.10.2016
comment
Еще раз спасибо за ответ. Я понимаю описанный вами процесс, хотя на самом деле это файл .tar.gz, что представляет собой еще один уровень сложности, и я не могу загрузить файл на сервер. но все это кажется очень сложным, чтобы просто получить базовые отчеты об ошибках. Неужели нет другого способа получить доступ к этим данным? - person Stace; 21.10.2016
comment
Я думаю, что нет никакого способа получить доступ к этим данным, я проверю их и сообщу вам, если таковые имеются. :) - person Mûhámmàd Yäsår K; 24.10.2016
comment
Спасибо за помощь. Я чувствую, что почти достиг цели, но застрял на последнем этапе. Я могу загрузить файл file.tar.gz на сервер, я могу распаковать его в path/file.tar, используя класс PharData и функцию распаковки. Оттуда я пробую phar:extractTo('путь/файл'), но выдает исключение Extraction from phar "/path/file.tar" failed: Cannot extract ".", internal error. Любые идеи? - person Stace; 01.11.2016