Descargar el objeto ContentVersion como JPG usando JSForce

Aug 23 2020

Estoy intentando descargar un archivo JPG almacenado como archivo adjunto en Salesforce en la máquina local. Tengo una URL que funciona correctamente cuando uso una solicitud GET en Workbench. Cuando trato de hacer lo mismo en Node.JS (usando JSForce), no puedo hacer que el archivo salga como JPG.

Esto es lo que tengo:

var jsforce = require('jsforce');
var conn = new jsforce.Connection();
conn.login('<username>', '<password>', function(err, res) {
  if (err) { return console.error(err); }  
conn.request('https://<my-dev-ed-instance>.my.salesforce.com/services/data/v42.0/sobjects/ContentVersion/<uuid>/VersionData', function(err, res) {
 if (err) { return console.error(err); }
 console.log(res);
 fs.writeFileSync('2.jpg',res,'base64');
});
});

Creo que la solicitud GET debería devolver una cadena BASE64, pero parece que no puedo convertirla o hacerla útil.

¡Cualquier ayuda será muy apreciada!

EDITAR: Encontré una solución. Tbh, realmente solo necesitaba dormir un poco y despertar y usar Postman para solucionar problemas correctamente.

var https = require('follow-redirects').https;
var fs = require('fs');

var options = {
  'method': 'GET',
  'hostname': '<HOSTNAME>',
  'path': '/services/data/v49.0/sobjects/ContentVersion/<UUID>/VersionData',
  'headers': {
    'Authorization': 'Bearer <TOKEN>',
    'Cookie': 'BrowserId=<COOKIE>',
    'Content-Type': 'text/plain'
  },
  'maxRedirects': 20
};

var req = https.request(options, function (res) {
  var chunks = [];

  res.on("data", function (chunk) {
    chunks.push(chunk);
  });

  res.on("end", function (chunk) {
    var body = Buffer.concat(chunks);
    fs.writeFileSync('output.jpg',body,'binary');
  });

  res.on("error", function (error) {
    console.error(error);
  });
});

req.end();

Gracias a quienes ayudaron, definitivamente me señalaron en la dirección correcta.

Respuestas

1 MaxGoldfarb Aug 24 2020 at 00:59

Aquí hay una solicitud de búsqueda de JS de muestra que convertí en Postman (esto es un pseudocódigo y probablemente no funcionará). Utilizo el siguiente punto final /services/data/v48.0/sobjects/Attachment/<ATTACHMENT_FILE_ID>/Body PERO la respuesta es binaria, por lo que necesitaría manejar esa respuesta y convertirla a JPG

https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/dome_sobject_blob_retrieve.htm

También puede intentar obtener el contenido del archivo con Connect API y el siguiente punto final (aún respuesta binaria): /services/data/v{{version}}/connect/files/<FILE_ID>/contentO cree un enlace público para compartir archivos con el siguiente punto final y use ese enlace de una forma u otra (solicitud PUT):/services/data/v{{version}}/connect/files/<FILE_ID>/file-shares/link

https://developer.salesforce.com/docs/atlas.en-us.chatterapi.meta/chatterapi/connect_resources_files_content.htm

https://developer.salesforce.com/docs/atlas.en-us.chatterapi.meta/chatterapi/connect_resources_files_shares_link.htm

var myHeaders = new Headers();
myHeaders.append("Authorization", "Bearer <ACCESS_TOKEN>");

var requestOptions = {
  method: 'GET',
  headers: myHeaders,
  redirect: 'follow'
};

fetch("https://domain.my.salesforce.com/services/data/v48.0/sobjects/Attachment/<ATTACHMENT_FILE_ID>/Body", requestOptions)
  .then(...)
sfdcfox Aug 23 2020 at 17:00

El extremo de Blob Retrieve en realidad devuelve el contenido del archivo como un archivo binario. No es necesario decodificar el valor en base64. Consulte la documentación .

El contenido del cuerpo del adjunto se devuelve en formato binario. Tenga en cuenta que el tipo de contenido de la respuesta no será JSON o XML, ya que los datos devueltos son binarios.

Nota: esto es para un cuerpo de adjunto, pero también se aplica a cualquier otro contenido de Blob.


Aquí hay un ejemplo rápido que escribí:

var jsforce = require('jsforce');
var fs = require('fs');
const conn = new jsforce.Connection();

conn.login('<username>', '<password>')
    .then(() => {
        conn.request('/services/data/v49.0/sobjects/ContentVersion/.../VersionData').then((result) => {
            fs.writeFileSync('output.data', result);
        });
    });