#![allow(clippy::all, unused_imports, dead_code)]
use crate::{Actor, ActorBehavior, ClientBuilderExt, Message, Port};
use anyhow::{Error, Result};
use reflow_actor::{message::EncodableValue, ActorContext};
use reflow_actor_macro::actor;
use serde_json::{json, Value};
use std::collections::HashMap;
use std::time::Duration;
const BASE_URL: &str = "https://rest.nexmo.com";
const ENV_KEY: &str = "VONAGE_API_KEY";
fn apply_auth(
config: &reflow_actor::ActorConfig,
mut builder: reqwest::RequestBuilder,
) -> Result<reqwest::RequestBuilder> {
let credential = config
.get_config_or_env(ENV_KEY)
.ok_or_else(|| anyhow::anyhow!("Missing env var: {}", ENV_KEY))?;
builder = builder.query(&[("api_key", &credential)]);
Ok(builder)
}
#[actor(
VonageSendSmsActor,
inports::<100>(from, to, text),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn vonage_send_sms(context: ActorContext) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/sms/json".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout_compat(Duration::from_secs(30))
.build()?;
let mut builder = client.post(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut body = serde_json::Map::new();
if let Some(val) = inputs.get("from") {
body.insert("from".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("to") {
body.insert("to".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("text") {
body.insert("text".to_string(), val.clone().into());
}
if !body.is_empty() {
builder = builder.json(&serde_json::Value::Object(body));
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("POST /sms/json failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
VonageReadInboundSmsActor,
inports::<100>(api_key, api_secret, date, to, from, ids),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn vonage_read_inbound_sms(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/search/messages".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout_compat(Duration::from_secs(30))
.build()?;
let mut builder = client.get(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut query_pairs: Vec<(&str, String)> = Vec::new();
if let Some(val) = inputs.get("api_key") {
query_pairs.push(("api_key", super::message_to_str(val)));
}
if let Some(val) = inputs.get("api_secret") {
query_pairs.push(("api_secret", super::message_to_str(val)));
}
if let Some(val) = inputs.get("date") {
query_pairs.push(("date", super::message_to_str(val)));
}
if let Some(val) = inputs.get("to") {
query_pairs.push(("to", super::message_to_str(val)));
}
if let Some(val) = inputs.get("from") {
query_pairs.push(("from", super::message_to_str(val)));
}
if let Some(val) = inputs.get("ids") {
query_pairs.push(("ids", super::message_to_str(val)));
}
if !query_pairs.is_empty() {
builder = builder.query(&query_pairs);
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("GET /search/messages failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
VonageCreateCallActor,
inports::<100>(to, from, ncco, answer_url, answer_method, event_url, event_method, machine_detection, length_timer, ringing_timer),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn vonage_create_call(context: ActorContext) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/v1/calls".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout_compat(Duration::from_secs(30))
.build()?;
let mut builder = client.post(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut body = serde_json::Map::new();
if let Some(val) = inputs.get("to") {
body.insert("to".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("from") {
body.insert("from".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("ncco") {
body.insert("ncco".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("answer_url") {
body.insert("answer_url".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("answer_method") {
body.insert("answer_method".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("event_url") {
body.insert("event_url".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("event_method") {
body.insert("event_method".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("machine_detection") {
body.insert("machine_detection".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("length_timer") {
body.insert("length_timer".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("ringing_timer") {
body.insert("ringing_timer".to_string(), val.clone().into());
}
if !body.is_empty() {
builder = builder.json(&serde_json::Value::Object(body));
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("POST /v1/calls failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
VonageListCallsActor,
inports::<100>(status, date_start, date_end, page_size, record_index, order, conversation_uuid),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn vonage_list_calls(context: ActorContext) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/v1/calls".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout_compat(Duration::from_secs(30))
.build()?;
let mut builder = client.get(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut query_pairs: Vec<(&str, String)> = Vec::new();
if let Some(val) = inputs.get("status") {
query_pairs.push(("status", super::message_to_str(val)));
}
if let Some(val) = inputs.get("date_start") {
query_pairs.push(("date_start", super::message_to_str(val)));
}
if let Some(val) = inputs.get("date_end") {
query_pairs.push(("date_end", super::message_to_str(val)));
}
if let Some(val) = inputs.get("page_size") {
query_pairs.push(("page_size", super::message_to_str(val)));
}
if let Some(val) = inputs.get("record_index") {
query_pairs.push(("record_index", super::message_to_str(val)));
}
if let Some(val) = inputs.get("order") {
query_pairs.push(("order", super::message_to_str(val)));
}
if let Some(val) = inputs.get("conversation_uuid") {
query_pairs.push(("conversation_uuid", super::message_to_str(val)));
}
if !query_pairs.is_empty() {
builder = builder.query(&query_pairs);
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("GET /v1/calls failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
VonageReadCallActor,
inports::<100>(uuid),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn vonage_read_call(context: ActorContext) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let mut endpoint = "/v1/calls/{uuid}".to_string();
if let Some(val) = inputs.get("uuid") {
endpoint = endpoint.replace("{{uuid}}", &super::message_to_str(val));
}
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout_compat(Duration::from_secs(30))
.build()?;
let mut builder = client.get(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("GET /v1/calls/{{uuid}} failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
VonageUpdateCallActor,
inports::<100>(uuid, action, destination),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn vonage_update_call(context: ActorContext) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let mut endpoint = "/v1/calls/{uuid}".to_string();
if let Some(val) = inputs.get("uuid") {
endpoint = endpoint.replace("{{uuid}}", &super::message_to_str(val));
}
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout_compat(Duration::from_secs(30))
.build()?;
let mut builder = client.put(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut body = serde_json::Map::new();
if let Some(val) = inputs.get("action") {
body.insert("action".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("destination") {
body.insert("destination".to_string(), val.clone().into());
}
if !body.is_empty() {
builder = builder.json(&serde_json::Value::Object(body));
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("PUT /v1/calls/{{uuid}} failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
VonageReadCallRecordingActor,
inports::<100>(uuid),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn vonage_read_call_recording(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let mut endpoint = "/v1/calls/{uuid}/stream".to_string();
if let Some(val) = inputs.get("uuid") {
endpoint = endpoint.replace("{{uuid}}", &super::message_to_str(val));
}
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout_compat(Duration::from_secs(30))
.build()?;
let mut builder = client.get(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("GET /v1/calls/{{uuid}}/stream failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
VonageStartCallStreamActor,
inports::<100>(uuid, stream_url, loop_, level),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn vonage_start_call_stream(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let mut endpoint = "/v1/calls/{uuid}/stream".to_string();
if let Some(val) = inputs.get("uuid") {
endpoint = endpoint.replace("{{uuid}}", &super::message_to_str(val));
}
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout_compat(Duration::from_secs(30))
.build()?;
let mut builder = client.put(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut body = serde_json::Map::new();
if let Some(val) = inputs.get("stream_url") {
body.insert("stream_url".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("loop_") {
body.insert("loop".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("level") {
body.insert("level".to_string(), val.clone().into());
}
if !body.is_empty() {
builder = builder.json(&serde_json::Value::Object(body));
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("PUT /v1/calls/{{uuid}}/stream failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
VonageStopCallStreamActor,
inports::<100>(uuid),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn vonage_stop_call_stream(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let mut endpoint = "/v1/calls/{uuid}/stream".to_string();
if let Some(val) = inputs.get("uuid") {
endpoint = endpoint.replace("{{uuid}}", &super::message_to_str(val));
}
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout_compat(Duration::from_secs(30))
.build()?;
let mut builder = client.delete(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("DELETE /v1/calls/{{uuid}}/stream failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
VonageStartCallTtsActor,
inports::<100>(uuid, text, voice_name, loop_, level, language, style),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn vonage_start_call_tts(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let mut endpoint = "/v1/calls/{uuid}/talk".to_string();
if let Some(val) = inputs.get("uuid") {
endpoint = endpoint.replace("{{uuid}}", &super::message_to_str(val));
}
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout_compat(Duration::from_secs(30))
.build()?;
let mut builder = client.put(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut body = serde_json::Map::new();
if let Some(val) = inputs.get("text") {
body.insert("text".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("voice_name") {
body.insert("voice_name".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("loop_") {
body.insert("loop".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("level") {
body.insert("level".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("language") {
body.insert("language".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("style") {
body.insert("style".to_string(), val.clone().into());
}
if !body.is_empty() {
builder = builder.json(&serde_json::Value::Object(body));
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("PUT /v1/calls/{{uuid}}/talk failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
VonageStopCallTtsActor,
inports::<100>(uuid),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn vonage_stop_call_tts(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let mut endpoint = "/v1/calls/{uuid}/talk".to_string();
if let Some(val) = inputs.get("uuid") {
endpoint = endpoint.replace("{{uuid}}", &super::message_to_str(val));
}
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout_compat(Duration::from_secs(30))
.build()?;
let mut builder = client.delete(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("DELETE /v1/calls/{{uuid}}/talk failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
VonageStartCallDtmfActor,
inports::<100>(uuid, digits),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn vonage_start_call_dtmf(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let mut endpoint = "/v1/calls/{uuid}/dtmf".to_string();
if let Some(val) = inputs.get("uuid") {
endpoint = endpoint.replace("{{uuid}}", &super::message_to_str(val));
}
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout_compat(Duration::from_secs(30))
.build()?;
let mut builder = client.put(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut body = serde_json::Map::new();
if let Some(val) = inputs.get("digits") {
body.insert("digits".to_string(), val.clone().into());
}
if !body.is_empty() {
builder = builder.json(&serde_json::Value::Object(body));
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("PUT /v1/calls/{{uuid}}/dtmf failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
VonageSendMessageActor,
inports::<100>(message_type, to, from, channel, text, image, audio, video, file, template, client_ref, webhook_url),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn vonage_send_message(context: ActorContext) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/v1/messages".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout_compat(Duration::from_secs(30))
.build()?;
let mut builder = client.post(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut body = serde_json::Map::new();
if let Some(val) = inputs.get("message_type") {
body.insert("message_type".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("to") {
body.insert("to".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("from") {
body.insert("from".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("channel") {
body.insert("channel".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("text") {
body.insert("text".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("image") {
body.insert("image".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("audio") {
body.insert("audio".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("video") {
body.insert("video".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("file") {
body.insert("file".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("template") {
body.insert("template".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("client_ref") {
body.insert("client_ref".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("webhook_url") {
body.insert("webhook_url".to_string(), val.clone().into());
}
if !body.is_empty() {
builder = builder.json(&serde_json::Value::Object(body));
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("POST /v1/messages failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
VonageCreateVerifyRequestActor,
inports::<100>(api_key, api_secret, number, brand, sender_id, code_length, locale, pin_expiry, workflow_id),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn vonage_create_verify_request(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/verify/json".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout_compat(Duration::from_secs(30))
.build()?;
let mut builder = client.post(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut body = serde_json::Map::new();
if let Some(val) = inputs.get("api_key") {
body.insert("api_key".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("api_secret") {
body.insert("api_secret".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("number") {
body.insert("number".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("brand") {
body.insert("brand".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("sender_id") {
body.insert("sender_id".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("code_length") {
body.insert("code_length".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("locale") {
body.insert("locale".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("pin_expiry") {
body.insert("pin_expiry".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("workflow_id") {
body.insert("workflow_id".to_string(), val.clone().into());
}
if !body.is_empty() {
builder = builder.json(&serde_json::Value::Object(body));
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("POST /verify/json failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
VonageCreateVerifyCheckActor,
inports::<100>(api_key, api_secret, request_id, code),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn vonage_create_verify_check(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/verify/check/json".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout_compat(Duration::from_secs(30))
.build()?;
let mut builder = client.post(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut body = serde_json::Map::new();
if let Some(val) = inputs.get("api_key") {
body.insert("api_key".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("api_secret") {
body.insert("api_secret".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("request_id") {
body.insert("request_id".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("code") {
body.insert("code".to_string(), val.clone().into());
}
if !body.is_empty() {
builder = builder.json(&serde_json::Value::Object(body));
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("POST /verify/check/json failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
VonageDeleteVerifyRequestActor,
inports::<100>(api_key, api_secret, request_id, cmd),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn vonage_delete_verify_request(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/verify/control/json".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout_compat(Duration::from_secs(30))
.build()?;
let mut builder = client.post(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut body = serde_json::Map::new();
if let Some(val) = inputs.get("api_key") {
body.insert("api_key".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("api_secret") {
body.insert("api_secret".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("request_id") {
body.insert("request_id".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("cmd") {
body.insert("cmd".to_string(), val.clone().into());
}
if !body.is_empty() {
builder = builder.json(&serde_json::Value::Object(body));
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("POST /verify/control/json failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
VonageReadVerifyRequestActor,
inports::<100>(api_key, api_secret, request_id, request_ids),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn vonage_read_verify_request(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/verify/search/json".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout_compat(Duration::from_secs(30))
.build()?;
let mut builder = client.get(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut query_pairs: Vec<(&str, String)> = Vec::new();
if let Some(val) = inputs.get("api_key") {
query_pairs.push(("api_key", super::message_to_str(val)));
}
if let Some(val) = inputs.get("api_secret") {
query_pairs.push(("api_secret", super::message_to_str(val)));
}
if let Some(val) = inputs.get("request_id") {
query_pairs.push(("request_id", super::message_to_str(val)));
}
if let Some(val) = inputs.get("request_ids") {
query_pairs.push(("request_ids", super::message_to_str(val)));
}
if !query_pairs.is_empty() {
builder = builder.query(&query_pairs);
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("GET /verify/search/json failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
VonageReadNumberInsightActor,
inports::<100>(api_key, api_secret, number, country),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn vonage_read_number_insight(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/ni/basic/json".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout_compat(Duration::from_secs(30))
.build()?;
let mut builder = client.get(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut query_pairs: Vec<(&str, String)> = Vec::new();
if let Some(val) = inputs.get("api_key") {
query_pairs.push(("api_key", super::message_to_str(val)));
}
if let Some(val) = inputs.get("api_secret") {
query_pairs.push(("api_secret", super::message_to_str(val)));
}
if let Some(val) = inputs.get("number") {
query_pairs.push(("number", super::message_to_str(val)));
}
if let Some(val) = inputs.get("country") {
query_pairs.push(("country", super::message_to_str(val)));
}
if !query_pairs.is_empty() {
builder = builder.query(&query_pairs);
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("GET /ni/basic/json failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
VonageReadNumberInsightStandardActor,
inports::<100>(api_key, api_secret, number, country, cnam),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn vonage_read_number_insight_standard(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/ni/standard/json".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout_compat(Duration::from_secs(30))
.build()?;
let mut builder = client.get(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut query_pairs: Vec<(&str, String)> = Vec::new();
if let Some(val) = inputs.get("api_key") {
query_pairs.push(("api_key", super::message_to_str(val)));
}
if let Some(val) = inputs.get("api_secret") {
query_pairs.push(("api_secret", super::message_to_str(val)));
}
if let Some(val) = inputs.get("number") {
query_pairs.push(("number", super::message_to_str(val)));
}
if let Some(val) = inputs.get("country") {
query_pairs.push(("country", super::message_to_str(val)));
}
if let Some(val) = inputs.get("cnam") {
query_pairs.push(("cnam", super::message_to_str(val)));
}
if !query_pairs.is_empty() {
builder = builder.query(&query_pairs);
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("GET /ni/standard/json failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
VonageReadNumberInsightAdvancedActor,
inports::<100>(api_key, api_secret, number, country, cnam, ip),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn vonage_read_number_insight_advanced(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/ni/advanced/json".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout_compat(Duration::from_secs(30))
.build()?;
let mut builder = client.get(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut query_pairs: Vec<(&str, String)> = Vec::new();
if let Some(val) = inputs.get("api_key") {
query_pairs.push(("api_key", super::message_to_str(val)));
}
if let Some(val) = inputs.get("api_secret") {
query_pairs.push(("api_secret", super::message_to_str(val)));
}
if let Some(val) = inputs.get("number") {
query_pairs.push(("number", super::message_to_str(val)));
}
if let Some(val) = inputs.get("country") {
query_pairs.push(("country", super::message_to_str(val)));
}
if let Some(val) = inputs.get("cnam") {
query_pairs.push(("cnam", super::message_to_str(val)));
}
if let Some(val) = inputs.get("ip") {
query_pairs.push(("ip", super::message_to_str(val)));
}
if !query_pairs.is_empty() {
builder = builder.query(&query_pairs);
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("GET /ni/advanced/json failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
VonageListNumbersActor,
inports::<100>(api_key, api_secret, index, size, pattern, search_pattern),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn vonage_list_numbers(context: ActorContext) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/account/numbers".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout_compat(Duration::from_secs(30))
.build()?;
let mut builder = client.get(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut query_pairs: Vec<(&str, String)> = Vec::new();
if let Some(val) = inputs.get("api_key") {
query_pairs.push(("api_key", super::message_to_str(val)));
}
if let Some(val) = inputs.get("api_secret") {
query_pairs.push(("api_secret", super::message_to_str(val)));
}
if let Some(val) = inputs.get("index") {
query_pairs.push(("index", super::message_to_str(val)));
}
if let Some(val) = inputs.get("size") {
query_pairs.push(("size", super::message_to_str(val)));
}
if let Some(val) = inputs.get("pattern") {
query_pairs.push(("pattern", super::message_to_str(val)));
}
if let Some(val) = inputs.get("search_pattern") {
query_pairs.push(("search_pattern", super::message_to_str(val)));
}
if !query_pairs.is_empty() {
builder = builder.query(&query_pairs);
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("GET /account/numbers failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
VonageSearchAvailableNumbersActor,
inports::<100>(api_key, api_secret, country, type_, pattern, search_pattern, features, size, index),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn vonage_search_available_numbers(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/number/search".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout_compat(Duration::from_secs(30))
.build()?;
let mut builder = client.get(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut query_pairs: Vec<(&str, String)> = Vec::new();
if let Some(val) = inputs.get("api_key") {
query_pairs.push(("api_key", super::message_to_str(val)));
}
if let Some(val) = inputs.get("api_secret") {
query_pairs.push(("api_secret", super::message_to_str(val)));
}
if let Some(val) = inputs.get("country") {
query_pairs.push(("country", super::message_to_str(val)));
}
if let Some(val) = inputs.get("type_") {
query_pairs.push(("type", super::message_to_str(val)));
}
if let Some(val) = inputs.get("pattern") {
query_pairs.push(("pattern", super::message_to_str(val)));
}
if let Some(val) = inputs.get("search_pattern") {
query_pairs.push(("search_pattern", super::message_to_str(val)));
}
if let Some(val) = inputs.get("features") {
query_pairs.push(("features", super::message_to_str(val)));
}
if let Some(val) = inputs.get("size") {
query_pairs.push(("size", super::message_to_str(val)));
}
if let Some(val) = inputs.get("index") {
query_pairs.push(("index", super::message_to_str(val)));
}
if !query_pairs.is_empty() {
builder = builder.query(&query_pairs);
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("GET /number/search failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
VonageCreateNumberActor,
inports::<100>(api_key, api_secret, country, msisdn),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn vonage_create_number(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/number/buy".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout_compat(Duration::from_secs(30))
.build()?;
let mut builder = client.post(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut body = serde_json::Map::new();
if let Some(val) = inputs.get("api_key") {
body.insert("api_key".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("api_secret") {
body.insert("api_secret".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("country") {
body.insert("country".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("msisdn") {
body.insert("msisdn".to_string(), val.clone().into());
}
if !body.is_empty() {
builder = builder.json(&serde_json::Value::Object(body));
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("POST /number/buy failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
VonageDeleteNumberActor,
inports::<100>(api_key, api_secret, country, msisdn),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn vonage_delete_number(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/number/cancel".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout_compat(Duration::from_secs(30))
.build()?;
let mut builder = client.post(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut body = serde_json::Map::new();
if let Some(val) = inputs.get("api_key") {
body.insert("api_key".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("api_secret") {
body.insert("api_secret".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("country") {
body.insert("country".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("msisdn") {
body.insert("msisdn".to_string(), val.clone().into());
}
if !body.is_empty() {
builder = builder.json(&serde_json::Value::Object(body));
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("POST /number/cancel failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
VonageUpdateNumberActor,
inports::<100>(api_key, api_secret, country, msisdn, moHttpUrl, voiceCallbackType, voiceCallbackValue, voiceStatusCallback),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn vonage_update_number(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/number/update".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout_compat(Duration::from_secs(30))
.build()?;
let mut builder = client.post(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut body = serde_json::Map::new();
if let Some(val) = inputs.get("api_key") {
body.insert("api_key".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("api_secret") {
body.insert("api_secret".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("country") {
body.insert("country".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("msisdn") {
body.insert("msisdn".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("moHttpUrl") {
body.insert("moHttpUrl".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("voiceCallbackType") {
body.insert("voiceCallbackType".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("voiceCallbackValue") {
body.insert("voiceCallbackValue".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("voiceStatusCallback") {
body.insert("voiceStatusCallback".to_string(), val.clone().into());
}
if !body.is_empty() {
builder = builder.json(&serde_json::Value::Object(body));
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("POST /number/update failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
VonageReadAccountActor,
inports::<100>(api_key, api_secret),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn vonage_read_account(context: ActorContext) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/account/get-balance".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout_compat(Duration::from_secs(30))
.build()?;
let mut builder = client.get(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut query_pairs: Vec<(&str, String)> = Vec::new();
if let Some(val) = inputs.get("api_key") {
query_pairs.push(("api_key", super::message_to_str(val)));
}
if let Some(val) = inputs.get("api_secret") {
query_pairs.push(("api_secret", super::message_to_str(val)));
}
if !query_pairs.is_empty() {
builder = builder.query(&query_pairs);
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("GET /account/get-balance failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
VonageReadAccountSettingsActor,
inports::<100>(api_key, api_secret),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn vonage_read_account_settings(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/account/settings".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout_compat(Duration::from_secs(30))
.build()?;
let mut builder = client.get(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut query_pairs: Vec<(&str, String)> = Vec::new();
if let Some(val) = inputs.get("api_key") {
query_pairs.push(("api_key", super::message_to_str(val)));
}
if let Some(val) = inputs.get("api_secret") {
query_pairs.push(("api_secret", super::message_to_str(val)));
}
if !query_pairs.is_empty() {
builder = builder.query(&query_pairs);
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("GET /account/settings failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
VonageUpdateAccountSettingsActor,
inports::<100>(api_key, api_secret, moCallBackUrl, drCallBackUrl),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn vonage_update_account_settings(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/account/settings".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout_compat(Duration::from_secs(30))
.build()?;
let mut builder = client.post(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut body = serde_json::Map::new();
if let Some(val) = inputs.get("api_key") {
body.insert("api_key".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("api_secret") {
body.insert("api_secret".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("moCallBackUrl") {
body.insert("moCallBackUrl".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("drCallBackUrl") {
body.insert("drCallBackUrl".to_string(), val.clone().into());
}
if !body.is_empty() {
builder = builder.json(&serde_json::Value::Object(body));
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("POST /account/settings failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
VonageCreateApplicationActor,
inports::<100>(name, capabilities),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn vonage_create_application(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/v2/applications".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout_compat(Duration::from_secs(30))
.build()?;
let mut builder = client.post(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut body = serde_json::Map::new();
if let Some(val) = inputs.get("name") {
body.insert("name".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("capabilities") {
body.insert("capabilities".to_string(), val.clone().into());
}
if !body.is_empty() {
builder = builder.json(&serde_json::Value::Object(body));
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("POST /v2/applications failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
VonageListApplicationsActor,
inports::<100>(page_size, page),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn vonage_list_applications(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/v2/applications".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout_compat(Duration::from_secs(30))
.build()?;
let mut builder = client.get(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut query_pairs: Vec<(&str, String)> = Vec::new();
if let Some(val) = inputs.get("page_size") {
query_pairs.push(("page_size", super::message_to_str(val)));
}
if let Some(val) = inputs.get("page") {
query_pairs.push(("page", super::message_to_str(val)));
}
if !query_pairs.is_empty() {
builder = builder.query(&query_pairs);
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("GET /v2/applications failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
VonageReadApplicationActor,
inports::<100>(application_id),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn vonage_read_application(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let mut endpoint = "/v2/applications/{application_id}".to_string();
if let Some(val) = inputs.get("application_id") {
endpoint = endpoint.replace("{{application_id}}", &super::message_to_str(val));
}
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout_compat(Duration::from_secs(30))
.build()?;
let mut builder = client.get(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(
format!("GET /v2/applications/{{application_id}} failed: {}", e).into(),
),
);
}
}
Ok(output)
}
#[actor(
VonageUpdateApplicationActor,
inports::<100>(application_id, name, capabilities),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn vonage_update_application(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let mut endpoint = "/v2/applications/{application_id}".to_string();
if let Some(val) = inputs.get("application_id") {
endpoint = endpoint.replace("{{application_id}}", &super::message_to_str(val));
}
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout_compat(Duration::from_secs(30))
.build()?;
let mut builder = client.put(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut body = serde_json::Map::new();
if let Some(val) = inputs.get("name") {
body.insert("name".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("capabilities") {
body.insert("capabilities".to_string(), val.clone().into());
}
if !body.is_empty() {
builder = builder.json(&serde_json::Value::Object(body));
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(
format!("PUT /v2/applications/{{application_id}} failed: {}", e).into(),
),
);
}
}
Ok(output)
}
#[actor(
VonageDeleteApplicationActor,
inports::<100>(application_id),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn vonage_delete_application(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let mut endpoint = "/v2/applications/{application_id}".to_string();
if let Some(val) = inputs.get("application_id") {
endpoint = endpoint.replace("{{application_id}}", &super::message_to_str(val));
}
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout_compat(Duration::from_secs(30))
.build()?;
let mut builder = client.delete(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(
format!("DELETE /v2/applications/{{application_id}} failed: {}", e).into(),
),
);
}
}
Ok(output)
}
#[actor(
VonageCreateConversationActor,
inports::<100>(name, display_name, image_url, properties),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn vonage_create_conversation(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/v1/conversations".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout_compat(Duration::from_secs(30))
.build()?;
let mut builder = client.post(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut body = serde_json::Map::new();
if let Some(val) = inputs.get("name") {
body.insert("name".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("display_name") {
body.insert("display_name".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("image_url") {
body.insert("image_url".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("properties") {
body.insert("properties".to_string(), val.clone().into());
}
if !body.is_empty() {
builder = builder.json(&serde_json::Value::Object(body));
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("POST /v1/conversations failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
VonageListConversationsActor,
inports::<100>(date_start, date_end, page_size, record_index, order),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn vonage_list_conversations(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/v1/conversations".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout_compat(Duration::from_secs(30))
.build()?;
let mut builder = client.get(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut query_pairs: Vec<(&str, String)> = Vec::new();
if let Some(val) = inputs.get("date_start") {
query_pairs.push(("date_start", super::message_to_str(val)));
}
if let Some(val) = inputs.get("date_end") {
query_pairs.push(("date_end", super::message_to_str(val)));
}
if let Some(val) = inputs.get("page_size") {
query_pairs.push(("page_size", super::message_to_str(val)));
}
if let Some(val) = inputs.get("record_index") {
query_pairs.push(("record_index", super::message_to_str(val)));
}
if let Some(val) = inputs.get("order") {
query_pairs.push(("order", super::message_to_str(val)));
}
if !query_pairs.is_empty() {
builder = builder.query(&query_pairs);
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("GET /v1/conversations failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
VonageReadConversationActor,
inports::<100>(conversation_id),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn vonage_read_conversation(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let mut endpoint = "/v1/conversations/{conversation_id}".to_string();
if let Some(val) = inputs.get("conversation_id") {
endpoint = endpoint.replace("{{conversation_id}}", &super::message_to_str(val));
}
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout_compat(Duration::from_secs(30))
.build()?;
let mut builder = client.get(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(
format!("GET /v1/conversations/{{conversation_id}} failed: {}", e).into(),
),
);
}
}
Ok(output)
}
#[actor(
VonageDeleteConversationActor,
inports::<100>(conversation_id),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn vonage_delete_conversation(
context: ActorContext,
) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let mut endpoint = "/v1/conversations/{conversation_id}".to_string();
if let Some(val) = inputs.get("conversation_id") {
endpoint = endpoint.replace("{{conversation_id}}", &super::message_to_str(val));
}
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout_compat(Duration::from_secs(30))
.build()?;
let mut builder = client.delete(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(
format!("DELETE /v1/conversations/{{conversation_id}} failed: {}", e).into(),
),
);
}
}
Ok(output)
}
#[actor(
VonageCreateUserActor,
inports::<100>(name, display_name, image_url, channels),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn vonage_create_user(context: ActorContext) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/v1/users".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout_compat(Duration::from_secs(30))
.build()?;
let mut builder = client.post(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut body = serde_json::Map::new();
if let Some(val) = inputs.get("name") {
body.insert("name".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("display_name") {
body.insert("display_name".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("image_url") {
body.insert("image_url".to_string(), val.clone().into());
}
if let Some(val) = inputs.get("channels") {
body.insert("channels".to_string(), val.clone().into());
}
if !body.is_empty() {
builder = builder.json(&serde_json::Value::Object(body));
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("POST /v1/users failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
VonageListUsersActor,
inports::<100>(page_size, record_index, order),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn vonage_list_users(context: ActorContext) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let endpoint = "/v1/users".to_string();
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout_compat(Duration::from_secs(30))
.build()?;
let mut builder = client.get(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut query_pairs: Vec<(&str, String)> = Vec::new();
if let Some(val) = inputs.get("page_size") {
query_pairs.push(("page_size", super::message_to_str(val)));
}
if let Some(val) = inputs.get("record_index") {
query_pairs.push(("record_index", super::message_to_str(val)));
}
if let Some(val) = inputs.get("order") {
query_pairs.push(("order", super::message_to_str(val)));
}
if !query_pairs.is_empty() {
builder = builder.query(&query_pairs);
}
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("GET /v1/users failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
VonageReadUserActor,
inports::<100>(user_id),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn vonage_read_user(context: ActorContext) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let mut endpoint = "/v1/users/{user_id}".to_string();
if let Some(val) = inputs.get("user_id") {
endpoint = endpoint.replace("{{user_id}}", &super::message_to_str(val));
}
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout_compat(Duration::from_secs(30))
.build()?;
let mut builder = client.get(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("GET /v1/users/{{user_id}} failed: {}", e).into()),
);
}
}
Ok(output)
}
#[actor(
VonageDeleteUserActor,
inports::<100>(user_id),
outports::<50>(response, error),
state(MemoryState)
)]
pub async fn vonage_delete_user(context: ActorContext) -> Result<HashMap<String, Message>, Error> {
let inputs = context.get_payload();
let actor_config = context.get_config();
let mut endpoint = "/v1/users/{user_id}".to_string();
if let Some(val) = inputs.get("user_id") {
endpoint = endpoint.replace("{{user_id}}", &super::message_to_str(val));
}
let url = format!("{}{}", BASE_URL.trim_end_matches('/'), endpoint);
let client = reqwest::Client::builder()
.timeout_compat(Duration::from_secs(30))
.build()?;
let mut builder = client.delete(&url);
builder = builder.header("Content-Type", "application/json");
builder = apply_auth(actor_config, builder)?;
let mut output = HashMap::new();
match builder.send().await {
Ok(resp) => {
let status = resp.status().as_u16();
let headers: HashMap<String, String> = resp
.headers()
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|val| (k.to_string(), val.to_string())))
.collect();
let body_text = resp.text().await.unwrap_or_default();
let body_value: Value =
serde_json::from_str(&body_text).unwrap_or(Value::String(body_text));
output.insert(
"response".to_string(),
Message::object(EncodableValue::from(json!({
"status": status,
"headers": headers,
"body": body_value,
}))),
);
}
Err(e) => {
output.insert(
"error".to_string(),
Message::Error(format!("DELETE /v1/users/{{user_id}} failed: {}", e).into()),
);
}
}
Ok(output)
}