/*
* Copyright (c) 2026 RAVAPI Soluções. Todos os direitos reservados.
* www.ravapi.com
*/
using System;
using System.IO;
using System.Net;
using System.Text;
using System.Web.Script.Serialization;
namespace TechDeskAgent
{
///
/// Comunica com a API do TechDesk Pro (backend Node/Express, rotas /api/monitoramento/*).
/// Usa apenas System.Net.HttpWebRequest — sem dependências externas.
///
public class ApiClient
{
private readonly AgentConfig _config;
private readonly JavaScriptSerializer _json;
public ApiClient(AgentConfig config)
{
_config = config;
_json = new JavaScriptSerializer { MaxJsonLength = 10_000_000 };
// Aceita certificado SSL (necessário para ravapi.com HTTPS)
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
ServicePointManager.ServerCertificateValidationCallback = (s, c, ch, e) => true;
}
// ── Registro inicial do terminal ──────────────────────────────────────
public string Registrar(IdentidadeInfo identidade)
{
try
{
string url = _config.ApiUrl + "register";
string body = _json.Serialize(new
{
client_id = _config.ClientId,
hostname = identidade.Hostname,
dominio = identidade.Dominio,
sistema_op = identidade.SistemaOp,
build_os = identidade.BuildOS,
arquitetura = identidade.Arquitetura,
serial = identidade.Serial,
mac_address = identidade.MacAddress,
ip_address = identidade.IpAddress,
agent_version = AgentConfig.VERSAO
});
var resp = Post(url, body);
if (resp != null)
{
dynamic obj = _json.DeserializeObject(resp);
var dict = obj as System.Collections.Generic.Dictionary;
if (dict != null && dict.ContainsKey("token"))
return dict["token"]?.ToString();
}
}
catch (Exception ex) { Logger.Error($"Registrar: {ex.Message}"); }
return null;
}
// ── Envio de heartbeat (telemetria) ───────────────────────────────────
public bool EnviarHeartbeat(TelemetriaPayload payload)
{
try
{
string url = _config.ApiUrl + "heartbeat";
string body = _json.Serialize(payload);
var resp = Post(url, body);
if (resp == null) return false;
dynamic obj = _json.DeserializeObject(resp);
var dict = obj as System.Collections.Generic.Dictionary;
return dict != null && dict.ContainsKey("status") && dict["status"]?.ToString() == "ok";
}
catch (Exception ex) { Logger.Error($"EnviarHeartbeat: {ex.Message}"); }
return false;
}
// ── HTTP POST helper ──────────────────────────────────────────────────
private string Post(string url, string jsonBody)
{
try
{
var req = (HttpWebRequest)WebRequest.Create(url);
req.Method = "POST";
req.ContentType = "application/json";
req.Timeout = 30_000;
req.Headers.Add("X-Agent-Version", AgentConfig.VERSAO);
byte[] bytes = Encoding.UTF8.GetBytes(jsonBody);
req.ContentLength = bytes.Length;
using (var stream = req.GetRequestStream())
stream.Write(bytes, 0, bytes.Length);
using (var resp = (HttpWebResponse)req.GetResponse())
using (var reader = new StreamReader(resp.GetResponseStream(), Encoding.UTF8))
return reader.ReadToEnd();
}
catch (WebException ex)
{
if (ex.Response != null)
using (var r = new StreamReader(ex.Response.GetResponseStream()))
Logger.Error($"HTTP Error: {r.ReadToEnd()}");
else
Logger.Error($"HTTP: {ex.Message}");
return null;
}
}
}
}