use crate::domain::ports::notifier::Notifier;
use crate::domain::ports::repositories::ResourceUsageRepository;
use crate::interface::slack::app::SlackApp;
use crate::interface::slack::constants::*;
use slack_morphism::prelude::*;
use tracing::error;
impl<R, N> SlackApp<R, N>
where
R: ResourceUsageRepository + Send + Sync + 'static,
N: Notifier + Send + Sync + 'static,
{
pub async fn route_slash_command(
&self,
event: SlackCommandEvent,
) -> Result<SlackCommandEventResponse, Box<dyn std::error::Error + Send + Sync>> {
let command = event.command.0.as_str();
self.user_channel_map()
.write()
.unwrap()
.insert(event.user_id.clone(), event.channel_id.clone());
match command {
"/reserve" => {
crate::interface::slack::slash_commands::reserve::handle(self, event).await
}
"/register-calendar" => {
crate::interface::slack::slash_commands::register_calendar::handle(self, event)
.await
}
"/link-user" => {
crate::interface::slack::slash_commands::link_user::handle(self, event).await
}
_ => Ok(SlackCommandEventResponse::new(
SlackMessageContent::new().with_text(format!("不明なコマンド: {}", command)),
)),
}
}
pub async fn route_interaction(
&self,
event: SlackInteractionEvent,
) -> Result<Option<SlackViewSubmissionResponse>, Box<dyn std::error::Error + Send + Sync>> {
match &event {
SlackInteractionEvent::ViewSubmission(view_submission) => {
self.route_view_submission(view_submission).await
}
SlackInteractionEvent::BlockActions(block_actions) => {
self.route_block_actions(block_actions).await?;
Ok(None)
}
SlackInteractionEvent::ViewClosed(_) => Ok(None),
_ => Ok(None),
}
}
async fn route_view_submission(
&self,
view_submission: &SlackInteractionViewSubmissionEvent,
) -> Result<Option<SlackViewSubmissionResponse>, Box<dyn std::error::Error + Send + Sync>> {
let callback_id = match &view_submission.view.view {
SlackView::Modal(modal) => modal.callback_id.as_ref().map(|id| id.to_string()),
_ => None,
};
match callback_id.as_deref() {
Some(CALLBACK_REGISTER_EMAIL) => {
crate::interface::slack::view_submissions::registration::handle(
self,
view_submission,
)
.await
}
Some(CALLBACK_LINK_USER) => {
crate::interface::slack::view_submissions::link_user::handle(self, view_submission)
.await
}
Some(CALLBACK_RESERVE_SUBMIT) => {
crate::interface::slack::view_submissions::reserve::handle(self, view_submission)
.await
}
Some(CALLBACK_RESERVE_UPDATE) => {
crate::interface::slack::view_submissions::update::handle(self, view_submission)
.await
}
_ => {
error!("❌ 不明なcallback_id: {:?}", callback_id);
Ok(None)
}
}
}
async fn route_block_actions(
&self,
block_actions: &SlackInteractionBlockActionsEvent,
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
if block_actions.view.is_some() {
return self.route_modal_interactions(block_actions).await;
}
let Some(actions) = &block_actions.actions else {
return Ok(());
};
for action in actions {
let action_id = action.action_id.to_string();
match action_id.as_str() {
ACTION_EDIT_RESERVATION => {
crate::interface::slack::block_actions::edit_button::handle(
self,
block_actions,
action,
)
.await?
}
ACTION_CANCEL_RESERVATION => {
crate::interface::slack::block_actions::cancel_button::handle(
self,
block_actions,
action,
)
.await?
}
_ => {}
}
}
Ok(())
}
async fn route_modal_interactions(
&self,
block_actions: &SlackInteractionBlockActionsEvent,
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let Some(actions) = &block_actions.actions else {
return Ok(());
};
for action in actions {
let action_id = action.action_id.to_string();
match action_id.as_str() {
ACTION_RESERVE_RESOURCE_TYPE | ACTION_RESERVE_SERVER_SELECT => {
crate::interface::slack::block_actions::modal_state_change::handle(
self,
block_actions,
action,
)
.await?
}
_ => {
}
}
}
Ok(())
}
}