use crate::errors::*;
use crate::events::*;
use crate::listener::{SlackClientEventsUserState, UserCallbackFunction};
use crate::models::events::{SlackCommandEvent, SlackCommandEventResponse};
use crate::models::socket_mode::SlackSocketModeHelloEvent;
use crate::{SlackClient, SlackClientHttpConnector, UserCallbackResult};
use futures::future::BoxFuture;
use std::future::Future;
use std::sync::Arc;
use tracing::*;
pub trait SlackSocketModeListenerCallback<SCHC, RQ, RS>
where
SCHC: SlackClientHttpConnector + Send + Sync,
RQ: Send + Sync + 'static,
RS: Send + Sync + 'static,
{
fn call(
&self,
ev: RQ,
client: Arc<SlackClient<SCHC>>,
state_storage: SlackClientEventsUserState,
) -> BoxFuture<'static, RS>;
}
impl<T, F, SCHC, RQ, RS> SlackSocketModeListenerCallback<SCHC, RQ, RS> for T
where
T: Send + Sync + Fn(RQ, Arc<SlackClient<SCHC>>, SlackClientEventsUserState) -> F,
F: Future<Output = RS> + Send + 'static,
SCHC: SlackClientHttpConnector + Send + Sync,
RQ: Send + Sync + 'static,
RS: Send + Sync + 'static,
{
fn call(
&self,
ev: RQ,
client: Arc<SlackClient<SCHC>>,
state_storage: SlackClientEventsUserState,
) -> BoxFuture<'static, RS> {
Box::pin(self(ev, client, state_storage))
}
}
pub struct SlackSocketModeListenerCallbacks<SCHC>
where
SCHC: SlackClientHttpConnector + Send + Sync,
{
pub hello_callback:
Box<dyn SlackSocketModeListenerCallback<SCHC, SlackSocketModeHelloEvent, ()> + Send + Sync>,
pub command_callback: Box<
dyn SlackSocketModeListenerCallback<
SCHC,
SlackCommandEvent,
UserCallbackResult<SlackCommandEventResponse>,
> + Send
+ Sync,
>,
pub interaction_callback: Box<
dyn SlackSocketModeListenerCallback<SCHC, SlackInteractionEvent, UserCallbackResult<()>>
+ Send
+ Sync,
>,
pub push_events_callback: Box<
dyn SlackSocketModeListenerCallback<SCHC, SlackPushEventCallback, UserCallbackResult<()>>
+ Send
+ Sync,
>,
}
impl<SCHC> SlackSocketModeListenerCallbacks<SCHC>
where
SCHC: SlackClientHttpConnector + Send + Sync + 'static,
{
pub fn new() -> Self {
Self {
hello_callback: Box::new(Self::empty_hello_callback),
command_callback: Box::new(Self::empty_command_events_callback),
interaction_callback: Box::new(Self::empty_interaction_events_callback),
push_events_callback: Box::new(Self::empty_push_events_callback),
}
}
pub fn with_hello_events<F>(
mut self,
hello_events_fn: UserCallbackFunction<SlackSocketModeHelloEvent, F, SCHC>,
) -> Self
where
F: Future<Output = ()> + Send + 'static,
{
self.hello_callback = Box::new(hello_events_fn);
self
}
async fn empty_hello_callback(
event: SlackSocketModeHelloEvent,
_client: Arc<SlackClient<SCHC>>,
_states: SlackClientEventsUserState,
) {
debug!("Received Slack hello for socket mode: {:?}", event);
}
pub fn with_command_events<F>(
mut self,
command_events_fn: UserCallbackFunction<SlackCommandEvent, F, SCHC>,
) -> Self
where
F: Future<Output = UserCallbackResult<SlackCommandEventResponse>> + Send + 'static,
{
self.command_callback = Box::new(command_events_fn);
self
}
async fn empty_command_events_callback(
event: SlackCommandEvent,
_client: Arc<SlackClient<SCHC>>,
_states: SlackClientEventsUserState,
) -> Result<SlackCommandEventResponse, Box<dyn std::error::Error + Send + Sync>> {
warn!("No callback is specified for a command event: {:?}", event);
Err(Box::new(SlackClientError::SystemError(
SlackClientSystemError::new()
.with_message("No callback is specified for a command event".to_string()),
)))
}
pub fn with_interaction_events<F>(
mut self,
interaction_events_fn: UserCallbackFunction<SlackInteractionEvent, F, SCHC>,
) -> Self
where
F: Future<Output = UserCallbackResult<()>> + Send + 'static,
{
self.interaction_callback = Box::new(interaction_events_fn);
self
}
async fn empty_interaction_events_callback(
event: SlackInteractionEvent,
_client: Arc<SlackClient<SCHC>>,
_states: SlackClientEventsUserState,
) -> UserCallbackResult<()> {
warn!(
"No callback is specified for interactive events: {:?}",
event
);
Err(Box::new(SlackClientError::SystemError(
SlackClientSystemError::new()
.with_message("No callback is specified for interactive events".to_string()),
)))
}
pub fn with_push_events<F>(
mut self,
push_events_fn: UserCallbackFunction<SlackPushEventCallback, F, SCHC>,
) -> Self
where
F: Future<Output = UserCallbackResult<()>> + Send + 'static,
{
self.push_events_callback = Box::new(push_events_fn);
self
}
async fn empty_push_events_callback(
event: SlackPushEventCallback,
_client: Arc<SlackClient<SCHC>>,
_states: SlackClientEventsUserState,
) -> UserCallbackResult<()> {
warn!("No callback is specified for a push event: {:?}", event);
Err(Box::new(SlackClientError::SystemError(
SlackClientSystemError::new()
.with_message("No callback is specified for push events".to_string()),
)))
}
}