pub mod database; pub mod schema; use std::ops::Deref; use std::str::FromStr; use xml_builder::{XMLBuilder, XMLElement, XMLVersion}; use actix_web::{web, App, HttpResponse, HttpServer, http::header::ContentType, Responder, }; use serde::Deserialize; use database as db; use database::DidTargetType; #[derive(Debug, Deserialize)] struct RouteData { #[serde(rename = "Caller-Destination-Number")] dest_did: String } #[derive(Debug, Deserialize)] struct JsonDid { did_number: String, target_type: String, target: String, active: bool } async fn route_did(data: web::Form) -> impl Responder { let _dest_did = data.dest_did.clone(); let mut xml = XMLBuilder::new() .version(XMLVersion::XML1_1) .encoding("UTF-8".into()) .build(); let mut doc = XMLElement::new("document"); doc.add_attribute("type", "xml/freeswitch-httapi"); let params = XMLElement::new("params"); let mut work = XMLElement::new("work"); let mut playback = XMLElement::new("playback"); playback.add_attribute("name", "exten"); playback.add_attribute("file", "ivr/ivr-welcome_to_freeswitch.wav"); work.add_child(playback).unwrap(); doc.add_child(params).unwrap(); doc.add_child(work).unwrap(); xml.set_root_element(doc); let mut writer: Vec = Vec::new(); xml.generate(&mut writer).unwrap(); HttpResponse::Ok() .content_type(ContentType::xml()) .body(writer) } async fn did_post(d: web::Json) -> impl Responder { let did = d.deref(); db::add_did(&did.did_number, &did.target_type, &did.target, did.active).unwrap(); HttpResponse::Ok().body("DID added.") } async fn did_index() -> impl Responder { let dids = db::list_did().unwrap(); HttpResponse::Ok().json(dids) } async fn did_get(path: web::Path) -> impl Responder { let id = path.into_inner(); let did = db::get_did(id).unwrap(); HttpResponse::Ok().json(did) } async fn did_patch(d: web::Json, path: web::Path) -> impl Responder { let id = path.into_inner(); let d = d.deref(); let did = db::Did { id: id, did_number: d.did_number.clone(), target_type: DidTargetType::from_str(&d.target_type).unwrap(), target: Some(d.target.clone()), active: d.active }; db::update_did(did).unwrap(); HttpResponse::Ok().body("DID updated") } async fn did_delete(path: web::Path) -> impl Responder { let id = path.into_inner(); db::delete_did(id).unwrap(); HttpResponse::Ok().body("DID deleted.") } fn api_config(cfg: &mut web::ServiceConfig) { cfg.service( web::resource("/fs") .route(web::get().to(did_index)) .route(web::post().to(did_post)) ); cfg.service( web::resource("/fs/{id}") .route(web::get().to(did_get)) .route(web::patch().to(did_patch)) .route(web::delete().to(did_delete)) ); cfg.service( web::resource("/route_did") .route(web::post().to(route_did)) ); } #[actix_web::main] async fn main() -> std::io::Result<()> { HttpServer::new(|| { App::new() .service( web::scope("/api").configure(api_config)) }) .bind(("0.0.0.0", 3000))? .run() .await }