FeedHive/twitter-api-client

400 On twitter.accountsAndUsers.accountUpdateProfileBanner()

vsnthdev opened this issue ยท 11 comments

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.

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

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 ๐Ÿ˜€

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

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

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

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

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.

@vasanthdeveloper @pbteja1998
Fixed in version 1.1.1 ๐Ÿ™Œ
Thanks a lot for your help, guys!

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

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.

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!')
})