Skip to content

Commit c5883f2

Browse files
committed
add more readmes and fix example
1 parent 00bdd48 commit c5883f2

File tree

9 files changed

+102
-30
lines changed

9 files changed

+102
-30
lines changed

CONTRIBUTING.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,20 @@
1+
### Fetching the git submodules
2+
3+
To get started with using this repository, ensure you have initialized and updated the submodules in order to retrieve their contents.
4+
5+
```sh
6+
git submodule update --init --recursive
7+
```
8+
9+
alternatively, you can also run
10+
11+
```sh
12+
git submodule init
13+
git submodule update
14+
```
15+
16+
### Maintaining
17+
118
#### Updating twitch_oauth2
219

320
To update the `twitch_oauth2` submodule, run the appropriate

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ See [documentation](https://docs.rs/twitch_api) for more info.
1212
You can see current unpublished docs for the main branch here: [![local-docs]](https://twitch-rs.github.io/twitch_api/twitch_api)
1313

1414
See [examples](./examples) for examples. If you want to run them locally,
15-
make sure you fetch the git submodules first.
15+
make sure you [get the git submodules](./CONTRIBUTING.md#fetching-the-git-submodules) first.
1616

1717
[local-docs]: https://img.shields.io/github/actions/workflow/status/twitch-rs/twitch_api/gh-pages.yml?label=dev%20docs&style=flat-square&event=push
1818

examples/README.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Examples
2+
3+
## Getting a token
4+
5+
To run the examples, you will need to have a Twitch OAuth token. You can get one by following the [Twitch OAuth guide](https://dev.twitch.tv/docs/authentication/getting-tokens-oauth).
6+
7+
There are sites available that can help you generate these tokens, or you can use the official [Twitch CLI](https://github.com/twitchdev/twitch-cli), `twitch_oauth2::UserToken::builder()` or `twitch_oauth2::tokens::ImplicitUserTokenBuilder`
8+
9+
## Running the examples
10+
11+
To run an example, ensure you've gotten the [submodules](../CONTRIBUTING.md#fetching-the-git-submodules) and have a [token](#getting-a-token) available.
12+
13+
```sh
14+
git clone https://github.com/twitch-rs/twitch_api.git --recurse-submodules
15+
cd twitch_api
16+
# if you didn't get the submodules, run
17+
# git submodule update --init --recursive
18+
cargo run --example <example_name> -- <token>
19+
```
20+
21+
Some examples are their own crates/workspace members, you can run these with
22+
23+
```sh
24+
cargo run -p <example> -- <args>
25+
```
26+
27+
## .env
28+
29+
Instead of passing a token to every example, you can also create a `.env` file in the root of the repository with the following contents
30+
31+
```txt
32+
# .env
33+
TWITCH_TOKEN=mytoken
34+
CLIENT_ID=myclientid
35+
CLIENT_SECRET=myclientid
36+
```

examples/eventsub_websocket/README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# EventSub Websocket Example
2+
3+
This example shows how to use the EventSub websocket to listen to events.
4+
5+
Ensure you've [gotten the git submodules](../../CONTRIBUTING.md#fetching-the-git-submodules) to [run this example](../README.md#running-the-examples)
6+
7+
```sh
8+
git clone https://github.com/twitch-rs/twitch_api.git --recurse-submodules
9+
cd twitch_api
10+
# if you didn't get the submodules, run
11+
# git submodule update --init --recursive
12+
cargo run -p eventsub_websocket -- --access-token <token>
13+
```

examples/eventsub_websocket/src/main.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,13 @@ pub mod websocket;
55

66
use clap::Parser;
77
pub use opts::Secret;
8-
use twitch_oauth2::UserToken;
98

109
use std::sync::Arc;
1110

1211
use opts::Opts;
1312

1413
use eyre::Context;
1514

16-
use tokio::sync::RwLock;
1715
use twitch_api::{client::ClientDefault, HelixClient};
1816

1917
#[tokio::main]
@@ -52,7 +50,8 @@ pub async fn run(opts: Arc<Opts>) -> eyre::Result<()> {
5250
);
5351

5452
// Get the access token from the cli, dotenv or an oauth service
55-
let token = util::get_access_token(client.get_client(), &opts).await?;
53+
let token: twitch_oauth2::UserToken =
54+
util::get_access_token(client.get_client(), &opts).await?;
5655

5756
// Get the user id of the channel we want to listen to
5857
let user_id = if let Some(ref id) = opts.channel_id {

examples/eventsub_websocket/src/opts.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@ use clap::{builder::ArgPredicate, ArgGroup, Parser};
33
#[derive(Parser, Debug, Clone)]
44
#[clap(about, version,
55
group = ArgGroup::new("token").multiple(false).required(false),
6-
group = ArgGroup::new("service").multiple(true).requires("oauth2-service-url"),
6+
group = ArgGroup::new("service").multiple(true).requires("oauth2_service_url"),
77
group = ArgGroup::new("channel").multiple(true).required(false),
88
)]
99
pub struct Opts {
1010
/// OAuth2 Access token
11-
#[clap(long, env, hide_env = true, group = "token", value_parser = is_token, required_unless_present = "service"
11+
#[clap(long, env, hide_env = true, group = "token", value_parser = to_token, required_unless_present = "service"
1212
)]
1313
pub access_token: Option<Secret>,
1414
/// Name of channel to monitor. If left out, defaults to owner of access token.
@@ -20,7 +20,7 @@ pub struct Opts {
2020
/// URL to service that provides OAuth2 token. Called on start and whenever the token needs to be refreshed.
2121
///
2222
/// This application does not do any refreshing of tokens.
23-
#[clap(long, env, hide_env = true, group = "token",
23+
#[clap(long, env, hide_env = true, group = "service",
2424
value_parser = url::Url::parse, required_unless_present = "token"
2525
)]
2626
pub oauth2_service_url: Option<url::Url>,
@@ -47,14 +47,14 @@ pub struct Opts {
4747
pub oauth2_service_refresh: Option<u64>,
4848
}
4949

50-
pub fn is_token(s: &str) -> eyre::Result<()> {
50+
pub fn to_token(s: &str) -> eyre::Result<Secret> {
5151
if s.starts_with("oauth:") {
5252
eyre::bail!("token should not have `oauth:` as a prefix")
5353
}
5454
if s.len() != 30 {
5555
eyre::bail!("token needs to be 30 characters long")
5656
}
57-
Ok(())
57+
Ok(Secret(s.to_owned()))
5858
}
5959

6060
#[derive(Clone)]

examples/tower_client/src/main.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ fn main() {
2121
}
2222

2323
#[tokio::main]
24+
/// Run the application
2425
async fn run() -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
2526
let _ = dotenvy::dotenv();
2627
tracing_subscriber::fmt()
@@ -53,11 +54,12 @@ async fn run() -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>>
5354
.service(
5455
hyper::Client::builder().build::<_, hyper::Body>(hyper_tls::HttpsConnector::new()),
5556
);
57+
5658
tracing::info!("Creating client");
5759
let client: HelixClient<Box<dyn twitch_api::HttpClient<Error = _>>> =
5860
HelixClient::with_client(Box::new(TowerService::new(tower_client)));
59-
tracing::info!("Getting token");
6061

62+
tracing::info!("Getting token");
6163
let token = UserToken::from_existing(
6264
&client,
6365
std::env::var("TWITCH_TOKEN")

examples/twitch_oauth2-integration/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ pub async fn get_auth_token_request(
77
let client_secret = ClientSecret::from("aaaa");
88

99
let token =
10+
// here we can use the TwitchClient as a client for twitch_oauth2
1011
AppAccessToken::get_app_access_token(client, client_id, client_secret, Scope::all())
1112
.await
1213
.unwrap();

src/lib.rs

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -17,31 +17,35 @@
1717
//! Get information about a channel with the [`Get Channel Information`](crate::helix::channels::get_channel_information) helix endpoint.
1818
//!
1919
//! ```rust,no_run
20+
//! use twitch_api::twitch_oauth2::{
21+
//! tokens::errors::AppAccessTokenError, AppAccessToken, TwitchToken,
22+
//! };
2023
//! use twitch_api::{helix::channels::GetChannelInformationRequest, TwitchClient};
21-
//! use twitch_api::twitch_oauth2::{tokens::errors::AppAccessTokenError, AppAccessToken, Scope, TwitchToken};
22-
//! # pub mod reqwest {pub type Client = twitch_api::client::DummyHttpClient;}
23-
//!
24-
//! # #[tokio::main]
25-
//! # async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
26-
//! # let client_id = twitch_oauth2::ClientId::from("validclientid");
27-
//! # let client_secret = twitch_oauth2::ClientSecret::from("validclientsecret");
28-
//!
29-
//! let client: TwitchClient<reqwest::Client> = TwitchClient::default();
30-
//! let token =
31-
//! AppAccessToken::get_app_access_token(&client, client_id, client_secret, Scope::all())
32-
//! .await?;
33-
//! let ids: &[&twitch_types::UserIdRef] = &["27620241".into()];
34-
//! let req = GetChannelInformationRequest::broadcaster_ids(ids);
35-
//! println!(
36-
//! "{:?}",
37-
//! &client.helix.req_get(req, &token).await?.data[0].title
38-
//! );
39-
//! # Ok(())
24+
//! # pub mod reqwest {
25+
//! # pub type Client = twitch_api::client::DummyHttpClient;
4026
//! # }
27+
//!
28+
//! #[tokio::main]
29+
//! async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
30+
//! let client: TwitchClient<reqwest::Client> = TwitchClient::default();
31+
//! let token = AppAccessToken::get_app_access_token(
32+
//! &client,
33+
//! "validclientid".into(),
34+
//! "validclientsecret".into(),
35+
//! vec![/* scopes */],
36+
//! )
37+
//! .await?;
38+
//! let ids: &[&twitch_types::UserIdRef] = &["27620241".into()];
39+
//! let req = GetChannelInformationRequest::broadcaster_ids(ids);
40+
//! println!(
41+
//! "{:?}",
42+
//! &client.helix.req_get(req, &token).await?.data[0].title
43+
//! );
44+
//! Ok(())
45+
//! }
4146
//! ```
4247
//!
4348
//! There is also convenience functions, like accessing channel information with a specified login name
44-
//!
4549
//! ```rust,no_run
4650
//! # use twitch_api::{TwitchClient, helix::channels::GetChannelInformationRequest};
4751
//! # use twitch_api::twitch_oauth2::{AppAccessToken, Scope, TwitchToken, tokens::errors::AppAccessTokenError};

0 commit comments

Comments
 (0)