use crate::domain::aggregates::identity_link::value_objects::ExternalSystem;
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::constants::ACTION_EMAIL_INPUT;
use crate::interface::slack::utility::extract_form_data;
use slack_morphism::prelude::*;
use tracing::{error, info};
pub async fn handle<R, N>(
app: &SlackApp<R, N>,
view_submission: &SlackInteractionViewSubmissionEvent,
) -> Result<Option<SlackViewSubmissionResponse>, Box<dyn std::error::Error + Send + Sync>>
where
R: ResourceUsageRepository + Send + Sync + 'static,
N: Notifier + Send + Sync + 'static,
{
info!("メールアドレス登録を処理中...");
let user_id = view_submission.user.id.clone();
let email_value = extract_form_data::get_plain_text_input(view_submission, ACTION_EMAIL_INPUT)
.ok_or("メールアドレスが入力されていません")?;
let email_result = EmailAddress::new(email_value.trim().to_string());
let registration_result = match &email_result {
Ok(email) => app
.grant_access_usecase()
.execute(ExternalSystem::Slack, user_id.to_string(), email.clone())
.await
.map_err(|e| e.into()),
Err(e) => Err(Box::new(e.clone()) as Box<dyn std::error::Error + Send + Sync>),
};
let channel_id = app
.user_channel_map()
.read()
.unwrap()
.get(&user_id)
.cloned()
.ok_or("セッションの有効期限が切れました。もう一度コマンドを実行してください。")?;
let message_text = match registration_result {
Ok(_) => {
info!(
"✅ ユーザー登録成功: {}",
email_result.as_ref().unwrap().as_str()
);
format!(
"✅ メールアドレス {} を登録しました",
email_result.as_ref().unwrap().as_str()
)
}
Err(e) => {
error!("❌ ユーザー登録に失敗: {}", e);
format!("❌ 登録に失敗しました: {}", e)
}
};
let ephemeral_req = SlackApiChatPostEphemeralRequest::new(
channel_id,
user_id.clone(),
SlackMessageContent::new().with_text(message_text),
);
let session = app.slack_client().open_session(app.bot_token());
session.chat_post_ephemeral(&ephemeral_req).await?;
Ok(None)
}