Calculo do response_time com template ou transferência.

This commit is contained in:
2026-05-07 08:49:51 -03:00
parent a4ad969176
commit 93346a98ad

View File

@@ -126,7 +126,6 @@ fn main() -> anyhow::Result<()> {
}; };
// Get the current day in the format YYYY-MM-DD // Get the current day in the format YYYY-MM-DD
let current_date = chrono::Local::now(); let current_date = chrono::Local::now();
let formatted_date = current_date.format("%Y-%m-%d").to_string(); let formatted_date = current_date.format("%Y-%m-%d").to_string();
@@ -232,9 +231,9 @@ fn main() -> anyhow::Result<()> {
)) ))
.expect("Failed to create response_time.csv"); .expect("Failed to create response_time.csv");
} }
*/ */
// Read system prompt // Read system prompt
let prompt = std::fs::read_to_string("PROMPT.txt").unwrap(); let prompt = std::fs::read_to_string("PROMPT.txt").unwrap();
let filter_file_contents = std::fs::read_to_string("FILTER.txt").unwrap_or(String::new()); let filter_file_contents = std::fs::read_to_string("FILTER.txt").unwrap_or(String::new());
@@ -318,7 +317,6 @@ fn main() -> anyhow::Result<()> {
let template_id = message_object["is_template"] let template_id = message_object["is_template"]
.as_bool() .as_bool()
.unwrap_or(true); .unwrap_or(true);
// println!("Conteudo do template_id da mensagem {}: {:?}", pos, template_id);
let found = message.find( let found = message.find(
"Atendimento transferido para a fila [NovaNet -> Atendimento -> NOC - Clientes]", "Atendimento transferido para a fila [NovaNet -> Atendimento -> NOC - Clientes]",
); );
@@ -373,12 +371,6 @@ fn main() -> anyhow::Result<()> {
.find(&keyword.to_uppercase()) .find(&keyword.to_uppercase())
.is_some() .is_some()
}); });
/*
let found2 = message_object["is_template"]
.as_bool()
.unwrap_or(true);
let found = found1 || found2;
*/
found1 found1
}); });
@@ -390,115 +382,103 @@ fn main() -> anyhow::Result<()> {
return Some(json); return Some(json);
}); });
// Calculate the response time in seconds //INICIO do response time consideranto template ou transferência.
let response_time = filtered_chats let response_time = filtered_chats
.clone() .clone()
.map(|messages| { .map(|messages| {
let json = messages.unwrap(); let json = messages.unwrap();
let talk_histories = &json["talk_histories"]; let talk_histories = &json["talk_histories"];
let histories = talk_histories.as_array()
.expect("Wrong message type received from talk histories");
// find the bot transfer message // 1. Encontrar o primeiro gatilho na ordem cronológica (percorrendo do índice mais alto para o mais baixo)
let bot_transfer_message = talk_histories let trigger = histories.iter().enumerate().rev().find(|(_, msg)| {
.as_array() let is_template = msg["is_template"].as_bool().unwrap_or(false);
.expect("Wrong message type received from talk histories") let user = msg["user"]["name"].as_str().unwrap_or("");
.into_iter() let message = msg["message"].as_str().unwrap_or("");
.enumerate() let is_transfer = user == "PipeBot"
.filter(|(pos, message_object)| { && message.contains("Atendimento entregue da fila de espera para o agente [NOC");
let user_name = message_object["user"]["name"] is_template || is_transfer
.as_str()
.expect("Failed to decode message as string");
user_name == "PipeBot".to_string()
})
.find(|(pos, message_object)| {
let message = message_object["message"]
.as_str()
.expect("Failed to decode message as string");
let found = message.find("Atendimento entregue da fila de espera para o agente [NOC");
let is_template = message_object["is_template"]
.as_bool()
.unwrap_or(true);
found.is_some() || is_template
}); });
// Find first agent message sent after the last bot message let (trigger_pos, trigger_msg) = match trigger {
// let (pos, transfer_message) = Some(pair) => pair,
// bot_transfer_message.expect("Failed to get the transfer bot message position"); None => return "".to_string(),
let (pos, transfer_message) = match bot_transfer_message {
Some((pos, msg)) => (pos, msg),
None => return "".to_string(), // Retorna string vazia em vez de panic
}; };
let msg = talk_histories // 2. Determinar se é transferência (para escolher a referência correta)
.as_array() let is_transfer_case = {
.expect("Wrong message type received from talk histories") let user = trigger_msg["user"]["name"].as_str().unwrap_or("");
.into_iter() let message = trigger_msg["message"].as_str().unwrap_or("");
.take(pos) user == "PipeBot"
.rev() && message.contains("Atendimento entregue da fila de espera para o agente [NOC")
.filter(|message| { };
message["type"] == "out".to_string()
// && message["user"]["name"] != "PipeBot".to_string() let (ref_pos, ref_msg) = if is_transfer_case {
&& message["user"]["name"].as_str().map_or(false, |name| name.starts_with("NOC -")) // Caso transferência: referência é o próprio gatilho
(trigger_pos, trigger_msg)
} else {
// Caso template: referência é a próxima mensagem cronológica (índice trigger_pos - 1)
if trigger_pos > 0 {
match histories.get(trigger_pos - 1) {
Some(next_msg) => (trigger_pos - 1, next_msg),
None => return "".to_string(),
}
} else {
return "".to_string(); // template na última posição (sem resposta do cliente)
}
};
// 3. Procurar a primeira resposta do agente após a referência (índices menores que ref_pos)
let agent_msg = (0..ref_pos).rev()
.filter_map(|i| {
let m = &histories[i];
if m["type"].as_str() == Some("out")
&& m["user"]["name"].as_str().map_or(false, |name| name.starts_with("NOC -"))
{
Some(m)
} else {
None
}
}) })
.take(1) .take(1)
.collect_vec(); .collect::<Vec<_>>();
// Se não encontrar mensagem do agente, retorna string vazia
if msg.is_empty() { if agent_msg.is_empty() {
return "".to_string(); return "".to_string();
} }
let agent_first_message = agent_msg[0];
let agent_first_message = msg[0]; // 4. Calcular tempo entre referência e primeira resposta do agente
// Calculate time difference between bot message and agent message
let date_user_message_sent = agent_first_message["sent_at"].as_str().unwrap();
let format = "%Y-%m-%d %H:%M:%S"; let format = "%Y-%m-%d %H:%M:%S";
let t_ref = chrono::NaiveDateTime::parse_from_str(
let date_user_message_sent_parsed = ref_msg["sent_at"].as_str().unwrap(),
match chrono::NaiveDateTime::parse_from_str(date_user_message_sent, format) {
Ok(dt) => dt,
Err(e) => {
println!("Error parsing DateTime: {}", e);
panic!("Failed parsing date")
}
};
let date_transfer_message_sent_parsed = match chrono::NaiveDateTime::parse_from_str(
transfer_message["sent_at"].as_str().unwrap(),
format, format,
) { ).expect("Erro ao parsear data da referência");
Ok(dt) => dt, let t_agent = chrono::NaiveDateTime::parse_from_str(
Err(e) => { agent_first_message["sent_at"].as_str().unwrap(),
println!("Error parsing DateTime: {}", e); format,
panic!("Failed parsing date") ).expect("Erro ao parsear data do agente");
}
};
let response_time = (date_user_message_sent_parsed - date_transfer_message_sent_parsed) let response_time = (t_agent - t_ref).num_seconds() as f32;
.as_seconds_f32();
let name = agent_first_message["user"]["name"] let name = agent_first_message["user"]["name"].as_str().unwrap().to_owned();
.as_str()
.unwrap()
.to_owned();
let id = json["tracking_number"].as_str().unwrap_or("").to_owned(); let id = json["tracking_number"].as_str().unwrap_or("").to_owned();
let bot_transfer_date = date_transfer_message_sent_parsed.to_owned(); let ref_date = ref_msg["sent_at"].as_str().unwrap().to_owned();
let user_response_date = date_user_message_sent.to_owned(); let agent_date = agent_first_message["sent_at"].as_str().unwrap().to_owned();
println!(
"response_time: {}s", println!("response_time: {}s", response_time);
(date_user_message_sent_parsed - date_transfer_message_sent_parsed)
.as_seconds_f32()
);
format!( format!(
"{};{};{};{};{}", "{};{};{};{};{}",
name, id, response_time, bot_transfer_date, user_response_date name, id, response_time, ref_date, agent_date
) )
}) })
.filter(|s| !s.is_empty()) // Filtra strings vazias .filter(|s| !s.is_empty())
.reduce(|acc, e| format!("{}\n{}", acc, e)) .reduce(|acc, e| format!("{}\n{}", acc, e))
.unwrap_or("".to_string()); .unwrap_or("".to_string());
//FIM do response time considerando template ou transferência.
// return Ok(());
// Open file and write to it // Open file and write to it
let header = "NOME;ID_TALK;TEMPO DE RESPOSTA;TRANFERENCIA PELO BOT;PRIMEIRA RESPOSTA DO AGENTE"; let header = "NOME;ID_TALK;TEMPO DE RESPOSTA;TRANFERENCIA PELO BOT;PRIMEIRA RESPOSTA DO AGENTE";
let mut response_time_file = std::fs::OpenOptions::new() let mut response_time_file = std::fs::OpenOptions::new()
@@ -535,7 +515,6 @@ fn main() -> anyhow::Result<()> {
message_object["type"], message_object["type"],
message_object["user"]["name"] message_object["user"]["name"]
); );
// println!("{}", new_json_filtered);
new_json_filtered new_json_filtered
}) })
.reduce(|acc, e| format!("{acc}\n{e}")) .reduce(|acc, e| format!("{acc}\n{e}"))
@@ -551,7 +530,6 @@ fn main() -> anyhow::Result<()> {
serde_json::json!({ serde_json::json!({
"model": OLLAMA_AI_MODEL, "model": OLLAMA_AI_MODEL,
"prompt": format!("{prompt} \n{talk}"), "prompt": format!("{prompt} \n{talk}"),
// "options": serde_json::json!({"temperature": 0.1}),
"stream": false, "stream": false,
}) })
.to_string(), .to_string(),
@@ -616,12 +594,12 @@ fn main() -> anyhow::Result<()> {
// Send folder to email // Send folder to email
let recipients = "Nicolas Borges da Silva <nicolas.borges@nova.net.br>, wilson@nova.net.br"; let recipients = "nicolas.borges@nova.net.br, wilson@nova.net.br";
println!("Trying to send email... Recipients {recipients}"); println!("Trying to send email... Recipients {recipients}");
send_mail_util::send_mail_util::send_email( send_mail_util::send_mail_util::send_email(
&format!("Avaliacao atendimentos da fila NOC - Clientes do dia {formatted_day_before}"), &format!("Avaliacao atendimentos da fila NOC - Clientes do dia {formatted_day_before}"),
//&format!("Avaliacao atendimentos da fila Financeiro NVL2 do dia {formatted_day}"), //&format!("Avaliacao atendimentos da fila NOC - Clientes do dia {formatted_day}"),
&BOT_EMAIL, &BOT_EMAIL,
&BOT_EMAIL_PASSWORD, &BOT_EMAIL_PASSWORD,
recipients, recipients,