aryat
aryat

Reputation: 93

Not able to send form data using axios in Nodejs?

I am trying to make POST request with axios but getting 400 bad request error message. I tried same request in POSTMAN but it worked correctly any idea what I am missing? Code:

const TWITTER_UPLOAD_MEDIA_BASE_URL = 'https://upload.twitter.com/1.1/media/upload.json';
 
const url = "https://ik.imagekit.io/XXXXXXXXXXXX/test-upload_XXXXXXXXXXX.png";
 
const { data } = await axios.get(url);
const form = new FormData();
form.append('media', data);
 
const token = {
    key: oauth_access_token,
    secret: oauth_access_token_secret
};
 
const oauth = OAuth({
    consumer: {
        key: process.env.TWITTER_CONSUMER_KEY,
        secret: process.env.TWITTER_CONSUMER_SECRET
    },
    signature_method: 'HMAC-SHA1',
    hash_function: (baseString, key) => crypto.createHmac('sha1', key).update(baseString).digest('base64')
});
 
const authHeader = oauth.toHeader(oauth.authorize({
    url: `${TWITTER_UPLOAD_MEDIA_BASE_URL}?media_category=tweet_image`,
    method: 'POST'
}, token));
 
const result = await axios.post(`${TWITTER_UPLOAD_MEDIA_BASE_URL}?media_category=tweet_image`, form, {
    headers: {
        Authorization: authHeader["Authorization"],
        'Content-type': "multipart/form-data",
        "Content-Transfer-Encoding": "base64"
    }
});

I also tried:

 
const url = "https://ik.imagekit.io/XXXXXXXXXXXX/test-upload_XXXXXXXXXXX.png";
 
const image = await axios.get(url, { responseType: 'arraybuffer' });
const raw = new Buffer.from(image.data).toString('base64');
const base64Image = "data:" + image.headers["content-type"] + ";base64," + raw;
 
const token = {
    key: oauth_access_token,
    secret: oauth_access_token_secret
};
 
const oauth = OAuth({
    consumer: {
        key: process.env.TWITTER_CONSUMER_KEY,
        secret: process.env.TWITTER_CONSUMER_SECRET
    },
    signature_method: 'HMAC-SHA1',
    hash_function: (baseString, key) => crypto.createHmac('sha1', key).update(baseString).digest('base64')
});
 
const authHeader = oauth.toHeader(oauth.authorize({
    url: `${TWITTER_UPLOAD_MEDIA_BASE_URL}?media_category=tweet_image`,
    method: 'POST'
}, token));
 
const result = await axios.post(`${TWITTER_UPLOAD_MEDIA_BASE_URL}?media_category=tweet_image`, {media_data: base64Image}, {
    headers: {
        Authorization: authHeader["Authorization"],
        'Content-type': "multipart/form-data",
        "Content-Transfer-Encoding": "base64"
    }
});

Bot snippets not working. Till line 27 (first code snippet) everything is correct. Issue is from line 28 with axios and form content POSTMAN screenshots of successful request: enter image description here

enter image description here

enter image description here

I think axios has got some serious issues:

  1. https://github.com/mzabriskie/axios/issues/789

  2. https://github.com/axios/axios/issues/1006

  3. https://developer.twitter.com/en/docs/twitter-api/v1/media/upload-media/api-reference/post-media-upload

  4. Twitter media upload guide: https://developer.twitter.com/en/docs/twitter-api/v1/media/upload-media/uploading-media/media-best-practices

Upvotes: 2

Views: 1967

Answers (1)

Omar Berrami
Omar Berrami

Reputation: 177

firstly download your image like:

const url = 'https://url-to-your-image'
const { data } = await axios.get(url, {
      responseType: 'stream',
})

after that you can append the image directly in formdata

const formData = new FormData()
formData.append('media', stream)

and finally upload

const result = await axios.post(`${TWITTER_UPLOAD_MEDIA_BASE_URL}? 
media_category=tweet_image`, formData, {
   headers: {
    Authorization: authHeader["Authorization"],
    'Content-type': "multipart/form-data",
    "Content-Transfer-Encoding": "base64"
   }
});

If you still get a problem let me know

Upvotes: 1

Related Questions