0

我正在用facebook messenger API在nodejs中構建一個facebook bot。我試圖通過直接從heroku服務器本身上傳圖像文件(而不是通過URL)從機器人發送圖像,但它不起作用。如何在Node js中使用facebook messenger發送圖像API?

這是來自控制檯的錯誤日誌。

失敗調用發送API 400錯誤請求{消息:'(#100)不正確 上傳的文件數量。必須上傳正好一個文件 '類型: 'OAuthException',代碼:100,error_subcode:2018005,fbtrace_id: 'E32ogm/ofxd'}

official facebook document只包含捲曲格式的一例和I'不知道如何將這個curl複製到節點格式中。

我已經測試過捲曲,它的工作就像一個魅力。

curl \ -F 'recipient={"id":"recipientId"}' \ -F 'message={"attachment":{"type":"image", "payload":{}}}' \ -F '[email protected]/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); 
     } 
    }); 
} 

請即固定捲曲到節點我節點的實現或翻譯任何幫助,將不勝感激。

+0

一個問題是,你必須發送'message','filedata'和'recipient'的形式數據,而不是json。 – amuramoto

回答

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; 
    }); 
} 
0

您可以在請求模塊(它具有集成的模塊'form-data')中使用forms/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

相關問題