jpopesculian / twitter-v2-rs

Rust bindings for Twitter API v2
https://docs.rs/twitter-v2/latest
102 stars 28 forks source link

Example for Oauth2Token confusing #4

Closed fekie closed 2 years ago

fekie commented 2 years ago

In the example on the readme it contains the line

let auth: Oauth2Token = serde_json::from_str(&stored_oauth2_token)?;

The variable for the json string was not in the example, so I looked at the Oauth2Token struct. However, I could not find out how to find the expires and scopes part of the token on the Twitter developer portal.

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Oauth2Token {
    access_token: AccessToken,
    refresh_token: Option<RefreshToken>,
    #[serde(with = "time::serde::rfc3339")]
    expires: OffsetDateTime,
    scopes: Vec<Scope>,
}

On the twitter developer portal I can only figure out how to create the access token and refresh token. I am not too familiar with the twitter api but I feel like it may be possible to put expires and scopes inside of an Option. The Oauth2Token struct should probably have the documentation for where you can find expires and scopes as well as a new() function for creating the token without deserializing from json.

I'm free to work on this issue this week, depending on which route you choose (documentation for finding expires and scopes or stuffing them in Options)

jpopesculian commented 2 years ago

Hi @Chloe-Woahie!

Im currently sitting on a train, so I apologize in advance for being brief, but usually the Oauth2 token is created programmatically via the authorization url and callback mechanism, where the serde stuff is just used for storage in a database or similar. I dont think i fully understand the use case of manually filling out the access_token. Can you maybe describe what the workflow is? Id rather not add an Option to those fields if its unnecessary. Maybe you'd be more inclined to use just the BearerToken struct, where you can use the access_token directly? I definitely need to add more documentation and authentication is probably a good place to start....

Best, Julian

fekie commented 2 years ago

I tried using the BearerToken first, but the endpoint I was trying to use (send tweet), did not support only having the BearerToken. This is the error:

Error: Api(ApiError { title: "Unsupported Authentication", kind: "https://api.twitter.com/2/problems/unsupported-authentication", status: 403, detail: "Authenticating with OAuth 2.0 Application-Only is forbidden for this endpoint.  Supported authentication types are [OAuth 1.0a User Context, OAuth 2.0 User Context].", errors: [] })
error: process didn't exit successfully: `target\debug\twitter-backend.exe` (exit code: 1)

I'm getting the Oauth2 clientid and secret from the twitter developer portal. I cannot find an option on the portal for it to give me a json dump containing the expiration and scopes.

image

The reason I suggested putting scopes and expiration in an option is because the typescript twitter-api-v2 library did not require them, which means there is probably some way to omit them (although I don't know if it complicates things).

jpopesculian commented 2 years ago

Hi @Chloe-Woahie, you have to use the Oauth2 client ID and secret to setup an Oauth2Client which can request the Oauth2Token. Checkout the example for more information https://github.com/jpopesculian/twitter-v2-rs/blob/master/examples/oauth2_callback.rs#L174. The twitter-api-v2 library combines these two into one Oauth2User object which automatically refreshes the token and authorizes the client. You can achieve the same affect by using RefreshableOauth2Token which combines an Oauth2Client and Oauth2Token to do the automatic refresh