use crate::error::{map_manager_err, ManagerError};
use crate::gen::manager::apis::configuration::Configuration;
use crate::gen::manager::apis::{agent_api, agent_group_api, manager_api};
use crate::gen::manager::models;
use crate::http::{collect_all, fetch_page, Page};
use crate::resources::raw::get_json;
use crate::retry::{with_retry, RetryPolicy};
use crate::token::SharedCfg;
#[derive(Debug, Clone, Default)]
pub struct ListAgentsQuery {
pub q: Option<String>,
pub enabled: Option<bool>,
pub name: Option<String>,
pub number: Option<String>,
pub source_id: Option<String>,
pub state: Option<models::AgentLineStatus>,
pub source: Option<String>,
pub group_ids: Vec<String>,
pub groups: Vec<String>,
pub tags: Vec<String>,
}
impl ListAgentsQuery {
fn to_path(&self, page: i32, max: Option<i32>) -> String {
let mut ser = url::form_urlencoded::Serializer::new(String::new());
ser.append_pair("page", &page.to_string());
if let Some(max) = max {
ser.append_pair("max", &max.to_string());
}
if let Some(v) = &self.q {
ser.append_pair("q", v);
}
if let Some(v) = self.enabled {
ser.append_pair("enabled", if v { "true" } else { "false" });
}
if let Some(v) = &self.name {
ser.append_pair("name", v);
}
if let Some(v) = &self.number {
ser.append_pair("number", v);
}
if let Some(v) = &self.source_id {
ser.append_pair("sourceId", v);
}
if let Some(v) = &self.state {
ser.append_pair("state", &v.to_string());
}
if let Some(v) = &self.source {
ser.append_pair("source", v);
}
for id in &self.group_ids {
ser.append_pair("groupIds", &normalize_entity_id(id));
}
for g in &self.groups {
ser.append_pair("groups", g);
}
for t in &self.tags {
ser.append_pair("tags", t);
}
format!("/api/v2/agents?{}", ser.finish())
}
}
fn normalize_entity_id(v: &str) -> String {
match uuid::Uuid::parse_str(v) {
Ok(u) => u.simple().to_string(),
Err(_) => v.to_string(),
}
}
pub struct AgentsResource {
pub(crate) cfg: SharedCfg<Configuration>,
pub(crate) retry: RetryPolicy,
pub groups: AgentGroupsResource,
}
impl AgentsResource {
pub async fn list(&self, query: ListAgentsQuery) -> Result<Vec<models::Agent>, ManagerError> {
let cfg = self.cfg.get().await?;
let cfg = cfg.as_ref();
let query = &query;
collect_all(
&self.retry,
|e| e,
|page| async move {
let v = get_json(cfg, &query.to_path(page, None)).await?;
let r: models::PaginatedAgentResponse =
serde_json::from_value(v).map_err(|e| ManagerError::Decode(e.to_string()))?;
Ok((r.items, r.pagination.pages, r.pagination.current))
},
)
.await
}
pub async fn list_all(&self) -> Result<Vec<models::Agent>, ManagerError> {
self.list(ListAgentsQuery::default()).await
}
pub async fn list_page(
&self,
page: i32,
per_page: Option<i32>,
query: ListAgentsQuery,
) -> Result<Page<models::Agent>, ManagerError> {
let cfg = self.cfg.get().await?;
let cfg = cfg.as_ref();
let query = &query;
fetch_page(
&self.retry,
|e| e,
|| async move {
let v = get_json(cfg, &query.to_path(page, per_page)).await?;
let r: models::PaginatedAgentResponse =
serde_json::from_value(v).map_err(|e| ManagerError::Decode(e.to_string()))?;
Ok((
r.items,
r.pagination.pages,
r.pagination.current,
Some(r.pagination.total),
))
},
)
.await
}
pub async fn create(
&self,
body: models::RestCreateAgent,
) -> Result<models::AgentItemResponse, ManagerError> {
let cfg = self.cfg.get().await?;
let cfg = cfg.as_ref();
with_retry(&self.retry, false, || {
agent_api::create_agent(cfg, body.clone())
})
.await
.map_err(map_manager_err)
}
pub async fn get(&self, id: &str) -> Result<models::AgentItemResponse, ManagerError> {
let cfg = self.cfg.get().await?;
let cfg = cfg.as_ref();
with_retry(&self.retry, true, || agent_api::get_agent(cfg, id))
.await
.map_err(map_manager_err)
}
pub async fn update(
&self,
id: &str,
body: models::RestUpdateAgent,
) -> Result<models::AgentItemResponse, ManagerError> {
let cfg = self.cfg.get().await?;
let cfg = cfg.as_ref();
with_retry(&self.retry, false, || {
agent_api::update_agent(cfg, id, body.clone())
})
.await
.map_err(map_manager_err)
}
pub async fn delete(&self, id: &str) -> Result<(), ManagerError> {
let cfg = self.cfg.get().await?;
let cfg = cfg.as_ref();
with_retry(&self.retry, false, || agent_api::delete_agent(cfg, id))
.await
.map_err(map_manager_err)?;
Ok(())
}
pub async fn update_status(
&self,
id: &str,
status: models::UpdateAgentStatusRequest,
) -> Result<models::AgentStatus, ManagerError> {
let cfg = self.cfg.get().await?;
let cfg = cfg.as_ref();
with_retry(&self.retry, false, || {
manager_api::update_agent_status(cfg, id, Some(status.clone()))
})
.await
.map_err(map_manager_err)
}
pub async fn presences(&self) -> Result<models::AgentPresenceListResponse, ManagerError> {
let cfg = self.cfg.get().await?;
let cfg = cfg.as_ref();
with_retry(&self.retry, true, || agent_api::list_agent_presences(cfg))
.await
.map_err(map_manager_err)
}
pub async fn get_presence(
&self,
name: &str,
) -> Result<models::AgentPresenceItemResponse, ManagerError> {
let cfg = self.cfg.get().await?;
let cfg = cfg.as_ref();
with_retry(&self.retry, true, || {
agent_api::get_agent_presence(cfg, name)
})
.await
.map_err(map_manager_err)
}
pub async fn create_presence(
&self,
body: models::AgentPresenceWriteBody,
) -> Result<models::AgentPresenceItemResponse, ManagerError> {
let cfg = self.cfg.get().await?;
let cfg = cfg.as_ref();
with_retry(&self.retry, false, || {
agent_api::create_agent_presence(cfg, body.clone())
})
.await
.map_err(map_manager_err)
}
pub async fn update_presence(
&self,
name: &str,
body: models::AgentPresenceWriteBody,
) -> Result<models::AgentPresenceItemResponse, ManagerError> {
let cfg = self.cfg.get().await?;
let cfg = cfg.as_ref();
with_retry(&self.retry, false, || {
agent_api::update_agent_presence(cfg, name, body.clone())
})
.await
.map_err(map_manager_err)
}
pub async fn delete_presence(
&self,
name: &str,
) -> Result<models::DefaultV2MessageResponse, ManagerError> {
let cfg = self.cfg.get().await?;
let cfg = cfg.as_ref();
with_retry(&self.retry, false, || {
agent_api::delete_agent_presence(cfg, name)
})
.await
.map_err(map_manager_err)
}
pub async fn get_status(
&self,
id: &str,
) -> Result<models::AgentTotalStatusResponse, ManagerError> {
let cfg = self.cfg.get().await?;
let cfg = cfg.as_ref();
with_retry(&self.retry, true, || agent_api::get_agent_status(cfg, id))
.await
.map_err(map_manager_err)
}
pub async fn available_statuses(
&self,
) -> Result<models::AgentAvailabilityListResponse, ManagerError> {
let cfg = self.cfg.get().await?;
let cfg = cfg.as_ref();
with_retry(&self.retry, true, || {
agent_api::list_available_agent_statuses(cfg)
})
.await
.map_err(map_manager_err)
}
pub async fn enable(&self, id: &str) -> Result<models::DefaultV2MessageResponse, ManagerError> {
let cfg = self.cfg.get().await?;
let cfg = cfg.as_ref();
with_retry(&self.retry, false, || agent_api::enable_agent(cfg, id))
.await
.map_err(map_manager_err)
}
pub async fn disable(
&self,
id: &str,
) -> Result<models::DefaultV2MessageResponse, ManagerError> {
let cfg = self.cfg.get().await?;
let cfg = cfg.as_ref();
with_retry(&self.retry, false, || agent_api::disable_agent(cfg, id))
.await
.map_err(map_manager_err)
}
pub async fn hangup_call(
&self,
id: &str,
) -> Result<models::DefaultV2MessageResponse, ManagerError> {
let cfg = self.cfg.get().await?;
let cfg = cfg.as_ref();
with_retry(&self.retry, false, || agent_api::hangup_agent_call(cfg, id))
.await
.map_err(map_manager_err)
}
pub async fn bulk_action(
&self,
action: &str,
body: models::AgentBulkRequest,
) -> Result<models::AgentBulkResponse, ManagerError> {
let cfg = self.cfg.get().await?;
let cfg = cfg.as_ref();
with_retry(&self.retry, false, || {
agent_api::bulk_agent_action(cfg, action, body.clone())
})
.await
.map_err(map_manager_err)
}
pub async fn export(&self, format: &str) -> Result<String, ManagerError> {
let cfg = self.cfg.get().await?;
let cfg = cfg.as_ref();
with_retry(&self.retry, true, || agent_api::export_agents(cfg, format))
.await
.map_err(map_manager_err)
}
#[allow(clippy::too_many_arguments)]
pub async fn import_agents(
&self,
format: &str,
file: std::path::PathBuf,
r#async: Option<bool>,
create_only: Option<bool>,
update_only: Option<bool>,
delete_unlisted: Option<bool>,
) -> Result<models::AgentImportValidationResults, ManagerError> {
let cfg = self.cfg.get().await?;
let cfg = cfg.as_ref();
with_retry(&self.retry, false, || {
agent_api::import_agents(
cfg,
format,
file.clone(),
r#async,
create_only,
update_only,
delete_unlisted,
)
})
.await
.map_err(map_manager_err)
}
pub async fn validate_import(
&self,
file: std::path::PathBuf,
) -> Result<models::AgentImportValidationResults, ManagerError> {
let cfg = self.cfg.get().await?;
let cfg = cfg.as_ref();
with_retry(&self.retry, false, || {
agent_api::validate_agent_import(cfg, file.clone())
})
.await
.map_err(map_manager_err)
}
pub async fn get_import_job(
&self,
id: &str,
) -> Result<models::AgentImportJobItemResponse, ManagerError> {
let cfg = self.cfg.get().await?;
let cfg = cfg.as_ref();
with_retry(&self.retry, true, || {
agent_api::get_agent_import_job(cfg, id)
})
.await
.map_err(map_manager_err)
}
pub async fn logs(
&self,
id: &str,
from: Option<i32>,
to: Option<i32>,
) -> Result<Vec<models::AgentLogEntry>, ManagerError> {
let cfg = self.cfg.get().await?;
let cfg = cfg.as_ref();
collect_all(&self.retry, map_manager_err, |page| async move {
let r = agent_api::list_agent_logs(cfg, id, Some(page), None, from, to).await?;
let (pages, current) = r
.pagination
.as_ref()
.map(|p| (p.pages, p.current))
.unwrap_or((1, 1));
Ok((r.items, pages, current))
})
.await
}
pub async fn all_logs(&self) -> Result<Vec<models::AgentLogEntry>, ManagerError> {
let cfg = self.cfg.get().await?;
let cfg = cfg.as_ref();
collect_all(&self.retry, map_manager_err, |page| async move {
let r = agent_api::list_all_agent_logs(cfg, Some(page), None).await?;
let (pages, current) = r
.pagination
.as_ref()
.map(|p| (p.pages, p.current))
.unwrap_or((1, 1));
Ok((r.items, pages, current))
})
.await
}
pub async fn push(
&self,
body: models::AgentPushRequest,
) -> Result<models::DefaultV2MessageResponse, ManagerError> {
let cfg = self.cfg.get().await?;
let cfg = cfg.as_ref();
with_retry(&self.retry, false, || {
agent_api::push_to_agent(cfg, body.clone())
})
.await
.map_err(map_manager_err)
}
pub async fn update_password(
&self,
id: &str,
body: models::AgentPasswordUpdateRequest,
) -> Result<models::DefaultV2MessageResponse, ManagerError> {
let cfg = self.cfg.get().await?;
let cfg = cfg.as_ref();
with_retry(&self.retry, false, || {
agent_api::update_agent_password(cfg, id, body.clone())
})
.await
.map_err(map_manager_err)
}
}
pub struct AgentGroupsResource {
pub(crate) cfg: SharedCfg<Configuration>,
pub(crate) retry: RetryPolicy,
}
impl AgentGroupsResource {
pub async fn list_all(&self) -> Result<Vec<models::AgentGroup>, ManagerError> {
let cfg = self.cfg.get().await?;
let cfg = cfg.as_ref();
collect_all(&self.retry, map_manager_err, |page| async move {
let r = agent_group_api::list_agent_groups(cfg, Some(page), None).await?;
Ok((r.items, r.pagination.pages, r.pagination.current))
})
.await
}
pub async fn create(
&self,
body: models::RestCreateAgentGroup,
) -> Result<models::AgentGroupItemResponse, ManagerError> {
let cfg = self.cfg.get().await?;
let cfg = cfg.as_ref();
with_retry(&self.retry, false, || {
agent_group_api::create_agent_group(cfg, body.clone())
})
.await
.map_err(map_manager_err)
}
pub async fn get(&self, id: &str) -> Result<models::AgentGroupItemResponse, ManagerError> {
let cfg = self.cfg.get().await?;
let cfg = cfg.as_ref();
with_retry(&self.retry, true, || {
agent_group_api::get_agent_group(cfg, id)
})
.await
.map_err(map_manager_err)
}
pub async fn update(
&self,
id: &str,
body: models::RestUpdateAgentGroup,
) -> Result<models::AgentGroupItemResponse, ManagerError> {
let cfg = self.cfg.get().await?;
let cfg = cfg.as_ref();
with_retry(&self.retry, false, || {
agent_group_api::update_agent_group(cfg, id, body.clone())
})
.await
.map_err(map_manager_err)
}
pub async fn delete(&self, id: &str) -> Result<(), ManagerError> {
let cfg = self.cfg.get().await?;
let cfg = cfg.as_ref();
with_retry(&self.retry, false, || {
agent_group_api::delete_agent_group(cfg, id)
})
.await
.map_err(map_manager_err)?;
Ok(())
}
pub async fn add_agent(
&self,
group_id: &str,
agent_id: &str,
) -> Result<models::AgentGroupAdditionResponse, ManagerError> {
let cfg = self.cfg.get().await?;
let cfg = cfg.as_ref();
let id = uuid::Uuid::parse_str(agent_id)
.map_err(|e| ManagerError::InvalidArgument(format!("agent_id: {e}")))?;
let body = models::AddAgentToGroupRequest { id };
with_retry(&self.retry, false, || {
manager_api::add_agent_to_group(cfg, group_id, Some(body.clone()))
})
.await
.map_err(map_manager_err)
}
pub async fn remove_agent(
&self,
group_id: &str,
agent_id: &str,
) -> Result<models::AgentGroupItemResponse, ManagerError> {
let cfg = self.cfg.get().await?;
let cfg = cfg.as_ref();
with_retry(&self.retry, false, || {
agent_group_api::remove_agent_from_group(cfg, group_id, agent_id)
})
.await
.map_err(map_manager_err)
}
pub async fn list_agents(&self, group_id: &str) -> Result<Vec<models::Agent>, ManagerError> {
let cfg = self.cfg.get().await?;
let cfg = cfg.as_ref();
collect_all(&self.retry, map_manager_err, |page| async move {
let r = agent_group_api::list_agents_in_group(cfg, group_id, Some(page), None).await?;
Ok((r.items, r.pagination.pages, r.pagination.current))
})
.await
}
pub async fn bulk_delete(
&self,
ids: Vec<String>,
) -> Result<models::DefaultV2MessageResponse, ManagerError> {
let cfg = self.cfg.get().await?;
let cfg = cfg.as_ref();
let ids = ids
.iter()
.map(|id| {
uuid::Uuid::parse_str(id)
.map_err(|e| ManagerError::InvalidArgument(format!("ids: {e}")))
})
.collect::<Result<Vec<_>, _>>()?;
let body = models::BulkIdsRequest { ids };
with_retry(&self.retry, false, || {
agent_group_api::bulk_delete_agent_groups(cfg, body.clone())
})
.await
.map_err(map_manager_err)
}
}