Skip to content

Commit

Permalink
fix: 通知処理の修正 (#18)
Browse files Browse the repository at this point in the history
fix: 指定時間経過後にユーザーが指定したボイスチャンネルに参加していると通知するように修正
  • Loading branch information
hulk510 authored Dec 21, 2023
1 parent 7168185 commit e43e2ec
Showing 1 changed file with 59 additions and 15 deletions.
74 changes: 59 additions & 15 deletions main.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
#[cfg(feature = "dotenv")]
use dotenvy::dotenv;
use std::{env, error::Error, sync::Arc};
use std::{env, error::Error, sync::Arc, time::Duration};
use twilight_cache_inmemory::{InMemoryCache, ResourceType};
use twilight_gateway::{Event, Intents, Shard, ShardId};
use twilight_http::Client as HttpClient;
use twilight_mention::Mention;
use twilight_model::id::{Id, marker::RoleMarker};
use twilight_model::id::{
marker::{ChannelMarker, RoleMarker, UserMarker},
Id,
};

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error + Send + Sync>> {
Expand All @@ -25,9 +28,11 @@ async fn main() -> Result<(), Box<dyn Error + Send + Sync>> {
let http = Arc::new(HttpClient::new(token));

// Since we only care about messages, make the cache only process messages.
let cache = InMemoryCache::builder()
.resource_types(ResourceType::MESSAGE)
.build();
let cache = Arc::new(
InMemoryCache::builder()
.resource_types(ResourceType::VOICE_STATE)
.build(),
);

// Startup the event loop to process each event in the event stream as they
// come in.
Expand All @@ -48,7 +53,7 @@ async fn main() -> Result<(), Box<dyn Error + Send + Sync>> {
cache.update(&event);

// Spawn a new task to handle the event
tokio::spawn(handle_event(event, Arc::clone(&http)));
tokio::spawn(handle_event(event, Arc::clone(&http), Arc::clone(&cache)));
}

Ok(())
Expand All @@ -57,26 +62,65 @@ async fn main() -> Result<(), Box<dyn Error + Send + Sync>> {
async fn handle_event(
event: Event,
http: Arc<HttpClient>,
cache: Arc<InMemoryCache>,
) -> Result<(), Box<dyn Error + Send + Sync>> {
match event {
Event::MessageCreate(msg) if msg.content == "!ping" => {
http.create_message(msg.channel_id).content("Pong!")?.await?;
}
Event::Ready(_) => {
println!("Shard is ready");
}
Event::VoiceStateUpdate(state) => {
let voice_channel_id: String = env::var("VOICE_CHANNEL_ID")?;
if state.channel_id.expect("Channel ID not found.").to_string() != voice_channel_id {
let Some(channel_id) = state.channel_id else {
return Ok(());
};
let voice_channel_id: Id<ChannelMarker> =
Id::new(env::var("VOICE_CHANNEL_ID")?.parse().unwrap());
// 指定したチャンネル以外のボイスチャンネルに入ったら何もしない
if channel_id != voice_channel_id {
return Ok(());
}
// ボイスチャンネルの人数が1人の場合処理を続ける
let member_count = cache
.voice_channel_states(voice_channel_id)
.unwrap()
.count();
if member_count != 1 {
return Ok(());
}
let text_channel_id = Id::new(env::var("TEXT_CHANNEL_ID")?.parse().unwrap());
let role_id: Id<RoleMarker> = Id::new(env::var("ROLE_ID")?.parse().unwrap());
let message: String = format!("{}の皆さん{}は暇です! 誰かカモン〜ヌ!", role_id.mention(), state.user_id.mention());
http.create_message(text_channel_id).content(&message)?.await?;

// 10秒後にまだそのユーザーが参加していたらメッセージを送信する
tokio::time::sleep(Duration::from_secs(10)).await;
let Some(guild_id) = state.guild_id else {
return Ok(());
};
let Some(current_state) = cache.voice_state(state.0.user_id, guild_id) else {
return Ok(());
};
// ユーザーが指定したチャンネルのボイスチャンネルに入ってるか確認
if current_state.channel_id() != voice_channel_id {
return Ok(());
};

create_join_message(state.0.user_id, http).await?;
}
_ => {}
}

Ok(())
}

async fn create_join_message(
user_id: Id<UserMarker>,
http: Arc<HttpClient>,
) -> Result<(), Box<dyn Error + Send + Sync>> {
let text_channel_id: Id<ChannelMarker> = Id::new(env::var("TEXT_CHANNEL_ID")?.parse().unwrap());
let role_id: Id<RoleMarker> = Id::new(env::var("ROLE_ID")?.parse().unwrap());
let message: String = format!(
"{}の皆さん{}は暇です! 誰かカモン〜ヌ!",
role_id.mention(),
user_id.mention()
);
http.create_message(text_channel_id)
.content(&message)?
.await?;
Ok(())
}

0 comments on commit e43e2ec

Please sign in to comment.