Distribuer ou refuser des messages par lots

Lorsque vous devez agir sur plusieurs messages mis en quarantaine à la fois, utilisez les méthodes de traitement par lot de la ressource customers.quarantinedMessages dans l'API Mail Admin Quarantine :

  • La méthode batchRelease libère jusqu'à 500 messages.
  • La méthode batchDeny refuse jusqu'à 500 messages.

Les deux méthodes sont asynchrones. L'API accepte la requête, renvoie une opération de longue durée et traite les messages en arrière-plan. Vous interrogez ensuite la méthode get de la ressource customers.operations jusqu'à ce que l'opération soit terminée, puis vous lisez les résultats par message à partir de la réponse.

Contrairement à l'appel des méthodes à message unique dans une boucle, les méthodes par lot sont comptabilisées comme une seule requête d'écriture dans votre utilisation du quota, quel que soit le nombre de messages qu'elles contiennent.

Prérequis

Démarrer une opération par lot

Pour libérer des messages par lot, envoyez une requête POST à la méthode personnalisée :batchRelease sur la ressource customers.quarantinedMessages. Le tableau requests contient un objet par message, chacun avec le nom de ressource du message :

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"}
  ]
}

Pour refuser des messages dans un lot, envoyez le même corps de requête à la méthode personnalisée :batchDeny sur la ressource customers.quarantinedMessages :

POST https://mailadminquarantine.googleapis.com/v1/customers/CUSTOMER_ID/quarantinedMessages:batchDeny

Chaque requête doit contenir entre 1 et 500 entrées. Chaque message doit appartenir au client dans le chemin de la requête. Une requête comportant plus de 500 entrées renvoie une erreur 400 INVALID_ARGUMENT.

L'API répond immédiatement avec une ressource 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
}

Stockez l'élément name de l'opération. Vous en aurez besoin pour vérifier la progression de l'opération.

Vérifier l'état d'une opération par lot

Pour vérifier la progression d'une opération par lot, envoyez une requête GET à la méthode get sur le nom de ressource de l'opération :

GET https://mailadminquarantine.googleapis.com/v1/customers/CUSTOMER_ID/operations/OPERATION_ID
Authorization: Bearer ACCESS_TOKEN

La méthode get accepte l'un ou l'autre des champs d'application de l'API Admin Quarantine. Une intégration en lecture seule peut donc surveiller les opérations démarrées par un autre système.

Pendant l'exécution de l'opération, le champ done est défini sur false et le champ metadata indique la progression :

Champ de métadonnées Description
state PROCESSING pendant le traitement des messages, puis SUCCEEDED ou FAILED.
processedCount Nombre de messages traités jusqu'à présent.
totalCount Nombre total de messages dans le lot.

Une fois l'opération terminée, le champ done est défini sur true et le champ response contient un résultat pour chaque message du lot :

{
  "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"
        }
      }
    ]
  }
}

Chaque entrée de results décrit le résultat d'un message :

Champ de résultat Description
name Nom de ressource du message.
status Un google.rpc.Status. Un objet vide (code 0, OK) signifie que l'action a réussi. Sinon, code et message expliquent pourquoi le message a été ignoré.
quarantinedMessage Le message mis à jour avec son nouveau state. Présent uniquement lorsque status est OK.

Une opération par lot réussit même si certains messages individuels échouent. Inspectez toujours le status de chaque résultat plutôt que de vous fier uniquement au state de l'opération.

Si l'ensemble de l'opération échoue, par exemple parce que le backend n'est pas disponible, le champ done est défini sur true et le champ error contient un google.rpc.Status au lieu de response.

Exemple : Libération par lot et interrogation pour l'achèvement

L'exemple Python suivant démarre une version par lot et interroge l'opération toutes les quelques secondes jusqu'à ce qu'elle se termine :

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')}")

Étapes suivantes