2017-10-17 8 views
1

J'essaie de récupérer, puis POST une image JPEG au point de terminaison https://api.foursquare.com/v2/photos/add de Foursquare en utilisant Axios dans le nœud. J'ai essayé quelques méthodes avec Axios (et Postman), mais toujours reçu la même réponse d'erreur de Missing file upload:Récupérer puis POST une photo à un Foursquare Checkin avec Axios

{ 
    "meta": { 
    "code": 400, 
    "errorType": "other", 
    "errorDetail": "Missing file upload", 
    "requestId": "NNNNNNNNNNNNNNNNNNNNN" // not the true requestId 
    }, 
    "notifications": [ 
    { 
     "type": "notificationTray", 
     "item": { 
     "unreadCount": 0 
     } 
    } 
    ], 
    "response": {} 
} 

L'image est créée en utilisant l'API Google Map statique et récupéré avec une demande Axios GET:

const image = await axios.get(imageURL, { 
    responseType: "arraybuffer" 
}); 

qui est enveloppé dans une fonction async et renvoie un tampon avec succès. Les données sont lues dans un Buffer et converti en une chaîne:

const imageData = new Buffer(image, "binary").toString(); 

Here's an example imageData string. J'ai également essayé de convertir la chaîne en base64.

Cette chaîne est alors POST ed au point final Foursquare:

const postPhoto = await axios.post(
    "https://developer.foursquare.com/docs/api/photos/add? 
    checkinId=1234& 
    oauth_token=[TOKEN]& 
    v=YYYYMMDD", 
    imageData, 
    { 
    headers: { "Content-Type": "image/jpeg" } 
    } 
); 

où les checkinId, oauth_token et v params sont tous valides.

J'ai essayé différentes valeurs Content-Type, base64 codant le imageData et plusieurs autres solutions trouvées dans les forums et ici sur SO (la plupart datent de plusieurs années), mais rien ne fonctionne. La réponse errorDetail dit toujours Missing file upload.

Le problème pourrait être la façon dont la demande POST est structurée, mais je pourrais aussi demander/traiter incorrectement les données d'image. Un 2ème (ou 3ème, ou 4ème) ensemble d'yeux pour vérifier que je mets cela ensemble serait super utile.

Répondre

1

Ouf, j'ai finalement résolu ceci.

J'ai finalement pu le faire fonctionner par le biais de Postman qui a fourni quelques conseils. Voici l'extrait de code Postman en utilisant request:

var fs = require("fs"); 
var request = require("request"); 

var options = { method: 'POST', 
    url: 'https://api.foursquare.com/v2/photos/add', 
    qs: 
    { checkinId: [MY CHECKING ID], 
    public: '1', 
    oauth_token: [MY OAUTH TOKEN], 
    v: [MY VERSION] }, 
    headers: 
    { 'postman-token': '8ce14473-b457-7f1a-eae2-ba384e99b983', 
    'cache-control': 'no-cache', 
    'content-type': 'multipart/form-data; boundary=---- WebKitFormBoundary7MA4YWxkTrZu0gW' }, 
    formData: 
    { file: 
     { value: 'fs.createReadStream("testimage.jpg")', 
     options: { 
      filename: 'testimage.jpg', 
      contentType: null 
     } 
     } 
    } 
    }; 

request(options, function (error, response, body) { 
    if (error) throw new Error(error); 

    console.log(body); 
}); 

La partie clé de c'était fs.createReadStream(). La partie qui me manquait avant était de passer l'image comme un flux à la demande.

L'utilisation de ce que j'ai pu comprendre la demande Axios:

const axios = require("axios"); 
const querystring = require("qs"); 
const FormData = require("form-data"); 

const getImageStream = async function(url) { 
    return await axios 
    .get(url, { 
     responseType: "stream" 
    }) 
    .then(response => response.data); 
}; 

let form = new FormData(); 
form.append("file", getImageStream([IMAGE URL])); 

const requestURL = "https://api.foursquare.com/v2/photos/add"; 
const requestParams = { 
    checkinId: [MY CHECKIN ID], 
    public: 1, 
    oauth_token: [MY OAUTH TOKEN], 
    v: [MY VERSION] 
}; 
const requestConfig = { 
    headers: form.getHeaders() 
}; 

try { 
    const postPhoto = await axios.post(
    requestURL + "?" + querystring.stringify(requestParams), 
    form, 
    requestConfig 
); 

    return postPhoto; 
} catch (e) { 
    console.error(e.response); 
} 

Et le tour est joué, la demande réussit et l'image est affichée à la Foursquare checkin.