ttezel / twit

Twitter API Client for node (REST & Streaming API)
4.31k stars 570 forks source link

How to Get Access Token on User's behalf #563

Open ebitogu opened 3 years ago

ebitogu commented 3 years ago

Thanks for this library.

My Application is not an app only app. I need the user to consent to and sign in and allow my app to get an access token so I can publish tweets on behalf of the user.

It's not clear how to proceed on that using this library.

From the Twitter documentation, I was told I need to first of all call /oauth/request_token to get an oauth_token and then call oauth/authorize with that oauth_token for the user to authorize, save the returned access token somewhere and then make further api calls using that access token.

Please how can the above be achieved using this library.

Here is what I have tried but I ended up with this error:

Error: Twit config must include `access_token` when using user auth.
2021-09-21T02:14:38.530586+00:00 app[web.1]:     at /app/node_modules/twit/lib/twitter.js:511:13

Here is the code I tried

      let T = new Twit({
            consumer_key: oAuthConsumerKey,
            consumer_secret: oAuthConsumerSecret,
            callback: oAuthCallbackURL,
            app_only_auth: false
        });
        T.post('oauth/request_token', {}, (err, data, response) => {
            console.log(`Twitter Response=${response} err=${err} and data=${data}`);
        });

Thank you

unstabler commented 2 years ago

to call oauth/request_token properly, you should subclass Twit class.

/**
 * specialized class for /oauth/request_token
 * do not use to other endpoints!
 */
class TwitExRequestToken extends Twit {
  public _validateConfigOrThrow()
    // leave as blank to bypass config validation
  }

  public _doRestApiRequest(reqOpts, twitOptions, method, callback) {
    // remove unused fields from oauth v1 signature map and call original function
    delete reqOpts['oauth']['token'];
    delete reqOpts['oauth']['token_secret'];

    super._doRestApiRequest(reqOpts, twitOptions, method, callback);
  }
}

const twit = new TwitExRequestToken({
  consumer_key: process.env['TWITTER_API_KEY']!,
  consumer_secret: process.env['TWITTER_API_KEY_SECRET']!,
});

// authorization-related endpoints are not under /v1 or /2, so it requires full url as parameter
twit.post('https://api.twitter.com/oauth/request_token', {
  oauth_callback: 'http://localhost:3000/twitter_oauth_callback'
}, (err, data, response) => {
  console.log(data); // oauth_token=XXX...,oauth_callback_confirmed=true
});