add global commands

This commit is contained in:
2024-02-14 23:40:59 +01:00
parent 197129cf72
commit 4eee0adf40
3 changed files with 45 additions and 36 deletions

11
Cargo.lock generated
View File

@@ -414,6 +414,7 @@ dependencies = [
"twilight-http",
"twilight-model",
"twilight-standby",
"twilight-util",
]
[[package]]
@@ -2613,6 +2614,16 @@ dependencies = [
"twilight-model",
]
[[package]]
name = "twilight-util"
version = "0.15.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fe3149347d8222e042a55deba80cd32f93f14770bbb845b8e4cfbd70a5062c56"
dependencies = [
"twilight-model",
"twilight-validate",
]
[[package]]
name = "twilight-validate"
version = "0.15.3"

View File

@@ -19,4 +19,5 @@ twilight-http = "0.15"
twilight-model = "0.15"
twilight-standby = "0.15"
twilight-cache-inmemory = "0.15"
twilight-util = { version = "0.15", features=["builder"] }
dotenv = "0.15.0"

View File

@@ -8,15 +8,17 @@ use songbird::{
use std::{
env, error::Error, future::Future, num::NonZeroU64, ops::Sub, sync::Arc, time::Duration,
};
use tracing::{debug, info};
use tracing::debug;
use twilight_cache_inmemory::InMemoryCache;
use twilight_gateway::{
stream::{self, ShardEventStream},
Event, Intents, Shard,
};
use twilight_http::Client as HttpClient;
use twilight_model::channel::Message;
use twilight_model::application::command::CommandType;
use twilight_model::{channel::Message, id::Id};
use twilight_standby::Standby;
use twilight_util::builder::command::{CommandBuilder, StringBuilder};
type State = Arc<StateRef>;
@@ -47,30 +49,42 @@ async fn main() -> Result<(), Box<dyn Error + Send + Sync + 'static>> {
let (mut shards, state) = {
let token = env::var("DISCORD_TOKEN")?;
let app_id = env::var("DISCORD_APP_ID")?.parse()?;
let http = HttpClient::new(token.clone());
let user_id = http.current_user().await?.model().await?.id;
let application_id = Id::new(app_id);
let interaction_client = http.interaction(application_id);
let commands = &[
CommandBuilder::new("play", "Add a song to the queue", CommandType::ChatInput)
.option(StringBuilder::new("query", "URL of a song").required(true))
.build(),
CommandBuilder::new("stop", "Stop playing", CommandType::ChatInput).build(),
CommandBuilder::new("join", "Join the channel", CommandType::ChatInput).build(),
CommandBuilder::new("leave", "Leave the channel", CommandType::ChatInput).build(),
];
interaction_client.set_global_commands(commands).await?;
let commands = interaction_client.global_commands().await?.models().await?;
debug!("Global commands: {:?}", commands);
let intents = Intents::GUILDS
| Intents::GUILD_MESSAGES
| Intents::GUILD_VOICE_STATES
| Intents::MESSAGE_CONTENT;
let config = twilight_gateway::Config::new(token.clone(), intents);
let shards: Vec<Shard> =
stream::create_recommended(&http, config, |_, builder| builder.build())
.await?
.collect();
let senders = TwilightMap::new(
shards
.iter()
.map(|s| (s.id().number(), s.sender()))
.collect(),
);
let songbird = Songbird::twilight(Arc::new(senders), user_id);
let cache = InMemoryCache::new();
(
@@ -99,10 +113,9 @@ async fn main() -> Result<(), Box<dyn Error + Send + Sync + 'static>> {
}
None => break,
};
debug!("{:?}", &event);
debug!("Event: {:?}", &event);
state.cache.update(&event);
state.standby.process(&event);
state.songbird.process(&event).await;
@@ -134,18 +147,11 @@ async fn join(msg: Message, state: State) -> Result<(), Box<dyn Error + Send + S
.channel_id();
let channel_id =
NonZeroU64::new(channel_id.into()).ok_or("Joined voice channel must have nonzero ID.")?;
let content = match state.songbird.join(guild_id, channel_id).await {
Ok(_handle) => format!("Joined <#{}>!", channel_id),
Err(e) => format!("Failed to join <#{}>! Why: {:?}", channel_id, e),
};
state
.http
.create_message(msg.channel_id)
.content(&content)?
.await?;
.songbird
.join(guild_id, channel_id)
.await
.map_err(|e| format!("Could not join voice channel: {:?}", e))?;
Ok(())
}
@@ -155,17 +161,8 @@ async fn leave(msg: Message, state: State) -> Result<(), Box<dyn Error + Send +
msg.channel_id,
msg.author.name
);
let guild_id = msg.guild_id.unwrap();
state.songbird.leave(guild_id).await?;
state
.http
.create_message(msg.channel_id)
.content("Left the channel")?
.await?;
Ok(())
}
@@ -176,23 +173,23 @@ async fn play(msg: Message, state: State) -> Result<(), Box<dyn Error + Send + S
msg.author.name
);
join(msg.clone(), state.clone()).await?;
let guild_id = msg.guild_id.unwrap();
let url = msg.content.replace("!play", "").trim().to_string();
let mut src = YoutubeDl::new(reqwest::Client::new(), url);
if let Ok(metadata) = src.aux_metadata().await {
info!("metadata: {:?}", metadata);
let content = format!(
"Playing **{:?}** by **{:?}**",
metadata.title.as_ref().unwrap_or(&"<UNKNOWN>".to_string()),
metadata.artist.as_ref().unwrap_or(&"<UNKNOWN>".to_string()),
);
debug!("metadata: {:?}", metadata);
state
.http
.create_message(msg.channel_id)
.content(&content)?
.content(&format!(
"Playing **{:?}** by **{:?}**",
metadata.title.as_ref().unwrap_or(&"<UNKNOWN>".to_string()),
metadata.artist.as_ref().unwrap_or(&"<UNKNOWN>".to_string()),
))?
.await?;
if let Some(call_lock) = state.songbird.get(guild_id) {