use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::sync::Arc;
use tokio::sync::RwLock;
pub const RWI_VERSION: &str = "1.0";
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct EventCallContext {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub caller_name: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub callee_name: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub caller: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub callee: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub direction: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub trunk: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub app_id: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub routing_target: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub agent_id: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub agent_name: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RwiEnvelope<T> {
#[serde(rename = "rwi")]
pub version: String,
#[serde(flatten)]
pub payload: T,
}
impl<T> RwiEnvelope<T> {
pub fn new(payload: T) -> Self {
Self {
version: RWI_VERSION.to_string(),
payload,
}
}
}
pub type RwiEventTx = tokio::sync::mpsc::UnboundedSender<RwiEvent>;
pub type RwiEventRx = tokio::sync::mpsc::UnboundedReceiver<RwiEvent>;
pub use crate::rwi::event::RwiEvent;
#[derive(Debug, Clone, Default)]
pub struct CallMeta {
pub caller: Option<String>,
pub callee: Option<String>,
pub caller_name: Option<String>,
pub callee_name: Option<String>,
pub direction: Option<String>,
pub trunk: Option<String>,
pub app_id: Option<String>,
pub routing_target: Option<String>,
pub agent_id: Option<String>,
pub agent_name: Option<String>,
}
impl From<CallMeta> for EventCallContext {
fn from(m: CallMeta) -> Self {
EventCallContext {
caller: m.caller,
callee: m.callee,
caller_name: m.caller_name,
callee_name: m.callee_name,
direction: m.direction,
trunk: m.trunk,
app_id: m.app_id,
routing_target: m.routing_target,
agent_id: m.agent_id,
agent_name: m.agent_name,
}
}
}
pub struct CallMetaStore {
store: RwLock<HashMap<String, CallMeta>>,
}
impl CallMetaStore {
pub fn new() -> Arc<Self> {
Arc::new(Self {
store: RwLock::new(HashMap::new()),
})
}
pub async fn insert(&self, call_id: String, meta: CallMeta) {
self.store.write().await.insert(call_id, meta);
}
pub async fn get(&self, call_id: &str) -> Option<CallMeta> {
self.store.read().await.get(call_id).cloned()
}
pub fn get_sync(&self, call_id: &str) -> Option<CallMeta> {
self.store.try_read().ok()?.get(call_id).cloned()
}
pub async fn remove(&self, call_id: &str) {
self.store.write().await.remove(call_id);
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub struct RecordingMetadata {
pub filename: String,
pub unique_id: String,
pub file_size: u64,
pub download_url: Option<String>,
pub caller_name: Option<String>,
pub callee_name: Option<String>,
pub called_phone: Option<String>,
pub call_type: String,
pub agent_id: Option<String>,
pub agent_name: Option<String>,
pub call_start_time: Option<String>,
pub call_end_time: Option<String>,
pub upload_time: Option<String>,
pub switch_flag: Option<String>,
pub process_flag: Option<String>,
pub root_call_id: Option<String>,
}