use async_trait::async_trait;
use serde::{Deserialize, Serialize};
use uuid::Uuid;
use crate::domain::entities::{Message, Rei};
use crate::domain::errors::DomainError;
#[async_trait]
pub trait TeiIntegration: Send + Sync {
async fn read_messages(&self, rei: &Rei) -> Result<Vec<Message>, DomainError>;
async fn post_message(&self, rei: &Rei, content: &str) -> Result<(), DomainError>;
fn name(&self) -> &str;
async fn handle_webhook(
&self,
_payload: &[u8],
) -> Result<Option<IntegrationEvent>, DomainError> {
Ok(None)
}
async fn health_check(&self) -> Result<bool, DomainError> {
Ok(true)
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum IntegrationEvent {
MessageReceived {
channel_id: String,
user_id: String,
user_name: String,
content: String,
#[serde(default)]
metadata: serde_json::Value,
},
MentionReceived {
rei_id: Uuid,
channel_id: String,
user_id: String,
user_name: String,
content: String,
},
ReactionAdded {
message_id: String,
channel_id: String,
user_id: String,
emoji: String,
},
DirectMessage {
user_id: String,
user_name: String,
content: String,
},
SlashCommand {
command: String,
user_id: String,
channel_id: String,
args: Vec<String>,
},
}
impl IntegrationEvent {
pub fn channel_id(&self) -> Option<&str> {
match self {
Self::MessageReceived { channel_id, .. } => Some(channel_id),
Self::MentionReceived { channel_id, .. } => Some(channel_id),
Self::ReactionAdded { channel_id, .. } => Some(channel_id),
Self::SlashCommand { channel_id, .. } => Some(channel_id),
Self::DirectMessage { .. } => None,
}
}
pub fn user_id(&self) -> Option<&str> {
match self {
Self::MessageReceived { user_id, .. } => Some(user_id),
Self::MentionReceived { user_id, .. } => Some(user_id),
Self::ReactionAdded { user_id, .. } => Some(user_id),
Self::DirectMessage { user_id, .. } => Some(user_id),
Self::SlashCommand { user_id, .. } => Some(user_id),
}
}
pub fn content(&self) -> Option<&str> {
match self {
Self::MessageReceived { content, .. } => Some(content),
Self::MentionReceived { content, .. } => Some(content),
Self::DirectMessage { content, .. } => Some(content),
_ => None,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct IntegrationConfig {
pub platform: String,
pub channel_id: Option<String>,
pub respond_to_mentions: bool,
pub respond_to_dms: bool,
#[serde(default)]
pub settings: serde_json::Value,
}
impl Default for IntegrationConfig {
fn default() -> Self {
Self {
platform: String::new(),
channel_id: None,
respond_to_mentions: true,
respond_to_dms: true,
settings: serde_json::Value::Null,
}
}
}