Passer au contenu principal

Utiliser les téléversements reprenables

Lors de l’utilisation des endpoints de conformité par lots (Batch compliance), les développeurs peuvent téléverser en batch de grandes quantités de données X et déterminer les actions nécessaires pour s’assurer que leurs jeux de données reflètent l’intention des utilisateurs et l’état actuel du contenu sur X. Le téléversement de gros volumes de données vers un serveur distant est une opération relativement simple lorsque les systèmes et la connectivité sont stables et fiables. Cependant, ce n’est pas toujours le cas. Certains environnements peuvent imposer un délai d’expiration de la connexion, coupant effectivement la liaison entre votre App et le serveur de téléversement après un certain temps ; vous pouvez également rencontrer des problèmes de connexion, par exemple lorsque vous essayez de téléverser un fichier volumineux depuis votre ordinateur portable via une connexion Wi‑Fi. Dans ces circonstances, il est préférable de téléverser des portions plus petites de ce fichier à la fois, plutôt que d’établir une seule connexion continue. Les endpoints de conformité par lots de X s’appuient sur Google Cloud Storage pour traiter les fichiers volumineux. Ce type de stockage est optimisé pour diverses applications ; Cloud Storage prend en charge une technique de gestion des gros fichiers appelée téléversement reprenable. Si le téléversement échoue à un moment quelconque, Google Cloud Storage peut reprendre l’opération là où elle s’est arrêtée.

Création d’un job reprenable

Première étape :

Tout d’abord, vous devez créer une tâche de conformité et préciser si vous allez envoyer des ID de Post ou des id d’utilisateur (à l’aide du paramètre type). Ajoutez également resumable dans le corps de la requête et définissez-le sur true. Veillez à remplacer $APP_ACCESS_TOKEN par votre App only Access Token.
curl --request POST \
 'https://api.x.com/2/compliance/jobs' --header 'Authorization: Bearer $APP_ACCESS_TOKEN --header 'Content-Type: application/json' --data-raw '{
   "type": "tweets",
   "resumable": true
}'
Si votre appel à l’API aboutit, vous recevrez une réponse similaire à la suivante :
{
   "data": {
       "download_expires_at": "2021-08-18T19:42:55.000Z",
       "status": "created",
       "upload_url": "https://storage.googleapis.com/twttr-tweet-compliance/1425543269983784962/submission/1202726487847104512_1425543269983784962?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=complianceapi-public-svc-acct%40twttr-compliance-public-prod.iam.gserviceaccount.com%2F20210811%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20210811T194255Z&X-Goog-Expires=900&X-Goog-SignedHeaders=content-type%3Bhost&X-Goog-Signature=355e4c4739ae508304d3df15b4e13e64b6c7752d8d79d73676a4d8e60dc5241f83924ad2a1f8b7bddcc768062bb9c64d39b8e8f7cce7f66ffbea9f9ed33a4da975b3a2c127fb738c1c1ff3c3964bd4d9dc0706e6c8a70e67522160ea774e090d2793e06f890d1158ce86be3031c1c471b74f961b6f18743a28730611000336286ad0111b41fb5d14aa813ff00cf06b3572dc68d0b3c6fdc07f25c1b1196c1af4325a9ead68994944bbef0d2123585ea051deb9765aa7f5832446440bc9ba76af327b69df1fd7b1a99bd4419c128f1f697dbbacbc62bbc7c2c9aebc82a2128be0ed05d48a54d814162daad1232a0d13081e9543ab8557f567149af82281193f37",
       "created_at": "2021-08-11T19:42:55.000Z",
       "resumable": false,
       "id": "1425543269983784962",
       "type": "tweets",
       "download_url": "https://storage.googleapis.com/twttr-tweet-compliance/1425543269983784962/delivery/1202726487847104512_1425543269983784962?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=complianceapi-public-svc-acct%40twttr-compliance-public-prod.iam.gserviceaccount.com%2F20210811%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20210811T194255Z&X-Goog-Expires=604800&X-Goog-SignedHeaders=host&X-Goog-Signature=0a11dd5a3c5adb508f32ce904568abada863dc9499ba2adeafb3452ccee0dcb3dade17910dbc502dcbe54c130ac4d8638eb176c8b7344de068139b06c970794efa6312f0a5149f40da441eafcaf475f670c93ca73951999902a531d34dfab1e5490918929e5b06ae803b5604e0c0c26852255ccdbc79a2c1e2eefe924e5e6bf5b6603a7f287d1621333b9548ec6cc203716070528bebc2e67c12e92b1f4e54471db92c15a54799f2b855ae224250ca44c47993fd7d79a4940a0f68fe09f73fc8b291e88cfd10ade860b4b35c2b964d1777c1d93cd300c313138d9ca90aa8b3ecd3bf9dc73d3ebe32ba7634228fe07e1e4ecdda57cd94c802afc520162735d5a3",
       "upload_expires_at": "2021-08-11T19:57:55.000Z"
   }
}
Notez la valeur de upload_url, vous en aurez besoin dans les étapes suivantes.

Étape deux : 

Ensuite, vous devrez initialiser le téléversement reprenable. Pour ce faire, effectuez un appel POST vers l’upload_url de l’étape précédente et veillez à inclure les en-têtes suivants : Content-Type: text/plain Content-Length: 0 x-goog-resumable: start
curl --request POST \
'https://storage.googleapis.com/twttr-tweet-compliance/1430227686685757442/submission/1202726487847104512_1430227686685757442?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=complianceapi-public-svc-acct%40twttr-compliance-public-prod.iam.gserviceaccount.com%2F20210824%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20210824T175707Z&X-Goog-Expires=900&X-Goog-SignedHeaders=content-length%3Bcontent-type%3Bhost%3Bx-goog-resumable&X-Goog-Signature=890d958f9c7dcb7f238e4971b59da5afc5b8329fb197c67b5930fe0f9dfe180afe2d4bec341111809b88ccfab46ab1f81f4242abc1af7b67c6e8977c52e6d486f5f43ce6a37a7a6530d25f15e2bcd9bb54655fe4ee22b26f8886ba71b67b7b11afd1198d658d1b6f0c41260f55260a260e1be0239977feba43dce40bc0e8e6293a4a3a3f7ee0afc74d3d2f7f2d3d514f108d5887a52ac85760385e5b9bb67cd26bfcf6b1c19151ea8111e217a29407722dc0dc9ab373334e88c18159546237ec9334f9a1e33717dc82800c6a45bba82706d5aece84ecdf3fcac52b21c8a3085a639047cf2707a8b9e4c296fc7cf05edbb110f07b89e38f0f5ea77e8b313cade7' \
--header 'Content-Type: text/plain' --header \
 'Content-Length: 0' --header \
 'x-goog-resumable: start
Si cet appel réussit, vous obtiendrez un code de réponse 201. Ensuite, dans l’en-tête de la réponse, copiez la valeur de l’en-tête Location, qui ressemblera à ceci :
https://storage.googleapis.com/twttr-tweet-compliance/1430227686685757442/submission/1202726487847104512_1430227686685757442?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=complianceapi-public-svc-acct%40twttr-compliance-public-prod.iam.gserviceaccount.com%2F20210824%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20210824T175707Z&X-Goog-Expires=900&X-Goog-SignedHeaders=content-length%3Bcontent-type%3Bhost%3Bx-goog-resumable&X-Goog-Signature=890d958f9c7dcb7f238e4971b59da5afc5b8329fb197c67b5930fe0f9dfe180afe2d4bec341111809b88ccfab46ab1f81f4242abc1af7b67c6e8977c52e6d486f5f43ce6a37a7a6530d25f15e2bcd9bb54655fe4ee22b26f8886ba71b67b7b11afd1198d658d1b6f0c41260f55260a260e1be0239977feba43dce40bc0e8e6293a4a3a3f7ee0afc74d3d2f7f2d3d514f108d5887a52ac85760385e5b9bb67cd26bfcf6b1c19151ea8111e217a29407722dc0dc9ab373334e88c18159546237ec9334f9a1e33717dc82800c6a45bba82706d5aece84ecdf3fcac52b21c8a3085a639047cf2707a8b9e4c296fc7cf05edbb110f07b89e38f0f5ea77e8b313cade7&upload_id=ADPycds-_Ow7aqcpbG4XguXSVAgd_2fy-XiDA2qm-It9PCwBlZhF4e2bfOAQzEmRJ4T_l6jU6LfYdfrKa_KlFFBOyx3PjYzrxQ
Vous pouvez ensuite importer vos id de Post ou d’utilisateur à cet emplacement en suivant l’étape deux et les suivantes, à partir du guide « Bien démarrer ». En raison de leur complexité technique, les envois repris (resumable uploads) sont à privilégier avec du code. Ce guide utilisera Node.js avec la bibliothèque de requêtes needle.

Installer les dépendances

Avant de continuer, vous devez disposer d’un environnement Node.js ; vous pouvez obtenir Node.js sur son site web. Une fois installé, Node.js inclut un utilitaire appelé npm ; vérifiez que Node et npm sont tous deux installés en exécutant la commande suivante et assurez-vous qu’elle ne renvoie pas d’erreur. $ npm -v 6.4.1 Un numéro de version similaire indique que votre environnement est prêt (notez que votre numéro peut différer). Nous utiliserons npm pour installer la bibliothèque d’envoi. Exécutez cette commande : $ npm install -g needle Tout est prêt ; aucune configuration supplémentaire n’est requise.

Demander une destination reprenant les envois

Lors de la création d’un nouveau job, définissez le paramètre resumable sur true afin d’obtenir une destination qui prend en charge le téléversement reprenable. Dans le corps de la réponse, vous recevrez une valeur upload_url.
"upload_url":\
"https://storage.googleapis.com/compliance_tweet_ids/customer_test_object_12950882_GlYjiE?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=193969463581-compute%40developer.gserviceaccount.com%2F20200618%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20200618T184154Z&X-Goog-Expires=900&X-Goog-SignedHeaders=content-type%3Bhost&X-Goog-Signature=b7bdcf32479b08715be91ed47b06471b8acdcdb319f8e4f423bf3a3056dfa03ed83e47446f33338e292967a15c08fa5ba34395edaf057a2ac975b88e710ca994adb023a9e1673a7c58ce2fa0d73537f72812af78e92b708dfe6b907a7d75bd0f6cfa61fec867e80ac83ced0725d1ee59787c9dbca50d41f7b0f513dad63a7564136b1a70042a2ec6ba6b697cbe480a4405362f7a08255a5e8205aa7baa562f99e6a092f0420f33d67ffaeb132f877fbaf16c969630b5f173e8a3f31c473707241fa4e28f4bed13fb2ea01d3af1c449321a2e6ee9ec1e331b447cabcfc6f9d1f99f564d180f0cc1d28ea54972c996102c67c6501c6c16a00c13d17756f960e0e1"

Préparez le code pour téléverser un fichier

Par défaut, la bibliothèque crée une nouvelle destination de téléversement en prenant un emplacement de téléversement (appelé bucket) et le nom du fichier à téléverser. Comme les endpoints de conformité par lots créent leur propre destination, nous devons indiquer à la bibliothèque que nous disposons déjà d’un emplacement prêt à accepter notre téléversement. Nous devons transmettre cette valeur à la bibliothèque de téléversement, ainsi que le nom du fichier contenant les data à téléverser. Créez un fichier nommé twitter-upload.js. Ajoutez le code suivant :
const needle = require('needle');
const fs = require('fs');
const path = require('path');

const [, scriptName, filename, uploadURL] = process.argv;
if (!filename || !uploadURL) {
  console.error(`Utilisation : node ${path.basename(scriptName)} nom_fichier url_téléversement`);
  process.exit(-1);
}

async function uploadFile(file, url) {
  // rangeEnd est l'index du dernier octet du fichier, c'est-à-dire le nombre d'octets du fichier
  const rangeEnd = (await fs.promises.stat(file)).size;

  let options = {
    headers: {
      'Content-Range': `bytes */${rangeEnd}`,
    },
  };

  const response = await needle('put', url, null, options);

  switch (response.statusCode) {
    case 200:
    case 201:
      console.log('Téléversement terminé');
      return;
    case 308:
      return resumeUpload(response, file, url);
    default:
      console.log('Code de réponse inattendu reçu : ', response.statusCode);
      return;
  }
}

async function resumeUpload(response, file, url) {
  console.log('Téléversement non terminé, reprise en cours');
  if (response.headers.range) {
    let resumeOffset = Number(response.headers.range.split('-')[1]) + 1;

    let options = {
      headers: {
        'Content-Range': `bytes ${resumeOffset}-${rangeEnd-1}/${rangeEnd}`,
        'Content-Length': `${rangeEnd-resumeOffset}`,
      },
    };

    let readStream = fs.createReadStream(file, {start: resumeOffset});
    return needle('put', url, readStream, options);
  } else {
    console.log('Initialisation du téléversement');
    let options = {
      headers: {
        'Content-Type': 'text/plain'
      }
    };

    let readStream = fs.createReadStream(file);
    return needle('put', url, readStream, options);
  }
}

// Demander l'URL de session reprise
async function requestResumableSession(url) {
  const options = {
    headers: {
      'Content-Type': 'text/plain',
      'Content-Length': '0',
      'x-goog-resumable': 'start',
    },
  };

  const res = await needle('post', url, null, options);
  if (res.statusCode === 201) {
    const resumableSessionURL = res.headers['location'];
    console.log('Démarrage du téléversement vers : ', resumableSessionURL);

    await uploadFile(filename, resumableSessionURL);
  } else {
    console.log('Échec de la création de l\'URI de session reprise');
  }

}

requestResumableSession(uploadURL).then(result => console.log('Téléversement terminé'));
Enregistrez le fichier à l’endroit le plus approprié. Ensuite, dans votre terminal, exécutez le script et passez deux paramètres :
  1. Le premier correspond à l’emplacement du fichier (contenant les Post ou User id) que vous souhaitez téléverser.
  2. Le second est l’URL de téléversement que nous avons reçue dans la réponse de l’endpoint de conformité.
Assurez-vous que l’URL est entre guillemets doubles, et faites de même pour le nom de votre fichier s’il contient des espaces ou d’autres caractères :
node twitter-upload.js compliance_upload.txt\
"https://storage.googleapis.com/compliance_tweet_ids/customer_test_object_12950882_GlYjiE?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=193969463581-compute%40developer.gserviceaccount.com%2F20200618%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20200618T184154Z&X-Goog-Expires=900&X-Goog-SignedHeaders=content-type%3Bhost&X-Goog-Signature=b7bdcf32479b08715be91ed47b06471b8acdcdb319f8e4f423bf3a3056dfa03ed83e47446f33338e292967a15c08fa5ba34395edaf057a2ac975b88e710ca994adb023a9e1673a7c58ce2fa0d73537f72812af78e92b708dfe6b907a7d75bd0f6cfa61fec867e80ac83ced0725d1ee59787c9dbca50d41f7b0f513dad63a7564136b1a70042a2ec6ba6b697cbe480a4405362f7a08255a5e8205aa7baa562f99e6a092f0420f33d67ffaeb132f877fbaf16c969630b5f173e8a3f31c473707241fa4e28f4bed13fb2ea01d3af1c449321a2e6ee9ec1e331b447cabcfc6f9d1f99f564d180f0cc1d28ea54972c996102c67c6501c6c16a00c13d17756f960e0e1"
Vous verrez une sortie similaire à celle-ci : Starting upload to: https://storage.googleapis.com/twttr-tweet-compliance/<redacted> Upload not completed, resuming Initiating upload Vous pouvez mettre en pause l’envoi à tout moment en appuyant sur Ctrl + C ou en fermant votre terminal. Vous pourrez reprendre l’envoi là où vous vous êtes arrêté en relançant la même commande ultérieurement. Une fois le fichier entièrement envoyé, le message suivant s’affichera : Upload complete À ce stade, vous pourrez utiliser l’endpoint d’état de conformité pour vérifier l’état de votre tâche de conformité et télécharger le résultat de conformité une fois prêt.
I