我正在使用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转换为节点。
答案 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!
}
答案 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;
});
}