-
Notifications
You must be signed in to change notification settings - Fork 119
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Move examples from the Serenity repository
- Loading branch information
Showing
12 changed files
with
1,586 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
# Songbird examples | ||
|
||
These examples show more advanced use of Songbird, or how to include Songbird in bots built on other libraries, such as twilight. | ||
These examples show more advanced use of Songbird, or how to include Songbird in bots built on other libraries, such as twilight or serenity. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
[package] | ||
name = "voice" | ||
version = "0.1.0" | ||
authors = ["my name <[email protected]>"] | ||
edition = "2018" | ||
|
||
[dependencies] | ||
tracing = "0.1" | ||
tracing-subscriber = "0.2" | ||
tracing-futures = "0.2" | ||
|
||
[dependencies.songbird] | ||
path = "../../../" | ||
|
||
[dependencies.serenity] | ||
features = ["client", "standard_framework", "voice", "rustls_backend"] | ||
git = "https://github.com/serenity-rs/serenity" | ||
branch = "current" | ||
|
||
[dependencies.tokio] | ||
version = "0.2" | ||
features = ["macros"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,291 @@ | ||
//! Requires the "client", "standard_framework", and "voice" features be enabled in your | ||
//! Cargo.toml, like so: | ||
//! | ||
//! ```toml | ||
//! [dependencies.serenity] | ||
//! git = "https://github.com/serenity-rs/serenity.git" | ||
//! features = ["client", standard_framework", "voice"] | ||
//! ``` | ||
use std::env; | ||
|
||
// This trait adds the `register_songbird` and `register_songbird_with` methods | ||
// to the client builder below, making it easy to install this voice client. | ||
// The voice client can be retrieved in any command using `songbird::get(ctx).await`. | ||
use songbird::SerenityInit; | ||
|
||
// Import the `Context` to handle commands. | ||
use serenity::client::Context; | ||
|
||
use serenity::{ | ||
async_trait, | ||
client::{Client, EventHandler}, | ||
framework::{ | ||
StandardFramework, | ||
standard::{ | ||
Args, CommandResult, | ||
macros::{command, group}, | ||
}, | ||
}, | ||
model::{channel::Message, gateway::Ready}, | ||
Result as SerenityResult, | ||
}; | ||
|
||
struct Handler; | ||
|
||
#[async_trait] | ||
impl EventHandler for Handler { | ||
async fn ready(&self, _: Context, ready: Ready) { | ||
println!("{} is connected!", ready.user.name); | ||
} | ||
} | ||
|
||
#[group] | ||
#[commands(deafen, join, leave, mute, play, ping, undeafen, unmute)] | ||
struct General; | ||
|
||
#[tokio::main] | ||
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 framework = StandardFramework::new() | ||
.configure(|c| c | ||
.prefix("~")) | ||
.group(&GENERAL_GROUP); | ||
|
||
let mut client = Client::builder(&token) | ||
.event_handler(Handler) | ||
.framework(framework) | ||
.register_songbird() | ||
.await | ||
.expect("Err creating client"); | ||
|
||
let _ = client.start().await.map_err(|why| println!("Client ended: {:?}", why)); | ||
} | ||
|
||
#[command] | ||
#[only_in(guilds)] | ||
async fn deafen(ctx: &Context, msg: &Message) -> CommandResult { | ||
let guild = msg.guild(&ctx.cache).await.unwrap(); | ||
let guild_id = guild.id; | ||
|
||
let manager = songbird::get(ctx).await | ||
.expect("Songbird Voice client placed in at initialisation.").clone(); | ||
|
||
let handler_lock = match manager.get(guild_id) { | ||
Some(handler) => handler, | ||
None => { | ||
check_msg(msg.reply(ctx, "Not in a voice channel").await); | ||
|
||
return Ok(()); | ||
}, | ||
}; | ||
|
||
let mut handler = handler_lock.lock().await; | ||
|
||
if handler.is_deaf() { | ||
check_msg(msg.channel_id.say(&ctx.http, "Already deafened").await); | ||
} else { | ||
if let Err(e) = handler.deafen(true).await { | ||
check_msg(msg.channel_id.say(&ctx.http, format!("Failed: {:?}", e)).await); | ||
} | ||
|
||
check_msg(msg.channel_id.say(&ctx.http, "Deafened").await); | ||
} | ||
|
||
Ok(()) | ||
} | ||
|
||
#[command] | ||
#[only_in(guilds)] | ||
async fn join(ctx: &Context, msg: &Message) -> CommandResult { | ||
let guild = msg.guild(&ctx.cache).await.unwrap(); | ||
let guild_id = guild.id; | ||
|
||
let channel_id = guild | ||
.voice_states.get(&msg.author.id) | ||
.and_then(|voice_state| voice_state.channel_id); | ||
|
||
let connect_to = match channel_id { | ||
Some(channel) => channel, | ||
None => { | ||
check_msg(msg.reply(ctx, "Not in a voice channel").await); | ||
|
||
return Ok(()); | ||
} | ||
}; | ||
|
||
let manager = songbird::get(ctx).await | ||
.expect("Songbird Voice client placed in at initialisation.").clone(); | ||
|
||
let _handler = manager.join(guild_id, connect_to).await; | ||
|
||
Ok(()) | ||
} | ||
|
||
#[command] | ||
#[only_in(guilds)] | ||
async fn leave(ctx: &Context, msg: &Message) -> CommandResult { | ||
let guild = msg.guild(&ctx.cache).await.unwrap(); | ||
let guild_id = guild.id; | ||
|
||
let manager = songbird::get(ctx).await | ||
.expect("Songbird Voice client placed in at initialisation.").clone(); | ||
let has_handler = manager.get(guild_id).is_some(); | ||
|
||
if has_handler { | ||
if let Err(e) = manager.remove(guild_id).await { | ||
check_msg(msg.channel_id.say(&ctx.http, format!("Failed: {:?}", e)).await); | ||
} | ||
|
||
check_msg(msg.channel_id.say(&ctx.http, "Left voice channel").await); | ||
} else { | ||
check_msg(msg.reply(ctx, "Not in a voice channel").await); | ||
} | ||
|
||
Ok(()) | ||
} | ||
|
||
#[command] | ||
#[only_in(guilds)] | ||
async fn mute(ctx: &Context, msg: &Message) -> CommandResult { | ||
let guild = msg.guild(&ctx.cache).await.unwrap(); | ||
let guild_id = guild.id; | ||
|
||
let manager = songbird::get(ctx).await | ||
.expect("Songbird Voice client placed in at initialisation.").clone(); | ||
|
||
let handler_lock = match manager.get(guild_id) { | ||
Some(handler) => handler, | ||
None => { | ||
check_msg(msg.reply(ctx, "Not in a voice channel").await); | ||
|
||
return Ok(()); | ||
}, | ||
}; | ||
|
||
let mut handler = handler_lock.lock().await; | ||
|
||
if handler.is_mute() { | ||
check_msg(msg.channel_id.say(&ctx.http, "Already muted").await); | ||
} else { | ||
if let Err(e) = handler.mute(true).await { | ||
check_msg(msg.channel_id.say(&ctx.http, format!("Failed: {:?}", e)).await); | ||
} | ||
|
||
check_msg(msg.channel_id.say(&ctx.http, "Now muted").await); | ||
} | ||
|
||
Ok(()) | ||
} | ||
|
||
#[command] | ||
async fn ping(context: &Context, msg: &Message) -> CommandResult { | ||
check_msg(msg.channel_id.say(&context.http, "Pong!").await); | ||
|
||
Ok(()) | ||
} | ||
|
||
#[command] | ||
#[only_in(guilds)] | ||
async fn play(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult { | ||
let url = match args.single::<String>() { | ||
Ok(url) => url, | ||
Err(_) => { | ||
check_msg(msg.channel_id.say(&ctx.http, "Must provide a URL to a video or audio").await); | ||
|
||
return Ok(()); | ||
}, | ||
}; | ||
|
||
if !url.starts_with("http") { | ||
check_msg(msg.channel_id.say(&ctx.http, "Must provide a valid URL").await); | ||
|
||
return Ok(()); | ||
} | ||
|
||
let guild = msg.guild(&ctx.cache).await.unwrap(); | ||
let guild_id = guild.id; | ||
|
||
let manager = songbird::get(ctx).await | ||
.expect("Songbird Voice client placed in at initialisation.").clone(); | ||
|
||
if let Some(handler_lock) = manager.get(guild_id) { | ||
let mut handler = handler_lock.lock().await; | ||
|
||
let source = match songbird::ytdl(&url).await { | ||
Ok(source) => source, | ||
Err(why) => { | ||
println!("Err starting source: {:?}", why); | ||
|
||
check_msg(msg.channel_id.say(&ctx.http, "Error sourcing ffmpeg").await); | ||
|
||
return Ok(()); | ||
}, | ||
}; | ||
|
||
handler.play_source(source); | ||
|
||
check_msg(msg.channel_id.say(&ctx.http, "Playing song").await); | ||
} else { | ||
check_msg(msg.channel_id.say(&ctx.http, "Not in a voice channel to play in").await); | ||
} | ||
|
||
Ok(()) | ||
} | ||
|
||
#[command] | ||
#[only_in(guilds)] | ||
async fn undeafen(ctx: &Context, msg: &Message) -> CommandResult { | ||
let guild = msg.guild(&ctx.cache).await.unwrap(); | ||
let guild_id = guild.id; | ||
|
||
let manager = songbird::get(ctx).await | ||
.expect("Songbird Voice client placed in at initialisation.").clone(); | ||
|
||
if let Some(handler_lock) = manager.get(guild_id) { | ||
let mut handler = handler_lock.lock().await; | ||
if let Err(e) = handler.deafen(false).await { | ||
check_msg(msg.channel_id.say(&ctx.http, format!("Failed: {:?}", e)).await); | ||
} | ||
|
||
check_msg(msg.channel_id.say(&ctx.http, "Undeafened").await); | ||
} else { | ||
check_msg(msg.channel_id.say(&ctx.http, "Not in a voice channel to undeafen in").await); | ||
} | ||
|
||
Ok(()) | ||
} | ||
|
||
#[command] | ||
#[only_in(guilds)] | ||
async fn unmute(ctx: &Context, msg: &Message) -> CommandResult { | ||
let guild = msg.guild(&ctx.cache).await.unwrap(); | ||
let guild_id = guild.id; | ||
|
||
let manager = songbird::get(ctx).await | ||
.expect("Songbird Voice client placed in at initialisation.").clone(); | ||
|
||
if let Some(handler_lock) = manager.get(guild_id) { | ||
let mut handler = handler_lock.lock().await; | ||
if let Err(e) = handler.mute(false).await { | ||
check_msg(msg.channel_id.say(&ctx.http, format!("Failed: {:?}", e)).await); | ||
} | ||
|
||
check_msg(msg.channel_id.say(&ctx.http, "Unmuted").await); | ||
} else { | ||
check_msg(msg.channel_id.say(&ctx.http, "Not in a voice channel to unmute in").await); | ||
} | ||
|
||
Ok(()) | ||
} | ||
|
||
/// Checks that a message successfully sent; if not, then logs why to stdout. | ||
fn check_msg(result: SerenityResult<Message>) { | ||
if let Err(why) = result { | ||
println!("Error sending message: {:?}", why); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
[package] | ||
name = "voice_events_queue" | ||
version = "0.1.0" | ||
authors = ["my name <[email protected]>"] | ||
edition = "2018" | ||
|
||
[dependencies] | ||
tracing = "0.1" | ||
tracing-subscriber = "0.2" | ||
tracing-futures = "0.2" | ||
|
||
[dependencies.songbird] | ||
path = "../../../" | ||
|
||
[dependencies.serenity] | ||
features = ["cache", "standard_framework", "voice", "rustls_backend"] | ||
git = "https://github.com/serenity-rs/serenity" | ||
branch = "current" | ||
|
||
[dependencies.tokio] | ||
version = "0.2" | ||
features = ["macros"] |
Oops, something went wrong.