Ad

Problem With Loading File To Facebook Messenger Through NodeJS

I'm building a chatbot for facebook using NodeJS, and I'm having a hard time trying sending a local file through messeger by Facebook's API, according to the documentation to perform the loading of a file, it is necessary to make a remote call as in the example below:

curl  \
  -F 'message={"attachment":{"type":"image", "payload":{"is_reusable":true}}}' \
  -F '[email protected]/tmp/shirt.png;type=image/png' \
  "https://graph.facebook.com/v2.6/me/message_attachments?access_token=<PAGE_ACCESS_TOKEN>"

In fact using the example, the upload of the file is performed, and the 'attachment_id' is returned so that I can attach the file to one or more messages, however I'm not able to upload through my application, I've already tried structure the file in different ways on the object, trying to put the path, trying to put the file stream, etc, but always the following error is returned:

{
    message: '(#100) Incorrect number of files uploaded. Must upload exactly one file.',
    type: 'OAuthException',
    code: 100,
    error_subcode: 2018005,
    fbtrace_id: 'XXXXXXXXXX',
    { recipient: { id: 'XXXXXXXXXX' },
    message: { attachment: { type: 'file', payload: [Object] } },
    filedata: '@pdf_exemple.pdf;type=application/pdf' 
}

I am not an expert on Node / JavaScript so it is possible that I am making some silly mistake... Anyway, below is the snippet of my code responsible for assembling the object and sending it to facebook. Any help is welcome.

function callSendAPI(messageData) {
    request({
        url: 'https://graph.facebook.com/v2.6/me',
        qs : { access_token: TOKEN },
        method: 'POST',
        json: messageData
    }, function(error, response, body) {
        if (error) {
            console.log(error);
        } else if (response.body.error) {
            console.log(response.body.error);
        }
    })
}

function sendAttachment(recipientID) {
    var messageData = {
        recipient: {
            id: recipientID
        },
        message: {
            attachment: {
                type: 'file', 
                payload: {
                    'is_reusable': true,
                }
            }
        },
        filedata: '@pdf_exemple.pdf;type=application/pdf'
    };
    callSendAPI(messageData);
}
Ad

Answer

After searching a lot, I was able to make the necessary changes to my application's methods to make it possible to transfer files through messeger, the concept was almost right, what was wrong was the way the data was being sent, the correct one is send them through a form. Here is the solution:

function callSendAPI(messageData, formData) {
    request({
        url: 'https://graph.facebook.com/v2.6/me',
        qs : { access_token: TOKEN },
        method: 'POST',
        json: messageData,
        formData: formData,
    }, function(error, response, body) {
        if (error) {
            console.log(error);
        } else if (response.body.error) {
            console.log(response.body.error);
        }
    })
}

function sendAttachment(recipientID, fileName) {
    var fileReaderStream = fs.createReadStream(fileName)
    var formData = {
                recipient: JSON.stringify({
                id: recipientID
            }),
            message: JSON.stringify({
            attachment: {
                type: 'file',
                payload: {
                    is_reusable: false
                }
            }
        }),
       filedata: fileReaderStream
    }
    callSendAPI(true, formData);
}
Ad
source: stackoverflow.com
Ad