/* * 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; } } } }