Skip to content

Commit

Permalink
Improve token semantics and clean up gateway feature gates (#3052)
Browse files Browse the repository at this point in the history
  • Loading branch information
mkrasnitski authored Nov 22, 2024
1 parent 1a0a809 commit 2369544
Show file tree
Hide file tree
Showing 39 changed files with 434 additions and 378 deletions.
7 changes: 3 additions & 4 deletions examples/e01_basic_ping_bot/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use std::env;

use serenity::async_trait;
use serenity::model::channel::Message;
use serenity::model::gateway::Ready;
Expand Down Expand Up @@ -37,7 +35,8 @@ impl EventHandler for Handler {
#[tokio::main]
async fn main() {
// Configure the client with your Discord bot token in the environment.
let token = env::var("DISCORD_TOKEN").expect("Expected a token in the environment");
let token =
Token::from_env("DISCORD_TOKEN").expect("Expected a valid token in the environment");
// Set gateway intents, which decides what events the bot will be notified about
let intents = GatewayIntents::GUILD_MESSAGES
| GatewayIntents::DIRECT_MESSAGES
Expand All @@ -46,7 +45,7 @@ async fn main() {
// Create a new instance of the Client, logging in as a bot. This will automatically prepend
// your bot token with "Bot ", which is a requirement by Discord for bot users.
let mut client =
Client::builder(&token, intents).event_handler(Handler).await.expect("Err creating client");
Client::builder(token, intents).event_handler(Handler).await.expect("Err creating client");

// Finally, start a single shard, and start listening to events.
//
Expand Down
7 changes: 3 additions & 4 deletions examples/e02_transparent_guild_sharding/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use std::env;

use serenity::async_trait;
use serenity::model::channel::Message;
use serenity::model::gateway::Ready;
Expand Down Expand Up @@ -42,12 +40,13 @@ impl EventHandler for Handler {
#[tokio::main]
async fn main() {
// Configure the client with your Discord bot token in the environment.
let token = env::var("DISCORD_TOKEN").expect("Expected a token in the environment");
let token =
Token::from_env("DISCORD_TOKEN").expect("Expected a valid token in the environment");
let intents = GatewayIntents::GUILD_MESSAGES
| GatewayIntents::DIRECT_MESSAGES
| GatewayIntents::MESSAGE_CONTENT;
let mut client =
Client::builder(&token, intents).event_handler(Handler).await.expect("Err creating client");
Client::builder(token, intents).event_handler(Handler).await.expect("Err creating client");

// The total number of shards to use. The "current shard number" of a shard - that is, the
// shard it is assigned to - is indexed at 0, while the total shard count is indexed at 1.
Expand Down
7 changes: 3 additions & 4 deletions examples/e03_struct_utilities/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use std::env;

use serenity::async_trait;
use serenity::builder::CreateMessage;
use serenity::model::channel::Message;
Expand Down Expand Up @@ -35,12 +33,13 @@ impl EventHandler for Handler {
#[tokio::main]
async fn main() {
// Configure the client with your Discord bot token in the environment.
let token = env::var("DISCORD_TOKEN").expect("Expected a token in the environment");
let token =
Token::from_env("DISCORD_TOKEN").expect("Expected a valid token in the environment");
let intents = GatewayIntents::GUILD_MESSAGES
| GatewayIntents::DIRECT_MESSAGES
| GatewayIntents::MESSAGE_CONTENT;
let mut client =
Client::builder(&token, intents).event_handler(Handler).await.expect("Err creating client");
Client::builder(token, intents).event_handler(Handler).await.expect("Err creating client");

if let Err(why) = client.start().await {
println!("Client error: {why:?}");
Expand Down
7 changes: 3 additions & 4 deletions examples/e04_message_builder/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use std::env;

use serenity::async_trait;
use serenity::model::channel::Message;
use serenity::model::gateway::Ready;
Expand Down Expand Up @@ -46,12 +44,13 @@ impl EventHandler for Handler {
#[tokio::main]
async fn main() {
// Configure the client with your Discord bot token in the environment.
let token = env::var("DISCORD_TOKEN").expect("Expected a token in the environment");
let token =
Token::from_env("DISCORD_TOKEN").expect("Expected a valid token in the environment");
let intents = GatewayIntents::GUILD_MESSAGES
| GatewayIntents::DIRECT_MESSAGES
| GatewayIntents::MESSAGE_CONTENT;
let mut client =
Client::builder(&token, intents).event_handler(Handler).await.expect("Err creating client");
Client::builder(token, intents).event_handler(Handler).await.expect("Err creating client");

if let Err(why) = client.start().await {
println!("Client error: {why:?}");
Expand Down
5 changes: 3 additions & 2 deletions examples/e05_sample_bot_structure/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,11 @@ impl EventHandler for Handler {
#[tokio::main]
async fn main() {
// Configure the client with your Discord bot token in the environment.
let token = env::var("DISCORD_TOKEN").expect("Expected a token in the environment");
let token =
Token::from_env("DISCORD_TOKEN").expect("Expected a valid token in the environment");

// Build our client.
let mut client = Client::builder(&token, GatewayIntents::empty())
let mut client = Client::builder(token, GatewayIntents::empty())
.event_handler(Handler)
.await
.expect("Error creating client");
Expand Down
7 changes: 3 additions & 4 deletions examples/e06_env_logging/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use std::env;

use serenity::async_trait;
use serenity::model::event::ResumedEvent;
use serenity::model::gateway::Ready;
Expand Down Expand Up @@ -42,14 +40,15 @@ async fn main() {
tracing_subscriber::fmt::init();

// Configure the client with your Discord bot token in the environment.
let token = env::var("DISCORD_TOKEN").expect("Expected a token in the environment");
let token =
Token::from_env("DISCORD_TOKEN").expect("Expected a valid token in the environment");

let intents = GatewayIntents::GUILD_MESSAGES
| GatewayIntents::DIRECT_MESSAGES
| GatewayIntents::MESSAGE_CONTENT;

let mut client =
Client::builder(&token, intents).event_handler(Handler).await.expect("Err creating client");
Client::builder(token, intents).event_handler(Handler).await.expect("Err creating client");

if let Err(why) = client.start().await {
error!("Client error: {:?}", why);
Expand Down
6 changes: 3 additions & 3 deletions examples/e07_shard_manager/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
//!
//! Note that it may take a minute or more for a latency to be recorded or to update, depending on
//! how often Discord tells the client to send a heartbeat.
use std::env;
use std::time::Duration;

use serenity::async_trait;
Expand All @@ -44,13 +43,14 @@ impl EventHandler for Handler {
#[tokio::main]
async fn main() {
// Configure the client with your Discord bot token in the environment.
let token = env::var("DISCORD_TOKEN").expect("Expected a token in the environment");
let token =
Token::from_env("DISCORD_TOKEN").expect("Expected a valid token in the environment");

let intents = GatewayIntents::GUILD_MESSAGES
| GatewayIntents::DIRECT_MESSAGES
| GatewayIntents::MESSAGE_CONTENT;
let mut client =
Client::builder(&token, intents).event_handler(Handler).await.expect("Err creating client");
Client::builder(token, intents).event_handler(Handler).await.expect("Err creating client");

// Here we clone a lock to the Shard Manager, and then move it into a new thread. The thread
// will unlock the manager and print shards' status on a loop.
Expand Down
7 changes: 3 additions & 4 deletions examples/e08_create_message_builder/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use std::env;

use serenity::async_trait;
use serenity::builder::{CreateAttachment, CreateEmbed, CreateEmbedFooter, CreateMessage};
use serenity::model::channel::Message;
Expand Down Expand Up @@ -51,12 +49,13 @@ impl EventHandler for Handler {
#[tokio::main]
async fn main() {
// Configure the client with your Discord bot token in the environment.
let token = env::var("DISCORD_TOKEN").expect("Expected a token in the environment");
let token =
Token::from_env("DISCORD_TOKEN").expect("Expected a valid token in the environment");
let intents = GatewayIntents::GUILD_MESSAGES
| GatewayIntents::DIRECT_MESSAGES
| GatewayIntents::MESSAGE_CONTENT;
let mut client =
Client::builder(&token, intents).event_handler(Handler).await.expect("Err creating client");
Client::builder(token, intents).event_handler(Handler).await.expect("Err creating client");

if let Err(why) = client.start().await {
println!("Client error: {why:?}");
Expand Down
6 changes: 3 additions & 3 deletions examples/e09_collectors/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
//! This example will showcase the beauty of collectors. They allow to await messages or reactions
//! from a user in the middle of a control flow, one being a command.
use std::collections::HashSet;
use std::env;
use std::time::Duration;

use serenity::async_trait;
Expand Down Expand Up @@ -136,15 +135,16 @@ impl EventHandler for Handler {
#[tokio::main]
async fn main() {
// Configure the client with your Discord bot token in the environment.
let token = env::var("DISCORD_TOKEN").expect("Expected a token in the environment");
let token =
Token::from_env("DISCORD_TOKEN").expect("Expected a valid token in the environment");

let intents = GatewayIntents::GUILD_MESSAGES
| GatewayIntents::DIRECT_MESSAGES
| GatewayIntents::MESSAGE_CONTENT
| GatewayIntents::GUILD_MESSAGE_REACTIONS;

let mut client =
Client::builder(&token, intents).event_handler(Handler).await.expect("Err creating client");
Client::builder(token, intents).event_handler(Handler).await.expect("Err creating client");

if let Err(why) = client.start().await {
println!("Client error: {why:?}");
Expand Down
7 changes: 3 additions & 4 deletions examples/e10_gateway_intents/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use std::env;

use serenity::async_trait;
use serenity::model::channel::Message;
use serenity::model::gateway::{Presence, Ready};
Expand Down Expand Up @@ -33,13 +31,14 @@ impl EventHandler for Handler {
#[tokio::main]
async fn main() {
// Configure the client with your Discord bot token in the environment.
let token = env::var("DISCORD_TOKEN").expect("Expected a token in the environment");
let token =
Token::from_env("DISCORD_TOKEN").expect("Expected a valid token in the environment");

// Intents are a bitflag, bitwise operations can be used to dictate which intents to use
let intents =
GatewayIntents::GUILDS | GatewayIntents::GUILD_MESSAGES | GatewayIntents::MESSAGE_CONTENT;
// Build our client.
let mut client = Client::builder(&token, intents)
let mut client = Client::builder(token, intents)
.event_handler(Handler)
.await
.expect("Error creating client");
Expand Down
6 changes: 3 additions & 3 deletions examples/e11_global_data/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
//! In this example, you will be shown how to share data between events.
use std::borrow::Cow;
use std::env;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc;

Expand Down Expand Up @@ -61,7 +60,8 @@ impl EventHandler for Handler {

#[tokio::main]
async fn main() {
let token = env::var("DISCORD_TOKEN").expect("Expected a token in the environment");
let token =
Token::from_env("DISCORD_TOKEN").expect("Expected a valid token in the environment");

// We setup the initial value for our user data, which we will use throughout the rest of our
// program.
Expand All @@ -72,7 +72,7 @@ async fn main() {
let intents = GatewayIntents::GUILD_MESSAGES
| GatewayIntents::DIRECT_MESSAGES
| GatewayIntents::MESSAGE_CONTENT;
let mut client = Client::builder(&token, intents)
let mut client = Client::builder(token, intents)
// Specifying the data type as a type argument here is optional, but if done, you can
// guarantee that Context::data will not panic if the same type is given, as providing the
// incorrect type will lead to a compiler error, rather than a runtime panic.
Expand Down
6 changes: 3 additions & 3 deletions examples/e12_parallel_loops/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use std::env;
use std::sync::atomic::{AtomicBool, Ordering};
use std::time::Duration;

Expand Down Expand Up @@ -100,13 +99,14 @@ fn set_activity_to_current_time(ctx: &Context) {

#[tokio::main]
async fn main() {
let token = env::var("DISCORD_TOKEN").expect("Expected a token in the environment");
let token =
Token::from_env("DISCORD_TOKEN").expect("Expected a valid token in the environment");

let intents = GatewayIntents::GUILD_MESSAGES
| GatewayIntents::DIRECT_MESSAGES
| GatewayIntents::GUILDS
| GatewayIntents::MESSAGE_CONTENT;
let mut client = Client::builder(&token, intents)
let mut client = Client::builder(token, intents)
.event_handler(Handler {
is_loop_running: AtomicBool::new(false),
})
Expand Down
5 changes: 3 additions & 2 deletions examples/e13_sqlite_database/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ impl EventHandler for Bot {
#[tokio::main]
async fn main() {
// Configure the client with your Discord bot token in the environment.
let token = std::env::var("DISCORD_TOKEN").expect("Expected a token in the environment");
let token =
Token::from_env("DISCORD_TOKEN").expect("Expected a valid token in the environment");

// Initiate a connection to the database file, creating the file if required.
let database = sqlx::sqlite::SqlitePoolOptions::new()
Expand All @@ -96,6 +97,6 @@ async fn main() {
| GatewayIntents::DIRECT_MESSAGES
| GatewayIntents::MESSAGE_CONTENT;
let mut client =
Client::builder(&token, intents).event_handler(bot).await.expect("Err creating client");
Client::builder(token, intents).event_handler(bot).await.expect("Err creating client");
client.start().await.unwrap();
}
6 changes: 3 additions & 3 deletions examples/e14_message_components/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use std::borrow::Cow;
use std::env;
use std::time::Duration;

use dotenv::dotenv;
Expand Down Expand Up @@ -140,13 +139,14 @@ impl EventHandler for Handler {
async fn main() {
dotenv().ok();
// Configure the client with your Discord bot token in the environment.
let token = env::var("DISCORD_TOKEN").expect("Expected a token in the environment");
let token =
Token::from_env("DISCORD_TOKEN").expect("Expected a valid token in the environment");

// Build our client.
let intents = GatewayIntents::GUILD_MESSAGES
| GatewayIntents::DIRECT_MESSAGES
| GatewayIntents::MESSAGE_CONTENT;
let mut client = Client::builder(&token, intents)
let mut client = Client::builder(token, intents)
.event_handler(Handler)
.await
.expect("Error creating client");
Expand Down
2 changes: 1 addition & 1 deletion examples/e15_webhook/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use serenity::model::webhook::Webhook;
#[tokio::main]
async fn main() {
// You don't need a token when you are only dealing with webhooks.
let http = Http::new("");
let http = Http::without_token();
let webhook = Webhook::from_url(&http, "https://discord.com/api/webhooks/133742013374206969/hello-there-oPNtRN5UY5DVmBe7m1N0HE-replace-me-Dw9LRkgq3zI7LoW3Rb-k-q")
.await
.expect("Replace the webhook with your own");
Expand Down
5 changes: 3 additions & 2 deletions examples/testing/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,8 @@ async fn main() -> Result<(), serenity::Error> {
}

env_logger::init();
let token = std::env::var("DISCORD_TOKEN").expect("Expected a token in the environment");
let token =
Token::from_env("DISCORD_TOKEN").expect("Expected a valid token in the environment");
let intents = GatewayIntents::non_privileged() | GatewayIntents::MESSAGE_CONTENT;
Client::builder(&token, intents).event_handler(Handler).await?.start().await
Client::builder(token, intents).event_handler(Handler).await?.start().await
}
13 changes: 13 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use crate::gateway::GatewayError;
use crate::http::HttpError;
use crate::internal::prelude::*;
use crate::model::ModelError;
use crate::secrets::TokenError;

/// The common result type between most library functions.
///
Expand Down Expand Up @@ -46,6 +47,10 @@ pub enum Error {
/// An error from the `tungstenite` crate.
#[cfg(feature = "gateway")]
Tungstenite(Box<TungsteniteError>),
/// An error from the [`secrets`] module.
///
/// [`secrets`]: crate::secrets
Token(TokenError),
}

#[cfg(feature = "gateway")]
Expand Down Expand Up @@ -87,6 +92,12 @@ impl From<HttpError> for Error {
}
}

impl From<TokenError> for Error {
fn from(e: TokenError) -> Error {
Error::Token(e)
}
}

#[cfg(feature = "http")]
impl From<InvalidHeaderValue> for Error {
fn from(e: InvalidHeaderValue) -> Error {
Expand All @@ -113,6 +124,7 @@ impl fmt::Display for Error {
Self::Http(inner) => fmt::Display::fmt(&inner, f),
#[cfg(feature = "gateway")]
Self::Tungstenite(inner) => fmt::Display::fmt(&inner, f),
Self::Token(inner) => fmt::Display::fmt(&inner, f),
}
}
}
Expand All @@ -130,6 +142,7 @@ impl StdError for Error {
Self::Http(inner) => Some(inner),
#[cfg(feature = "gateway")]
Self::Tungstenite(inner) => Some(inner),
Self::Token(inner) => Some(inner),
}
}
}
Loading

0 comments on commit 2369544

Please sign in to comment.