如何在Node js中使用facebook messenger发送图像API?

时间:2017-08-18 07:41:06

标签: node.js facebook facebook-graph-api curl facebook-messenger-bot

我正在使用facebook messenger API在nodejs中构建一个facebook bot。我正试图通过直接上传来自heroku服务器本身的图像文件(不通过URL )从机器人发送图像,但它不起作用。

以下是来自控制台的错误日志。

  

调用Send API 400 Bad Request {message:'(#100)不正确   上传的文件数量。必须上传一个文件。',键入:   'OAuthException',代码:100,error_subcode:2018005,fbtrace_id:   'E32ogm / ofxd'}

official facebook document仅包含卷曲格式的示例,并且我不知道如何将此卷曲复制到节点格式。

我已经用卷发进行测试,它就像一个魅力。

curl  \   -F 'recipient={"id":"recipientId"}' \   -F 'message={"attachment":{"type":"image", "payload":{}}}' \   -F 'filedata=@resource/pdf_img/sample.jpg;type=image/jpeg' \   "https://graph.facebook.com/v2.6/me/messages?access_token=PAGE_ACCESS_TOKEN"

这是我的节点实现似乎有问题,

//file_loc = __dirname+"/resource/pdf_img/sample.jpg"
function sendImageMessage(recipientId, file_loc){
    let fs = require('fs');
    var readStream = fs.createReadStream(file_loc);
    var messageData = {
        recipient : {
            id : recipientId
        },
        message : {
            attachment : {
                type : "image",
                payload :{}
            }
        },
        filedata:readStream
    }
    callSendAPI(messageData);
}
function callSendAPI(messageData) {
    request({
        uri: "https://graph.facebook.com/v2.6/me/messages",
        qs: {access_token: process.env.PAGE_ACCESS_TOKEN},
        method: "POST",
        json: messageData
    }, function(error, response, body) {
        if (!error && response.statusCode == 200) {
            var recipientId = body.recipient_id;
            var messageId = body.message_id;

            if (messageId) {
                console.log("Successfully sent message with id %s to recipient %s", 
                    messageId, recipientId);
            } else {
                console.log("Successfully called Send API for recipient %s", 
                    recipientId);
            }
        } else {
            console.error("Failed calling Send API", response.statusCode, response.statusMessage, body.error);
        }
    });
} 

请帮助修复我的节点实现或将该curl转换为节点。

2 个答案:

答案 0 :(得分:1)

您可以在请求模块中使用forms / form-data /(它具有集成模块'form-data')。 但是所有请求都需要进行字符串化。 因此,根据您的示例,以下内容应该执行作业>>

function sendImageMessage(recipientId, file_loc){
    let fs = require('fs');
    var readStream = fs.createReadStream(file_loc);
    var messageData = {
        recipient : {
            id : recipientId
        },
        message : {
            attachment : {
                type : "image",
                payload :{}
            }
        },
        filedata:readStream
    }
    callSendAPI(messageData);
}

function callSendAPI(messageData) {
    var endpoint = "https://graph.facebook.com/v2.6/me/messages?access_token=" + process.env.PAGE_ACCESS_TOKEN;
    var r = request.post(endpoint, function(err, httpResponse, body) {
        if (err) {return console.error("upload failed >> \n", err)};
        console.log("upload successfull >> \n", body); //facebook always return 'ok' message, so you need to read error in 'body.error' if any
    });
    var form = r.form();
    form.append('recipient', JSON.stringify(messageData.recipient));
    form.append('message', JSON.stringify(messageData.message));
    form.append('filedata', messageData.filedata); //no need to stringify!
}

此处详细信息https://github.com/request/request#forms

答案 1 :(得分:0)

我认为将变量messagedata作为formdata发送可以解决问题。

var FormData = require('form-data');
var fs = require('fs');
var https = require('https');

function sendImageMessage(recipientId, file_loc){
 var readStream = fs.createReadStream(file_loc);
 var messageData = new FormData();
 messageData.append('recipient', '{id:' +recipientId+ '}');
 messageData.append('message', '{attachment :{type:"image", payload:{}}}');
 messageData.append('filedata', readStream);
 callSendAPI(messageData);
}

其次,您需要稍微更改请求,因为现在您正在使用formdata。我使用模块https完成了它,因此相应地更改了callSendAPI()代码。您可以使用请求模块了解如何发送formdata。

function callSendAPI(messageData) {
    var options = {
    method: 'post',
    host: 'graph.facebook.com',
    path: '/v2.6/me/messages?access_token=' + pagetoken,
    headers: messageData.getHeaders()
  };
  var request = https.request(options);
  messageData.pipe(request);

  request.on('error', function(error) {
  console.log("Unable to send message to recipient %s", recipientId);
    return;
  });
  request.on('response', function(res) {
    if (res.statusMessage == "OK") {
      console.log("Successfully sent message to recipient %s", recipientId);
    } else {

      console.log("Unable to send message to recipient %s", recipientId);
    }
    return;
  }); 
}