2025-09-23 21:01:01 -03:00
// src/services/servicenowService.js
2025-08-30 19:04:35 -03:00
const axios = require ( 'axios' ) ;
2025-09-03 11:13:23 -03:00
const apiConfig = require ( '../../config/apiConfig' ) ;
const fs = require ( 'fs' ) ;
2025-09-05 20:28:15 -03:00
const TicketSnModel = require ( '../models/ticketSnModel' ) ;
const { logInfo , logError , logSync } = require ( '../utils/logger' ) ;
2025-09-25 15:59:52 -03:00
const TicketUpdateModel = require ( '../models/ticketUpdateModel' ) ;
2025-08-30 19:04:35 -03:00
2025-09-03 11:13:23 -03:00
const fetchTicketsFromServiceNow = async ( ) => {
2025-08-30 19:04:35 -03:00
try {
2025-09-05 20:28:15 -03:00
logInfo ( '📡 Buscando incidentes do ServiceNow...' , { service : 'servicenow' } ) ;
2025-09-03 21:40:04 -03:00
2025-09-03 16:11:30 -03:00
const ticketsResponse = await axios . get ( apiConfig . snIncidentConfig . baseUrl , {
auth : apiConfig . servicenowAuthentication . auth
2025-09-03 11:13:23 -03:00
} ) ;
2025-09-05 20:28:15 -03:00
// comentado para evitar muitos arquivos
2025-09-15 20:55:19 -03:00
//fs.writeFileSync('servicenow_tickets.json', JSON.stringify(ticketsResponse.data, null, 2));
2025-09-05 20:28:15 -03:00
//logInfo('💾 Backup JSON de incidentes salvo', { count: ticketsResponse.data.result.length });
2025-09-03 21:40:04 -03:00
// Salvar os tickets no banco de dados
2025-09-05 20:28:15 -03:00
logInfo ( '💾 Iniciando salvamento de incidentes no banco...' ) ;
2025-09-03 21:40:04 -03:00
for ( const ticket of ticketsResponse . data . result ) {
2025-09-05 20:28:15 -03:00
await TicketSnModel . saveTicket ( ticket , 'incidente' ) ;
2025-09-03 21:40:04 -03:00
}
2025-09-05 20:28:15 -03:00
logSync ( 'ServiceNow' , ticketsResponse . data . result . length , 'incidentes' ) ;
2025-09-03 21:40:04 -03:00
2025-09-03 16:11:30 -03:00
} catch ( error ) {
2025-09-05 20:28:15 -03:00
logError ( error , 'SERVICE NOW Tickets' ) ;
2025-09-03 16:11:30 -03:00
}
}
const fetchRequestsFromServiceNow = async ( ) => {
try {
2025-09-05 20:28:15 -03:00
logInfo ( '📡 Buscando requisições do ServiceNow...' , { service : 'servicenow' } ) ;
2025-09-03 16:11:30 -03:00
const requestsResponse = await axios . get ( apiConfig . snRequestConfig . baseUrl , {
auth : apiConfig . servicenowAuthentication . auth
} ) ;
2025-09-05 20:28:15 -03:00
// Comentado para evitar muitos arquivos
2025-09-15 20:55:19 -03:00
//fs.writeFileSync('servicenow_requests.json', JSON.stringify(requestsResponse.data, null, 2));
2025-09-05 20:28:15 -03:00
//logInfo('💾 Backup JSON de requisições salvo', { count: requestsResponse.data.result.length });
2025-09-03 16:11:30 -03:00
2025-09-05 20:28:15 -03:00
// Salvar as requisições no banco de dados
logInfo ( '💾 Iniciando salvamento de requisições no banco...' ) ;
2025-09-03 21:40:04 -03:00
for ( const request of requestsResponse . data . result ) {
2025-09-05 20:28:15 -03:00
await TicketSnModel . saveTicket ( request , 'requisicao' ) ;
2025-09-03 21:40:04 -03:00
}
2025-09-05 20:28:15 -03:00
logSync ( 'ServiceNow' , requestsResponse . data . result . length , 'requisições' ) ;
2025-09-03 21:40:04 -03:00
2025-08-30 19:04:35 -03:00
} catch ( error ) {
2025-09-05 20:28:15 -03:00
logError ( error , 'SERVICE NOW Requests' ) ;
2025-08-30 19:04:35 -03:00
}
2025-09-03 11:13:23 -03:00
}
2025-08-30 19:04:35 -03:00
2025-09-25 15:59:52 -03:00
// Função para obter o sys_id de um ticket pela tabela de sincronização do banco de dados local
const getTicketSysId = async ( ticketNumber ) => {
try {
const ticket = await TicketSnModel . findByTicketNumber ( ticketNumber ) ;
return ticket . sys _id ;
} catch ( error ) {
logError ( error , '🚨Falha ao obter sys_id do ticket' ) ;
return null ;
}
}
// Função para obter o código de um comentário dentro de um ticket do ServiceNow
const getCommentId = async ( sysId , comment ) => {
try {
// Exemplo de requisição GET para buscar comentários:
// GET https://SEU_INSTANCE.service-now.com/api/now/table/sys_journal_field?sysparm_query=name=incident^element=comments^element_id={SYS_ID_DO_INCIDENTE}&sysparm_fields=sys_id,sys_created_on,sys_created_by,value&sysparm_orderby_desc=sys_created_on&sysparm_limit=1&sysparm_orderby_desc=sys_created_on&sysparm_limit=1
const url = ` ${ apiConfig . snTableJournalConfig . baseUrl } ?sysparm_query=name=incident^element=comments^element_id= ${ sysId } &sysparm_fields=sys_id,sys_created_on,sys_created_by,value&sysparm_orderby_desc=sys_created_on&sysparm_limit=1 ` ;
const response = await axios . get ( url , {
auth : apiConfig . servicenowAuthentication . auth
} ) ;
for ( const entry of response . data . result ) {
if ( entry . value . includes ( comment ) ) {
return entry . sys _id ;
} else {
logInfo ( 'Comentário não encontrado no ticket' , { sysId } ) ;
}
}
} catch ( error ) {
logError ( error , '🚨Falha ao obter ID do comentário no ServiceNow' ) ;
return null ;
}
}
// Função para criar um comentário em um ticket no ServiceNow
const createCommentInServiceNow = async ( sysId , comment ) => {
try {
// Exemplo de requisição PATCH para atualizar um ticket:
// curl -u user:pass \
// -H "Content-Type: application/json" \
// -X PATCH "https://SEU_INSTANCE.service-now.com/api/now/table/incident/{SYS_ID_DO_INCIDENTE}" \
// -d '{"comments":"Estamos analisando seu chamado. Retorno em breve."}'
const url = ` ${ apiConfig . snTableIncidentConfig . baseUrl } ${ sysId } ` ;
const payload = {
comments : comment
} ;
await axios . patch ( url , payload , {
auth : apiConfig . servicenowAuthentication . auth
} ) ;
logInfo ( '💬 Comentário criado com sucesso no ServiceNow' , { sysId , comment } ) ;
// retornar id do comentário criado
const commentId = await getCommentId ( sysId , comment ) ;
return commentId ;
} catch ( error ) {
logError ( error , '🚨Falha ao criar comentário no ServiceNow' ) ;
}
}
2025-08-30 19:04:35 -03:00
module . exports = {
2025-09-03 16:11:30 -03:00
fetchTicketsFromServiceNow ,
2025-09-25 15:59:52 -03:00
fetchRequestsFromServiceNow ,
getTicketSysId ,
createCommentInServiceNow ,
getCommentId ,
2025-09-05 20:28:15 -03:00
}