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

400 On twitter.accountsAndUsers.accountUpdateProfileBanner() #33

Closed vsnthdev closed 4 years ago

vsnthdev commented 4 years ago

Describe the bug
As per the documentation of Twitter and twitter-api-client, here is the code I've written that should update an account's cover image πŸ‘‡

const { default: TwitterClient } = require('twitter-api-client')
const fs = require('fs')

const twitter = new TwitterClient({
    apiKey: '[API key]',
    apiSecret: '[API secret]',
    accessToken: '[access token]',
    accessTokenSecret: '[access token secret]'
})

const set = async () => {
    try {
        const data = await twitter.accountsAndUsers.accountUpdateProfileBanner({
            banner: fs.readFileSync('cover.jpg', { encoding: 'base64' })
        })

        console.log(data)
    } catch (e) {
        console.log(e)
    }
}

set()

This results in πŸ‘‡

{ statusCode: 400, data: '' }

and does not update the cover image of the authorized user. A quick note: The import is wrapped in a default, which requires the usage of this ☝️ ugly syntax. Tried on JavaScript CommonJS and JavaScript ECMAScript Modules πŸ™‚

To reproduce
Steps to reproduce the behavior:

  1. Copy the above code.
  2. Install credentials
  3. Have an image on the same directory named cover.jpg
  4. Run the script.

Expected behavior
An updated cover image with a response of statusCode of 200 or 201 with data set to an empty string.

Package Manager:
Yarn: v1.22.5 Node.js: v15.0.1

Additional context
According to the documentation, on Twitter, the field banner should be sent as a URL query parameter. But since a banner is usually a big file (relatively) it's a bad practice to send it through URL query parameters.

Hence Twitter has updated to use x-www-form-urlencoded (POST body) and that isn't updated in their docs. Thanks, @Silind for making this module and I am πŸ™‚ happy to give more info.

SimonHoiberg commented 4 years ago

Thanks a lot for creating this very detailed issue, @vasanthdeveloper. We will take a look at this asap!

vsnthdev commented 4 years ago

Thank you, I was actually in urgency as I had to open-source my project before the 8th of November as there's still a lot of work πŸ˜€

vsnthdev commented 4 years ago

Here's a working copy of the request in Postman πŸ‘‡ https://www.getpostman.com/collections/e460f5997d62ec0733fb

vsnthdev commented 4 years ago

I hope, I didn't expose my API keys πŸ˜‚

pbteja1998 commented 4 years ago

This is working for me in postman. But when tried to update it using this package, I am getting {statusCode: 431, data: ''}, not 400.

SimonHoiberg commented 4 years ago

Alright, this is very helpful. Thanks a lot. I'll be looking into this later today.

vsnthdev commented 4 years ago

Thank you πŸ™ if this works out, I'll be so happy πŸ˜ƒ as I will open-source the project I've worked on for weeks now.

SimonHoiberg commented 4 years ago

@vasanthdeveloper @pbteja1998 Fixed in version 1.1.1 :raised_hands: Thanks a lot for your help, guys!

SimonHoiberg commented 4 years ago

There's still an issue with a pending promise. Reopening this issue to investigate.

SimonHoiberg commented 4 years ago

This is now solved in 1.2.0. Also, I've changed to non-default export instead to resolve the problems with the require syntax.

vsnthdev commented 4 years ago

Even though the cover image is updated the Promise never resolves, thus blocking the execution flow when awaited.

In the below code πŸ‘‡ the console.log() never executes.

twitter.accountsAndUsers.accountUpdateProfileBanner({
    banner: fs.readFileSync('coverPage.png', { encoding: 'base64' })
}).then(() => {
    console.log('resolved!')
})