Invalid Content-Type: The retrieved media has an incorrect Content-Type

847 views Asked by At

I am using twilio to try and send an MMS message. The twilio server needs my to send my png image so it can save it in their db and send me a unique Id to access that png.

I am testing this feature as a newbie.

I have tried sending the png image as an html image blob after getting in the frontend with a file input tag

Here is my frontend below to upload image


const manualMMSUpload = (e) => {
        e.preventDefault();
        if(e.target.files[0].name) {
            setUserMMS(e.target.files[0].name)
            const viewFile = URL.createObjectURL(e.target.files[0])
            console.log(viewFile) // <-- shows blob:http://localhost:3000/06fe4f1a-06fb-4baf-a18f-7698ffd6e227
            handleInputChange({value: viewFile, name: "fileData"})   
        }
      }

<input 
          type="file" 
          onChange={(e) => manualMMSUpload(e)}
          accept=".gif, .png, .jpeg" 
          ref={InputFile}
          className="d-none" />

I am sending this blob to my backend which sends it to twilio with Content-Type: "image/png" <-- is this where I am wrong? How can I upload a file from a file input in frontend, and retain the ability to send an image with Content-Type: 'image/png'

Twilio is giving me an error Invalid Content-Type: The retrieved media has an incorrect Content-Type.

   const createMediaMMSResource = async (req, res) => {
            try {
            const { subActServiceSid, subActAuthToken, convoServiceSid} = req.user
            let mediaUrl
            let serviceSid
            console.log("req.body.uploadMMS.fileData", req.body.uploadMMS.fileData)
            
                await axios({
                    
                   url:`https://mcs.us1.twilio.com/v1/Services/${convoServiceSid}/Media`,
                    method:"POST",
                    data: req.body.uploadMMS.fileData,
                    headers: {
                        'Content-Type': 'image/png',
                    },
                    auth: { username: subActServiceSid, password: subActAuthToken },
                    withCredentials: true
                    }).then(res => console.log(res))

           res.status(201).json({mediaObj})
           } catch(err) {
            console.log(err)
            }
        }

Here is the function that sends the data to the backend Node.js server

        export const attachMMS = (uploadMMS) => async (dispatch) => {
                console.log(uploadMMS)
                try {
                        dispatch({type: ATTACH_MMS_CREATE_REQUEST })
                        await axios({
                                url:"http://localhost:5000/mms",
                                method:"POST",
                                data: { uploadMMS },
                                withCredentials: true
                              }).then(res =>  dispatch({type: ATTACH_MMS_CREATE_SUCCESS, payload: res}))   


                } catch(error) {
                        console.log(error)
                        dispatch({type: ATTACH_MMS_CREATE_FAIL,
                                payload:
                                error.message && error.response.data.message 
                                ? error.response.data.message :
                                error.message
                                })
                }
        }

1

There are 1 answers

2
philnash On

I think the issue here is that you are sending an object URL to your back-end and not the contents of the file. Your viewFile variable is literally the string blob:http://localhost:3000/06fe4f1a-06fb-4baf-a18f-7698ffd6e227 which means nothing to the backend or to Twilio.

Instead you should send the actual content of the file to your backend. You can get the content from the File object by calling the arrayBuffer() function.

    const manualMMSUpload = (e) => {
        e.preventDefault();
        if(e.target.files[0].name) {
            setUserMMS(e.target.files[0].name)
            const viewFile = e.target.files[0].arrayBuffer();
            handleInputChange({value: viewFile, name: "fileData"});
        }
      }

You will need to ensure you are sending the binary content of the file to your back-end correctly too, but you haven't shared the code for that.