use crate::domain::aggregates::resource_usage::value_objects::UsageId;
use crate::domain::common::EmailAddress;
use crate::domain::ports::notifier::Notifier;
use crate::domain::ports::repositories::ResourceUsageRepository;
use crate::interface::slack::app::SlackApp;
use crate::interface::slack::utility::user_resolver;
use slack_morphism::prelude::*;
use tracing::{error, info};
pub async fn handle<R, N>(
app: &SlackApp<R, N>,
block_actions: &SlackInteractionBlockActionsEvent,
action: &SlackInteractionActionInfo,
) -> Result<(), Box<dyn std::error::Error + Send + Sync>>
where
R: ResourceUsageRepository + Send + Sync + 'static,
N: Notifier + Send + Sync + 'static,
{
let Some(usage_id_str) = &action.value else {
error!("❌ usage_idが取得できませんでした");
return Ok(());
};
let Some(user) = &block_actions.user else {
error!("❌ ユーザー情報が取得できませんでした");
return Ok(());
};
info!("🗑️ 予約キャンセル要求: usage_id={}", usage_id_str);
let channel_id = if let Some(channel) = &block_actions.channel {
app.user_channel_map()
.write()
.unwrap()
.insert(user.id.clone(), channel.id.clone());
Some(channel.id.clone())
} else if let SlackInteractionActionContainer::Message(msg) = &block_actions.container {
if let Some(channel_id) = &msg.channel_id {
app.user_channel_map()
.write()
.unwrap()
.insert(user.id.clone(), channel_id.clone());
Some(channel_id.clone())
} else {
None
}
} else {
None
};
let delete_usage_usecase = app.delete_usage_usecase();
let identity_repo = app.identity_repo();
let owner_email = user_resolver::resolve_user_email(&user.id, identity_repo).await?;
let usage_id = UsageId::from_string(usage_id_str.to_string());
info!(
"📍 削除処理開始: usage_id={}, owner={}",
usage_id.as_str(),
owner_email.as_str()
);
let result = delete_usage_usecase
.execute(&usage_id, &EmailAddress::new(owner_email.clone())?)
.await;
if let Some(ch_id) = channel_id {
let message_text = match &result {
Ok(_) => {
info!("✅ 削除成功: {}", usage_id.as_str());
"✅ 予約をキャンセルしました".to_string()
}
Err(e) => {
error!("❌ 削除失敗: usage_id={}, error={}", usage_id.as_str(), e);
let error_msg = e.to_string();
if error_msg.contains("見つかりません") || error_msg.contains("NotFound") {
"❌ 申し訳ございません。この予約は既に削除されているか、見つかりませんでした。"
.to_string()
} else if error_msg.contains("権限") || error_msg.contains("Unauthorized") {
"❌ この予約を削除する権限がありません。".to_string()
} else {
format!("❌ 予約の削除に失敗しました: {}", error_msg)
}
}
};
let ephemeral_req = SlackApiChatPostEphemeralRequest::new(
ch_id,
user.id.clone(),
SlackMessageContent::new().with_text(message_text),
);
let session = app.slack_client().open_session(app.bot_token());
if let Err(e) = session.chat_post_ephemeral(&ephemeral_req).await {
error!("❌ エフェメラルメッセージ送信失敗: {}", e);
}
} else {
error!("❌ channel_idが取得できないため、エフェメラルメッセージを送信できませんでした");
}
Ok(())
}