Compare commits

...

2 Commits

Author SHA1 Message Date
adriano bb25ec1f09 fix: removed api key hubspot loaded from .env 2025-06-20 10:48:48 -03:00
Eduxavier88 8b83c7613c refactor: apply feedback and finalize PR #2 2025-06-20 08:57:01 -03:00
3 changed files with 57 additions and 28 deletions

View File

@ -1,19 +1,33 @@
const HubspotService = require('../services/hubspotService'); const HubspotService = require('../services/hubspotService');
const { get, del } = require('../utils/redisClient') const { get, del } = require('../utils/redisClient')
const hubspotService = new HubspotService();
const receiveTranscription = async (req, res) => { const receiveTranscription = async (req, res) => {
try { try {
console.log('Payload recebido:', JSON.stringify(req.body, null, 2));
const { crmPhone, uniqueId, transcription, recordingUrl, companyId } = req.body; const { crmPhone, uniqueId, transcription, recordingUrl, companyId, clientTranscription, agentTranscription } = req.body;
console.log('=========> crmPhone: ', crmPhone, "===> uniqueId: ", uniqueId, "===> transcription: ", transcription, "===> recordingUrl: ", recordingUrl, "===> companyId: ", companyId )
if (!crmPhone || !uniqueId || !transcription || !recordingUrl) { if (!crmPhone || !uniqueId || !transcription || !recordingUrl) {
console.log('Campos faltando:', {
crmPhone: !crmPhone,
uniqueId: !uniqueId,
transcription: !transcription,
recordingUrl: !recordingUrl
});
return res.status(400).json({ error: 'Campos obrigatórios ausentes.' }); return res.status(400).json({ error: 'Campos obrigatórios ausentes.' });
} }
console.log(`Recebida transcrição para crmPhone: ${crmPhone}, uniqueId: ${uniqueId}`); console.log(`Recebida transcrição para crmPhone: ${crmPhone}, uniqueId: ${uniqueId}`);
console.log('Transcrição:', transcription.summary); console.log('Transcrição Resumo:', transcription);
console.log('Transcrição Cliente:', clientTranscription);
console.log('Transcrição Agente:', agentTranscription);
// 1. Buscar ticketId no Redis // 1. Buscar ticketId no Redis
const ticketId = await get(crmPhone); const ticketId = await get(crmPhone);
@ -22,20 +36,22 @@ const receiveTranscription = async (req, res) => {
console.warn(`Nenhum ticketId encontrado no Redis para o crmPhone: ${crmPhone}. A transcrição será salva como uma nota sem associação ao ticket.`); console.warn(`Nenhum ticketId encontrado no Redis para o crmPhone: ${crmPhone}. A transcrição será salva como uma nota sem associação ao ticket.`);
} }
const hubspotService = await new HubspotService(companyId).init();
// 2. Buscar ou criar contato no HubSpot // 2. Buscar ou criar contato no HubSpot
const contact = await hubspotService.createContactIfNotExists(companyId, crmPhone); const contact = await hubspotService.createContactIfNotExists(crmPhone);
// 3. Criar nota no HubSpot e associar ao contato e ao ticket (se existir) // 3. Criar nota no HubSpot e associar ao contato e ao ticket (se existir)
await hubspotService.createCallNote(contact.contactId, { await hubspotService.createCallNote(contact.contactId, {
transcription: `${transcription.client || ''}\n${transcription.agent || ''}`, transcription: `${clientTranscription || ''}\n${agentTranscription || ''}`,
summary: transcription.summary, summary: transcription,
recordingUrl, recordingUrl,
crmPhone, crmPhone,
uniqueId, uniqueId,
ticketId ticketId
}); });
await del(crmPhone) // await del(crmPhone)
return res.status(200).json({ message: 'Transcrição recebida e processada com sucesso!' }); return res.status(200).json({ message: 'Transcrição recebida e processada com sucesso!' });
} catch (error) { } catch (error) {

View File

@ -12,17 +12,28 @@ class HubspotService {
/** /**
* Inicializa o serviço HubspotService com configuração da API. * Inicializa o serviço HubspotService com configuração da API.
*/ */
constructor() { constructor(companyId) {
this.logger = Logger; this.logger = Logger;
this.baseUrl = 'https://api.hubapi.com'; this.companyId = companyId
this.apiKey = process.env.HUBSPOT_API_KEY; }
this.client = axios.create({
baseURL: this.baseUrl, async init() {
headers: { this.crmFiles = await loadCRM(this.companyId);
'Authorization': `Bearer ${this.apiKey}`,
'Content-Type': 'application/json' if (this?.crmFiles?.length > 0) {
}
}); const { authentication } = this.crmFiles[0].crm
this.client = axios.create({
baseURL: 'https://api.hubapi.com',
headers: {
'Authorization': `Bearer ${authentication.token}`,
'Content-Type': 'application/json'
}
});
}
return this;
} }
/** /**
@ -40,12 +51,12 @@ class HubspotService {
*/ */
async createCallNote(contactId, callData) { async createCallNote(contactId, callData) {
try { try {
const { transcription, summary, recordingUrl, callerId, uniqueId, ticketId } = callData; const { transcription, summary, recordingUrl, crmPhone, uniqueId, ticketId } = callData;
const noteContent = ` const noteContent = `
Chamada Recebida Chamada Recebida
------------------ ------------------
Número: ${callerId} Número: ${crmPhone}
ID da Chamada: ${uniqueId} ID da Chamada: ${uniqueId}
Data/Hora: ${new Date().toLocaleString('pt-BR', { timeZone: 'America/Sao_Paulo' })} Data/Hora: ${new Date().toLocaleString('pt-BR', { timeZone: 'America/Sao_Paulo' })}
@ -90,8 +101,8 @@ Link da Gravação: ${recordingUrl}
/** /**
* Busca um contato no HubSpot pelo número de telefone. * Busca um contato no HubSpot pelo número de telefone.
* *
* @param {string} phoneNumber - Número de telefone para buscar. * @param {string} phoneNumber
* @returns {Promise<Object|null>} - Contato encontrado ou null. * @returns {Promise<Object|null>}
*/ */
async findContactByPhone(phoneNumber) { async findContactByPhone(phoneNumber) {
try { try {
@ -118,23 +129,22 @@ Link da Gravação: ${recordingUrl}
* @param {string} crmPhone - Número de telefone do contato. * @param {string} crmPhone - Número de telefone do contato.
* @returns {Promise<Object>} - Contato existente ou novo contato criado. * @returns {Promise<Object>} - Contato existente ou novo contato criado.
*/ */
async createContactIfNotExists(companyId, crmPhone) { async createContactIfNotExists(crmPhone) {
const crmFiles = await loadCRM(companyId) if (this?.crmFiles?.length > 0) {
if (crmFiles.length > 0) { const { crmRest: rest, authentication } = this.crmFiles[0].crm
const { crmRest: rest, authentication } = crmFiles[0].crm
let contact = await lookupContactByPhone(rest, authentication, crmPhone, companyId) let contact = await lookupContactByPhone(rest, authentication, crmPhone, companyId)
if (!contact.exist) { if (!contact.exist) {
contact = await createContact(companyId, rest, authentication, crmPhone) contact = await createContact(companyId, rest, authentication, crmPhone)
}
}
console.log('========> contact', contact)
return contact return contact
} }
return null
} }
} }

View File

@ -25,6 +25,9 @@ async function get(key) {
// Function to delete a token // Function to delete a token
async function del(key) { async function del(key) {
console.log('=========> key: ', key)
const deletedCount = await redis.del(key) const deletedCount = await redis.del(key)
if (deletedCount === 1) { if (deletedCount === 1) {
console.log(`Token ${key} deleted successfully!`) console.log(`Token ${key} deleted successfully!`)