Smooch - create attachments from buffer

88 views Asked by At

I'm trying to create an image via smooch-core API

I have an image as Buffer - base64, And I try something like this:

smoochClient.attachments
            .create({
                appId: appId,
                props: {
                    for: 'message',
                    access: 'public',
                    appUserId: appUserId
                },
                source: myBuffer
            })
            .then(() => {
                console.log('OK');
            }).catch(err => {
            console.log(JSON.stringify(err));
        });

I get this error: "status":413,"statusText":"Payload Too Large"

[When I create this image normally through Postman it does work well, so it's not too big - I guess it's because of the Buffer's sending]

Anyone know how I can send a buffer to this API?

2

There are 2 answers

0
Hodaya Shalom On BEST ANSWER

I found such a solution:

Create a temporary file to get it's read stream and send it in source instead of the myBuffer parameter and here is the code of creating the temporary file:

 async getTempFileSource(bufferData) {
        const fs = require("fs");
        //remove mime type
        if (bufferData.startsWith('data:'))
            bufferData = bufferData.split('base64,')[1];
        //Get file extension
        const type = await require('file-type').fromBuffer(new Buffer(bufferData, 'base64'));
        if (!type) {
            console.log("getTempFileSource - The buffer data is corrupted", 'red');
            return null;
        }
        //create temporary file
        const tempFile = require('tmp').fileSync({postfix: '.' + type.ext});
        //append buffer data to temp file
        fs.appendFileSync(tempFile.name, new Buffer(bufferData, 'base64'));
        //create read stream from the temp file
        const source = fs.createReadStream(tempFile.name);
        //remove the temp file
        tempFile.removeCallback();
        return source;
    }

Here is the code for creating the attachment:

 return new Promise(async (resolve, reject) => {
        const source = await getTempFileSource(bufferData);
        if (!source)
            resolve(null);
        else {
            session.smoochClient.attachments
                .create({
                    appId: appId,
                    props: {
                        for: 'message',
                        access: 'public',
                        appUserId: appUserId
                    },
                    source: source
                })
                .then(res => {
                    resolve(res);
                }).catch(err => {
                reject(err);
            });
        }
    });
0
Adam Smooch On

Are you able to submit the base64 data directly in the postman call?

Reading through the spec here it looks like source should be a filepath/name, and not raw binary data.

The easy way may be to save the base64 data to a[n appropriately encoded] file, then provide that file's path as source

Otherwise I'm not sure I'd go so far as to take apart api_instance.upload_attachment() to feed in the base64 data instead of opening/reading from the specified filename.