This commit is contained in:
Rafael Alves Lopes 2025-10-10 08:12:26 -03:00
parent 3208e83246
commit 3b6d78152d
9 changed files with 126 additions and 27 deletions

View File

@ -11,7 +11,7 @@ logInfo('Aplicação iniciada', {
async function main() { async function main() {
try { try {
await snServices(); await snServices();
//await glpiServices(); await glpiServices();
} catch (error) { } catch (error) {
logInfo('Erro na aplicação:', error); logInfo('Erro na aplicação:', error);
} }

View File

@ -1,10 +1,10 @@
// src/controllers/glpiController.js // src/controllers/glpiController.js
const { syncTicketsToGlpi } = require('../services/glpiTicketService'); const { syncTicketsToGlpi } = require('../services/glpiTicketService');
const { syncCommentsGlpi } = require('../services/glpiCommentService'); const { syncCommentsGlpitoSN } = require('../services/glpiCommentService');
const glpiServices = async () => { const glpiServices = async () => {
//await syncTicketsToGlpi(); //await syncTicketsToGlpi();
await syncCommentsGlpi(); await syncCommentsGlpitoSN();
} }
module.exports = { module.exports = {

View File

@ -1,9 +1,9 @@
const { fetchTicketsFromServiceNow, fetchRequestsFromServiceNow, getAllCommentsFromServiceNow } = require('../services/servicenowService'); const { fetchTicketsFromServiceNow, fetchRequestsFromServiceNow, fetchCommentsFromServiceNow } = require('../services/servicenowService');
const snServices = async () => { const snServices = async () => {
//await fetchTicketsFromServiceNow(); //await fetchTicketsFromServiceNow();
//await fetchRequestsFromServiceNow(); //await fetchRequestsFromServiceNow();
await getAllCommentsFromServiceNow(626) await fetchCommentsFromServiceNow(626)
} }
module.exports = { module.exports = {

View File

@ -27,6 +27,7 @@ class TicketSyncModel {
} }
} }
// Buscar o ID de sincronização baseado no glpi_ticket_id // Buscar o ID de sincronização baseado no glpi_ticket_id
static async getIdSyncByGlpiId(glpiTicketId) { static async getIdSyncByGlpiId(glpiTicketId) {
try { try {
@ -39,6 +40,20 @@ class TicketSyncModel {
} }
} }
// Buscar o ID de sincronização baseado no sn_ticket_id
static async getIdSyncBySnId(snTicketId) {
try {
const query = 'SELECT id FROM ticket_sync WHERE sn_ticket_id = $1';
const { rows } = await pool.query(query, [snTicketId]);
return rows[0] ? rows[0].id : null;
} catch (error) {
logError(error, `❌ Erro ao buscar ID de sincronização por GLPI ID: ${glpiTicketId}`);
throw error;
}
}
} }
/** /**
* @module TicketSyncModel * @module TicketSyncModel

View File

@ -8,6 +8,15 @@ class TicketUpdateModel {
const query = ` const query = `
INSERT INTO ticket_updates (ticket_sync_id, update_type, source_system, content, author, created_at, updated_at, source_id, destiny_id) INSERT INTO ticket_updates (ticket_sync_id, update_type, source_system, content, author, created_at, updated_at, source_id, destiny_id)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
ON CONFLICT (source_id) DO UPDATE SET
ticket_sync_id = $1,
update_type = $2,
source_system = $3,
content = $4,
author = $5,
created_at = $6,
updated_at = $7,
destiny_id = $9
RETURNING id; RETURNING id;
`; `;
const values = [ const values = [
@ -15,7 +24,7 @@ class TicketUpdateModel {
'note', 'note',
updateData.source_system, updateData.source_system,
updateData.content, updateData.content,
'Sothis', updateData.author,
updateData.created_at, updateData.created_at,
updateData.updated_at, updateData.updated_at,
updateData.source_id, updateData.source_id,
@ -30,6 +39,19 @@ class TicketUpdateModel {
} }
} }
//Buscar o ID de sincronização baseado no source_id
static async getIdSyncBySourceId(sourceId) {
try {
const query = 'SELECT id FROM ticket_updates WHERE source_id = $1';
const { rows } = await pool.query(query, [sourceId]);
return rows[0] ? rows[0].id : null;
} catch (error) {
logError(error, `❌ Erro ao buscar ID de sincronização por GLPI ID: ${sourceId}`);
throw error;
}
}
static async getByTicketSyncIdAndSourceId(ticketSyncId, sourceId) { static async getByTicketSyncIdAndSourceId(ticketSyncId, sourceId) {
try { try {
const query = ` const query = `
@ -43,11 +65,9 @@ class TicketUpdateModel {
throw error; throw error;
} }
} }
static async getCommentSync(glpiTicketId, sourceId) { static async getCommentSync(glpiTicketId, sourceId) {
const ticketSyncModel = require('./ticketSyncModel'); const ticketSyncModel = require('./ticketSyncModel');
const ticketSyncId = await ticketSyncModel.getIdSyncByGlpiId(glpiTicketId); const ticketSyncId = await TicketUpdateModel.getIdSyncBySourceId(sourceId);
if (!ticketSyncId) { if (!ticketSyncId) {
return null; return null;

View File

@ -8,7 +8,7 @@ const { existingCommentInServiceNow, syncCommentToServiceNow } = require('./serv
const { sanitizeGLPIComment } = require('../utils/commentSanitizer'); const { sanitizeGLPIComment } = require('../utils/commentSanitizer');
// Sincroniza comentários do GLPI para o Banco de Dados local // Sincroniza comentários do GLPI para o Banco de Dados local
const syncCommentsGlpi = async () => { const syncCommentsGlpitoSN = async () => {
try { try {
logInfo('🔄 Iniciando sincronização de comments do GLPI para o Service Now...'); logInfo('🔄 Iniciando sincronização de comments do GLPI para o Service Now...');
@ -52,6 +52,7 @@ const syncCommentsGlpi = async () => {
source_system: 'glpi', source_system: 'glpi',
content: sanitizedContent, // ✅ Usa o conteúdo sanitizado content: sanitizedContent, // ✅ Usa o conteúdo sanitizado
created_at: new Date(comment.date_creation), created_at: new Date(comment.date_creation),
author: 'Sothis',
updated_at: new Date(comment.date_mod), updated_at: new Date(comment.date_mod),
source_id: comment.id, source_id: comment.id,
destiny_id: commentExistsInSN.destiny_id destiny_id: commentExistsInSN.destiny_id
@ -110,6 +111,21 @@ const syncCommentsGlpi = async () => {
} }
} }
const syncCommentsSNtoGlpi = async () => {
try {
logInfo('🔄 Iniciando sincronização de comments do Service Now para o GLPI...');
}
catch (error) {
logError(error, 'ServiceNow Comments');
}
}
/** /**
* @module glpiCommentService * @module glpiCommentService
@ -120,7 +136,9 @@ const syncCommentsGlpi = async () => {
* Atualiza o status de sincronização após cada comentário processado. * Atualiza o status de sincronização após cada comentário processado.
* Inclui logging detalhado para monitorar o progresso e identificar erros durante o processo de sincronização. * Inclui logging detalhado para monitorar o progresso e identificar erros durante o processo de sincronização.
*/ */
module.exports = { module.exports = {
syncCommentsGlpi syncCommentsGlpitoSN,
syncCommentsSNtoGlpi
}; };

View File

@ -1,12 +0,0 @@
const axios = require('axios');
const apiConfig = require('../../config/apiConfig');
const TicketSnModel = require('../models/ticketSnModel');
const { logInfo, logError, logSync } = require('../utils/logger');
const syncCommentsInServiceNow = async () => {
try {
} catch (error) {
}
}

View File

@ -4,6 +4,8 @@ const apiConfig = require('../../config/apiConfig');
const TicketSnModel = require('../models/ticketSnModel'); const TicketSnModel = require('../models/ticketSnModel');
const { logInfo, logError, logSync } = require('../utils/logger'); const { logInfo, logError, logSync } = require('../utils/logger');
const fs = require('fs'); const fs = require('fs');
const TicketUpdateModel = require('../models/ticketUpdateModel');
const TicketSyncModel = require('../models/ticketSyncModel');
const fetchTicketsFromServiceNow = async () => { const fetchTicketsFromServiceNow = async () => {
try { try {
@ -202,8 +204,10 @@ const syncCommentToServiceNow = async (ticketId, comment) => {
// Deve-se atentar para a paginação da API do ServiceNow // Deve-se atentar para a paginação da API do ServiceNow
// para fins de teste, gerar um arquivo JSON com os comentários de um ticket específico // para fins de teste, gerar um arquivo JSON com os comentários de um ticket específico
const getAllCommentsFromServiceNow = async (ticketId) => { const fetchCommentsFromServiceNow = async (ticketId) => {
try { try {
console.log(`Iniciando busca de comentários do ServiceNow para o ticket SN Ticket: ${ticketId}`);
const sys_id = await getTicketSysId(ticketId); const sys_id = await getTicketSysId(ticketId);
if (!sys_id) { if (!sys_id) {
logError('sys_id não encontrado para ticket', { ticketId }); logError('sys_id não encontrado para ticket', { ticketId });
@ -256,7 +260,61 @@ const getAllCommentsFromServiceNow = async (ticketId) => {
// salvar em arquivo para análise // salvar em arquivo para análise
const filename = `servicenow_comments_ticket_${ticketId}.json`; const filename = `servicenow_comments_ticket_${ticketId}.json`;
// Salva no arquivo
fs.writeFileSync(filename, JSON.stringify(allComments, null, 2)); fs.writeFileSync(filename, JSON.stringify(allComments, null, 2));
//Trata os dados para inserir no banco intermediario apenas os tickets que não são do sys_created_by: "SOTHIS.CAOA"
const filteredComments = allComments.filter(comment => comment.sys_created_by !== 'SOTHIS.CAOA');
// Insere cada comment no banco intermediario
for (const comment of filteredComments) {
const existingComment = await TicketUpdateModel.getCommentSync(ticketId, comment.sys_id);
if (existingComment) {
logInfo(`Comentário: ${comment.sys_id} já existe no banco de dados`, { step: 3 });
continue;
} else {
console.log(comment);
const ticketSnId = await TicketSyncModel.getIdSyncBySnId(ticketId);
const commentData = {
ticket_sync_id: parseInt(ticketSnId),
source_system: 'servicenow',
content: comment.value,
created_at: new Date(comment.sys_created_on),
author: "CAOA",
updated_at: new Date(),
source_id: comment.sys_id,
destiny_id: null
};
commentInserted = await TicketUpdateModel.insert(commentData);
if (commentInserted.success) {
// Insere Glpi status como pending e SN status como synced
await TicketSyncModel.updateStatus(ticketGlpiId.id, 'pending', 'synced');
logInfo(`✅ Comentário ID ${comment.sys_id} inserido no banco! Novo ID: ${commentInserted.newId}`, { step: 4 });
} else {
logError(`❌ Erro ao inserir comentário ID ${comment.sys_id} no banco: ${commentInserted.error}`, { step: 4 });
}
if (!ticketSyncId) {
logError(`❌ TicketSyncId não encontrado para o ticket GLPI ID: ${ticketId}`, { step: 4 });
continue;
} else {
continue;
}
}
}
logInfo(`💾 Backup JSON de comentários salvo: ${filename}`, { count: allComments.length }); logInfo(`💾 Backup JSON de comentários salvo: ${filename}`, { count: allComments.length });
} catch (error) { } catch (error) {
logError(error, '🚨Falha ao buscar comentários do ServiceNow'); logError(error, '🚨Falha ao buscar comentários do ServiceNow');
@ -272,5 +330,5 @@ module.exports = {
getCommentId, getCommentId,
existingCommentInServiceNow, existingCommentInServiceNow,
syncCommentToServiceNow, syncCommentToServiceNow,
getAllCommentsFromServiceNow fetchCommentsFromServiceNow
} }