Если вам нужно выполнить действие с несколькими сообщениями в карантине одновременно, используйте методы пакетной обработки ресурса customers.quarantinedMessages в Mail Admin Quarantine API:
- Метод
batchReleaseпозволяет разблокировать до 500 сообщений. - Метод
batchDenyотклоняет до 500 сообщений.
Оба метода являются асинхронными. API принимает запрос, возвращает длительную операцию и обрабатывает сообщения в фоновом режиме. Затем вы опрашиваете метод get ресурса customers.operations, пока операция не будет завершена, и считываете результаты для каждого сообщения из ответа.
В отличие от вызова методов для отдельных сообщений в цикле, пакетные методы считаются одним запросом на запись в рамках использования квоты независимо от того, сколько сообщений они содержат.
.Требования
- Вы выполнили инструкции из статьи Как настроить API.
- Токен доступа, который выдает себя за администратора с правами на карантин и включает область действия
https://www.googleapis.com/auth/gmail.admin.quarantine. Подробнее об авторизации с делегированием доступа к данным в домене… - Названия ресурсов для не более чем 500 помещенных в карантин сообщений в состоянии
PENDING_TRIAGE, которые вы получаете из списка и поиска помещенных в карантин сообщений.
Как запустить пакетную операцию
Чтобы выпустить сообщения пакетом, отправьте запрос POST к пользовательскому методу :batchRelease ресурса customers.quarantinedMessages. Массив requests содержит по одному объекту для каждого сообщения, каждый из которых содержит название ресурса сообщения:
POST https://mailadminquarantine.googleapis.com/v1/customers/CUSTOMER_ID/quarantinedMessages:batchRelease
Authorization: Bearer ACCESS_TOKEN
Content-Type: application/json
{
"requests": [
{"name": "customers/CUSTOMER_ID/quarantinedMessages/user1@example.com:18d3ef45a8b2c1d0"},
{"name": "customers/CUSTOMER_ID/quarantinedMessages/user2@example.com:18d3ef45a8b2c1d1"}
]
}
Чтобы отклонить сообщения в пакете, отправьте то же тело запроса в пользовательский метод :batchDeny ресурса customers.quarantinedMessages:
POST https://mailadminquarantine.googleapis.com/v1/customers/CUSTOMER_ID/quarantinedMessages:batchDeny
Каждый запрос должен содержать от 1 до 500 записей. Каждое сообщение должно принадлежать клиенту, указанному в пути запроса. Если в запросе больше 500 записей, возвращается ошибка 400 INVALID_ARGUMENT.
API сразу же возвращает ресурс Operation:
{
"name": "customers/01abc23de/operations/7f1c2a0e-5b7d-4d3a-9c1e-2f4b6a8d0e13",
"metadata": {
"@type": "type.googleapis.com/google.gmail.mailadminquarantine.v1.BatchReleaseQuarantinedMessagesMetadata",
"state": "PROCESSING",
"processedCount": 0,
"totalCount": 2
},
"done": false
}
Сохраните name операции. Он понадобится вам, чтобы отслеживать ход выполнения операции.
Как проверить статус пакетной операции
Чтобы проверить ход выполнения пакетной операции, отправьте запрос GET к методу get, указав название ресурса операции:
GET https://mailadminquarantine.googleapis.com/v1/customers/CUSTOMER_ID/operations/OPERATION_ID
Authorization: Bearer ACCESS_TOKEN
Метод get принимает любую область действия Admin Quarantine API, поэтому интеграция только для чтения может отслеживать операции, запущенные другой системой.
Пока операция выполняется, поле done имеет значение false, а в поле metadata указывается ход выполнения:
| Поле для метаданных | Описание |
|---|---|
state |
PROCESSING во время обработки сообщений, а затем SUCCEEDED или FAILED. |
processedCount |
Количество обработанных сообщений. |
totalCount |
Общее количество сообщений в пакете. |
Когда операция завершится, поле done получит значение true, а поле response будет содержать результат для каждого сообщения в пакете:
{
"name": "customers/01abc23de/operations/7f1c2a0e-5b7d-4d3a-9c1e-2f4b6a8d0e13",
"metadata": {
"@type": "type.googleapis.com/google.gmail.mailadminquarantine.v1.BatchReleaseQuarantinedMessagesMetadata",
"state": "SUCCEEDED",
"processedCount": 2,
"totalCount": 2
},
"done": true,
"response": {
"@type": "type.googleapis.com/google.gmail.mailadminquarantine.v1.BatchReleaseQuarantinedMessagesResponse",
"results": [
{
"name": "customers/01abc23de/quarantinedMessages/user1@example.com:18d3ef45a8b2c1d0",
"status": {},
"quarantinedMessage": {
"name": "customers/01abc23de/quarantinedMessages/user1@example.com:18d3ef45a8b2c1d0",
"messageId": "18d3ef45a8b2c1d0",
"messageOwner": "user1@example.com",
"state": "RELEASED"
}
},
{
"name": "customers/01abc23de/quarantinedMessages/user2@example.com:18d3ef45a8b2c1d1",
"status": {
"code": 5,
"message": "Quarantined message not found"
}
}
]
}
}
Каждая запись в results описывает результат для одного сообщения:
| Поле результата | Описание |
|---|---|
name |
Название ресурса сообщения. |
status |
google.rpc.Status. Пустой объект (код 0, OK) означает, что действие выполнено успешно. В противном случае в полях code и message будет указана причина, по которой сообщение было пропущено. |
quarantinedMessage |
Обновленное сообщение с новым значением state. Присутствует, только если status имеет значение OK. |
Пакетная операция считается успешной, даже если некоторые сообщения не удалось обработать. Всегда проверяйте status каждого результата, а не только state операции.
Если вся операция завершилась неудачно, например из-за недоступности бэкенда, поле done будет иметь значение true, а поле error будет содержать google.rpc.Status вместо response.
Пример: пакетный выпуск и опрос о завершении
В примере ниже показано, как запустить пакетный выпуск и опрашивать операцию каждые несколько секунд до ее завершения.
import time
import requests
BASE_URL = 'https://mailadminquarantine.googleapis.com/v1'
CUSTOMER_ID = '01abc23de' # Your customer ID without the leading 'C'.
headers = {
'Authorization': f'Bearer {access_token}',
'Content-Type': 'application/json',
}
# message_names is a list of up to 500 quarantined message resource names.
batch_url = f'{BASE_URL}/customers/{CUSTOMER_ID}/quarantinedMessages:batchRelease'
body = {'requests': [{'name': name} for name in message_names]}
operation = requests.post(batch_url, headers=headers, json=body)
operation.raise_for_status()
operation_name = operation.json()['name']
while True:
status = requests.get(f'{BASE_URL}/{operation_name}', headers=headers)
status.raise_for_status()
operation = status.json()
if operation.get('done'):
break
metadata = operation.get('metadata', {})
print(f"Processed {metadata.get('processedCount', 0)} of "
f"{metadata.get('totalCount', 0)} messages...")
time.sleep(5)
if 'error' in operation:
raise RuntimeError(f"Batch failed: {operation['error']}")
for result in operation['response'].get('results', []):
if result.get('status', {}).get('code', 0) == 0:
print(f"Released: {result['name']}")
else:
print(f"Skipped {result['name']}: {result['status'].get('message')}")