FeedHive / twitter-api-client

A user-friendly Node.js / JavaScript client library for interacting with the Twitter API.
MIT License
948 stars 84 forks source link

401 On twitter.media.mediaUpload() #55

Closed vsnthdev closed 3 years ago

vsnthdev commented 3 years ago

Describe the bug
Below are the authentication requirements by Twitter for twitter.tweets.statusesUpdate() and twitter.media.mediaUpload() endpoints respectively 👇

Screenshot 2021-02-04 at 8 01 57 PM

and

Screenshot 2021-02-04 at 8 01 14 PM

As they require same level of authentication if twitter.tweets.statusesUpdate() works then twitter.media.mediaUpload() should also work. Where twitter.tweets.statusesUpdate() works as expected, twitter.media.mediaUpload() responds with a 401. Here's the code I've used 👇

const res = await twitter.media.mediaUpload({
    media: await fs.readFile(image.path)
})

console.log('res ', res)

And here's the response I get 👇

{
    statusCode: 401,
    data: '{"errors":[{"code":32,"message":"Could not authenticate you."}]}'
}

To reproduce
Steps to reproduce the behavior:

  1. Create a new Node.js project and add twitter-api-client as dependency.
  2. Write the following code 👇 in a file named index.js
    
    const fs = require('fs/promises')

const res = await twitter.media.mediaUpload({ media: await fs.readFile('./image.png') })

console.log('res ', res)


3. Add a dummy image in the same folder as `index.js`
4. Run it!

**Expected behavior**  
I see the newly uploaded image in Twitter Media Studio.

**Package Manager:**  
To install the Twitter API Client, I used **Yarn v1.22.10**

**Additional context**  
**Node.js:** v15.4.0
**Module System:** Native ESM
**Operating System:** macOS Big Sur 11.1 (20C69)
SimonHoiberg commented 3 years ago

Hi @vasanthdeveloper :wave: Thanks for creating this issue.

The mediaUpload endpoint expects the media to be base64 encoded. So - without having tried your reproduction example yet - could you first try to do the following:

const fs = require('fs/promises')

const res = await twitter.media.mediaUpload({
    media: await fs.readFile('./image.png', { encoding: 'base64' }) // <- add base64 here
})

console.log('res ', res)

I have a feeling that will work. Thank you.

vsnthdev commented 3 years ago

@SimonHoiberg Yup! that works 🥳 you're a genius! 🙌

vsnthdev commented 3 years ago

@SimonHoiberg It would be great if you make an example of chunked upload since that's tricky 🙂

slorber commented 3 years ago

Couldn't make chunked upload work due to auth failures => https://github.com/FeedHive/twitter-api-client/issues/63