检索然后将照片发布到带有Axios的Foursquare签到

时间:2017-10-17 09:53:50

标签: javascript foursquare axios

我正在尝试使用Node中的https://api.foursquare.com/v2/photos/add将JPEG图像POST检索到Foursquare的Axios端点。我已经尝试了一些Axios(和Postman)的方法,但总是收到Missing file upload的相同错误响应:

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

图片是使用Google Static Map API创建的,并使用Axios GET请求进行检索:

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

包含在async函数中并成功返回缓冲区。数据被读入Buffer并转换为字符串:

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

Here's an example imageData string。我也尝试将字符串转换为base64

然后将此字符串POST添加到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" }
  }
);

其中checkinIdoauth_tokenv参数均有效。

我尝试了不同的Content-Type值,base64编码imageData以及在论坛中找到的其他几个解决方案,这里有SO(大多数都是几年),但没有任何效果。响应errorDetail总是说Missing file upload

问题可能在于POST请求的结构如何,但我也可能错误地请求/处理图像数据。第二个(或第三个或第四个)眼睛检查我把它放在一起将是非常有帮助的。

1 个答案:

答案 0 :(得分:1)

哇,我终于解决了这个问题。

我最终能够通过Postman工作,提供了一些提示。这是使用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);
});

这个关键部分是fs.createReadStream()。我之前缺少的部分是将图像作为流传递给请求。

使用这个我能够找出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);
}

瞧,请求成功,图像发布到Foursquare签到。