Commit 0c2b831f authored by Sebastián Long's avatar Sebastián Long

Finish CHATBOTS-10

parents 979c4243 6911a16d
......@@ -11,5 +11,9 @@
},
"isBaseUrl": "",
"sendingbluBaseUrl": "",
"sendingblueListId": 54
"sendingblueListId": 54,
"crispWebsiteIdIpsTurnosBajoDemanda": "",
"crispWebsiteIdIsTurnosProgramados": "",
"idAgendaIPS": "",
"idDominioIPS": ""
}
\ No newline at end of file
......@@ -5,12 +5,14 @@ const config = require('config');
var identifier = config.get('credenciales.crisp.identifier');
var key = config.get('credenciales.crisp.key');
let SIGUIENTE_PASO = 'siguiente_paso';
const DELAY_MS = 1000;
let localData = {};
CrispClient.authenticate(identifier, key);
async function sendTextMessage(website_id, session_id, message) {
await composeMessage(website_id, session_id, DELAY_MS);
await CrispClient.websiteConversations.sendMessage(
website_id,
session_id, {
......@@ -22,7 +24,28 @@ async function sendTextMessage(website_id, session_id, message) {
);
}
async function composeMessage(website_id, session_id, ms){
await CrispClient.websiteConversations.composeMessage(
website_id,
session_id, {
"type": "start",
"from": "operator"}
);
await new Promise(resolve => setTimeout(resolve, ms));
await CrispClient.websiteConversations.composeMessage(
website_id,
session_id, {
"type": "stop",
"from": "operator"}
);
}
async function showWritingIcon(website_id, session_id){
await composeMessage(website_id, session_id, DELAY_MS);
}
async function sendPickerMessage(website_id, session_id, id, title, choices) {
await composeMessage(website_id, session_id, DELAY_MS);
await CrispClient.websiteConversations.sendMessage(
website_id,
session_id, {
......@@ -83,6 +106,7 @@ async function updateUserData(website_id, session_id, data) {
module.exports =
{
CrispClient: CrispClient,
showWritingIcon: showWritingIcon,
sendTextMessage: sendTextMessage,
sendPickerMessage: sendPickerMessage,
getSiguientePaso: getSiguientePaso,
......
......@@ -43,7 +43,7 @@ module.exports =
});
},
getMedicosByName: async function (nombreMedico, idProvincia) {
return await isClient.get(`/medicos/atencion?id_provincia=${idProvincia}&nombre=${nombreMedico}`)
return await isClient.get(`/medicos/atencion?id_provincia=${idProvincia}&nombre=${nombreMedico}&todos=1`)
.then(async function (response) {
return response.data.data;
})
......@@ -52,7 +52,7 @@ module.exports =
});
},
getEspecialidadesMedico: async function (idPersonaInstitucional, idProvincia) {
return await isClient.get(`/atenciones?id_provincia=${idProvincia}&id_persona_institucional=${idPersonaInstitucional}`)
return await isClient.get(`/atenciones?id_provincia=${idProvincia}&id_persona_institucional=${idPersonaInstitucional}&todos=1`)
.then(async function (response) {
return response.data.data;
})
......@@ -81,20 +81,15 @@ module.exports =
existeUsuario: async function(tipo_documento, numero_documento, fecha_nacimiento, sexo){
return await isClient.get(`/watson/existe_persona?tipo_documento=${tipo_documento}&numero_documento=${numero_documento}&fecha_nacimiento=${fecha_nacimiento}&sexo=${sexo}`)
.then(async function (response) {
return response.data.existe;
return response.data;
})
.catch(function (error) {
console.log(error);
});
},
crearTurno: async function (tipoDocumento, numeroDocumento, fechaNacimiento, sexo, mail, telefono, idHorario, fechaHora) {
crearTurno: async function (idPersonaFederada, idHorario, fechaHora) {
return await isClient.post('/watson/confirmar_reserva', {
"tipo_documento": tipoDocumento,
"numero_documento": numeroDocumento,
"fecha_nacimiento": fechaNacimiento,
"sexo": sexo,
"mail": mail,
"telefono_celular": telefono,
"id_persona_federada": idPersonaFederada,
"id_horario": idHorario,
"fecha_hora": fechaHora
})
......@@ -104,5 +99,38 @@ module.exports =
.catch(function (error) {
console.log(error);
});
},
federarUsuario: async function (tipoDocumento, numeroDocumento, fechaNacimiento, sexo, mail, telefonoCelular, idDominio) {
let data = {
tipo_documento: tipoDocumento,
numero_documento: numeroDocumento,
fecha_nacimiento: fechaNacimiento,
sexo: sexo,
mail: mail,
telefono_celular: telefonoCelular
};
if(idDominio !== null){
data.id_dominio = idDominio;
}
return await isClient.post(`/watson/federar_persona`, data)
.then(async function (response) {
return response.data;
})
.catch(function (error) {
console.log(error);
return {success: false};
});
},
crearTurnoBajoDemanda: async function (idAgenda, idPersonaFederada) {
return await isClient.post(`/watson/confirmar_reserva_espontanea?id_agenda=${idAgenda}&id_persona_federada=${idPersonaFederada}`)
.then(async function (response) {
return response.data;
})
.catch(function (error) {
console.log(error);
return {success: false};
});
}
}
\ No newline at end of file
const crisp = require('../crisp.js');
const utils = require('../utils.js');
const pasos = require('./pasos_ips_turnos_bajo_demanda.js');
const is = require('../endpoints/is.js')
const config = require('config');
const LINK_CONDICIONES_DE_USO = 'https://www.integrandosalud.com/es-ar/ip-condiciones-de-uso/';
const ID_AGENDA_IPS = config.get('idAgendaIPS');
const ID_DOMINIO_IPS = config.get('idDominioIPS');
const SI = 'SI';
const NO = 'NO';
const TIPO_DOCUMENTO = 'tipo_documento';
const NUMERO_DOCUMENTO = 'numero_documento';
const FECHA_NACIMIENTO = 'fecha_nacimiento';
const SEXO = 'sexo';
const TELEFONO = 'telefono';
const CORREO = 'correo';
function getChoiceElegida(message){
for (let i = 0; i < message.content.choices.length; i++) {
if (message.content.choices[i].selected === true) {
return message.content.choices[i];
}
}
}
function fechaArgToFechaUsa(fechaArg){
let year = fechaArg.split('/')[2];
let month = fechaArg.split('/')[1];
let day = fechaArg.split('/')[0];
let fechaUSA = year + "-" + month + "-" + day;
return fechaUSA;
}
async function limpiarDatos(message, userData, website_id, session_id){
await crisp.updateUserData(website_id, session_id, {});
}
module.exports =
{
bienvenida: async function (message, userData, website_id, session_id) {
await crisp.sendTextMessage(website_id, session_id, 'Hola! Soy Emilia, tu asistente virtual');
await this.ask_acepta_condiciones(message, userData, website_id, session_id);
},
ask_acepta_condiciones: async function(message, userData, website_id, session_id) {
await crisp.setSiguientePaso(website_id, session_id, pasos.RESP_ACEPTA_CONDICIONES, userData);
await crisp.sendTextMessage(website_id, session_id, `Para continuar, debes aceptar las\n condiciones del servicio: ${LINK_CONDICIONES_DE_USO}`);
let choices = [];
choices.push(utils.armarChoice(SI, SI));
choices.push(utils.armarChoice(NO, NO));
await crisp.sendPickerMessage(website_id, session_id, pasos.RESP_ACEPTA_CONDICIONES, '¿Aceptas las condiciones de uso del servicio?', choices);
},
resp_acepta_condiciones: async function(message, userData, website_id, session_id) {
const aceptaCondiciones = getChoiceElegida(message).value;
if(aceptaCondiciones === SI){
await crisp.sendTextMessage(website_id, session_id, 'Para que puedas atenderte con un\n profesional necesito algunos datos');
await crisp.setSiguientePaso(website_id, session_id, pasos.ASK_TIPO_DOCUMENTO, userData);
await this.ask_tipo_documento(message, userData, website_id, session_id);
}
else{
await crisp.sendTextMessage(website_id, session_id, 'Gracias por contactarnos!');
await limpiarDatos(message, userData, website_id, session_id);
}
},
ask_tipo_documento: async function(message, userData, website_id, session_id){
await crisp.sendTextMessage(website_id, session_id, 'Seleccioná tu tipo de documento');
let choices = [];
choices.push(utils.armarChoice("DNI", "DNI"));
choices.push(utils.armarChoice("CDM", "CDM"));
choices.push(utils.armarChoice("CED", "CED"));
choices.push(utils.armarChoice("CIE", "CIE"));
choices.push(utils.armarChoice("CM", "CM"));
await crisp.sendPickerMessage(website_id, session_id, pasos.RESP_TIPO_DOCUMENTO, "Tipo de documento", choices);
await crisp.setSiguientePaso(website_id, session_id, pasos.RESP_TIPO_DOCUMENTO, userData);
},
resp_tipo_documento: async function(message, userData, website_id, session_id){
let tipoDocumentoElegido = getChoiceElegida(message);
userData[TIPO_DOCUMENTO] = tipoDocumentoElegido.value;
await this.ask_numero_documento(message, userData, website_id, session_id);
},
ask_numero_documento: async function(message, userData, website_id, session_id){
await crisp.setSiguientePaso(website_id, session_id, pasos.RESP_NUMERO_DOCUMENTO, userData);
await crisp.sendTextMessage(website_id, session_id, 'Ingresá tu número de documento');
},
resp_numero_documento: async function(message, userData, website_id, session_id){
userData[NUMERO_DOCUMENTO] = message.content;
await this.ask_fecha_nacimiento(message, userData, website_id, session_id);
},
ask_fecha_nacimiento: async function(message, userData, website_id, session_id){
await crisp.setSiguientePaso(website_id, session_id, pasos.RESP_FECHA_NACIMIENTO, userData);
await crisp.sendTextMessage(website_id, session_id, 'Ingresá tu fecha de nacimiento (DD/MM/AAAA)');
},
resp_fecha_nacimiento: async function(message, userData, website_id, session_id){
userData[FECHA_NACIMIENTO] = message.content;
await this.ask_sexo(message, userData, website_id, session_id);
},
ask_sexo: async function(message, userData, website_id, session_id){
let choices = [];
choices.push(utils.armarChoice("M", "Masculino"));
choices.push(utils.armarChoice("F", "Femenino"));
await crisp.setSiguientePaso(website_id, session_id, pasos.RESP_SEXO, userData);
await crisp.sendPickerMessage(website_id, session_id, pasos.RESP_SEXO, 'Seleccioná tu sexo', choices);
},
resp_sexo: async function(message, userData, website_id, session_id){
userData[SEXO] = getChoiceElegida(message).value;
await this.ask_telefono(message, userData, website_id, session_id);
},
ask_telefono: async function(message, userData, website_id, session_id){
await crisp.setSiguientePaso(website_id, session_id, pasos.RESP_TELEFONO, userData);
await crisp.sendTextMessage(website_id, session_id, 'Ingresá tu teléfono');
},
resp_telefono: async function(message, userData, website_id, session_id){
userData[TELEFONO] = message.content;
await this.ask_correo(message, userData, website_id, session_id);
},
ask_correo: async function(message, userData, website_id, session_id){
await crisp.setSiguientePaso(website_id, session_id, pasos.RESP_CORREO, userData);
await crisp.sendTextMessage(website_id, session_id, 'Ingresá tu correo electrónico');
},
resp_correo: async function(message, userData, website_id, session_id){
await crisp.showWritingIcon(website_id, session_id);
userData[CORREO] = message.content;
let existeUsuario = await is.existeUsuario(userData[TIPO_DOCUMENTO], userData[NUMERO_DOCUMENTO], fechaArgToFechaUsa(userData[FECHA_NACIMIENTO]), userData[SEXO]);
if(existeUsuario.existe){
if(existeUsuario.id_persona_federada !== null){
await this.crearTurnoBajoDemanda(ID_AGENDA_IPS, existeUsuario.id_persona_federada, message, userData, website_id, session_id);
}
else{
let federarUsuario = await is.federarUsuario(userData[TIPO_DOCUMENTO], userData[NUMERO_DOCUMENTO], fechaArgToFechaUsa(userData[FECHA_NACIMIENTO]), userData[SEXO], userData[CORREO], userData[TELEFONO], ID_DOMINIO_IPS);
if(federarUsuario.id_persona_federada !== null){
await this.crearTurnoBajoDemanda(ID_AGENDA_IPS, federarUsuario.id_persona_federada, message, userData, website_id, session_id)
}
else{
await this.errorDatosInvalidos(message, userData, website_id, session_id);
}
}
}
else {
await this.errorDatosInvalidos(message, userData, website_id, session_id);
}
},
crearTurnoBajoDemanda: async function (idAgenda, idPersonaFederada, message, userData, website_id, session_id){
let turnoDemandaResp = await is.crearTurnoBajoDemanda(idAgenda, idPersonaFederada);
if(!turnoDemandaResp.success){
//Error al crear turno
await crisp.sendTextMessage(website_id, session_id,'Disculpame, en este momento no puedo contactarte con un profesional');
await crisp.sendTextMessage(website_id, session_id,'Por favor, intentá de nuevo en unos minutos');
await limpiarDatos(message, userData, website_id, session_id);
}
else {
//Turno reservado exitosamente
await crisp.sendTextMessage(website_id, session_id,`Hacé click sobre "Iniciar consulta" para iniciar tu consulta`);
await crisp.sendTextMessage(website_id, session_id,`[Iniciar consulta](${turnoDemandaResp.link_vc})`);
await limpiarDatos(message, userData, website_id, session_id);
}
},
errorDatosInvalidos: async function (message, userData, website_id, session_id){
await crisp.sendTextMessage(website_id, session_id,'Uno de los datos ingresados es inválido');
await crisp.sendTextMessage(website_id, session_id,'Intentemos nuevamente');
await limpiarDatos(message, userData, website_id, session_id);
await this.ask_tipo_documento(message, userData, website_id, session_id);
}
}
\ No newline at end of file
const crisp = require('./crisp.js');
const utils = require('./utils.js');
const pasos = require('./pasos.js');
const is = require('./endpoints/is.js')
const crisp = require('../crisp.js');
const utils = require('../utils.js');
const pasos = require('./pasos_is_turnos_programados.js');
const is = require('../endpoints/is.js')
let LINK_SOLICITAR_ACCESO_POR_EMAIL = 'https://www.integrandosalud.com/es-ar/integrando-pacientes-solicitar-acceso-por-email/';
......@@ -420,7 +420,8 @@ module.exports =
resp_correo: async function(message, userData, website_id, session_id){
userData[CORREO] = message.content;
await crisp.updateCrispData(website_id, session_id, userData[CORREO], userData[TIPO_DOCUMENTO], userData[NUMERO_DOCUMENTO], userData[FECHA_NACIMIENTO], userData[SEXO]);
if(!await is.existeUsuario(userData[TIPO_DOCUMENTO], userData[NUMERO_DOCUMENTO], userData[FECHA_NACIMIENTO], userData[SEXO]) === true){
let existeUsuario = await is.existeUsuario(userData[TIPO_DOCUMENTO], userData[NUMERO_DOCUMENTO], fechaArgToFechaUsa(userData[FECHA_NACIMIENTO]), userData[SEXO]);
if(!existeUsuario.existe){
await crisp.sendTextMessage(website_id, session_id,
'No se pudieron validar sus datos. Solicite por favor su acceso por email ingresando al siguiente link'
);
......@@ -428,8 +429,7 @@ module.exports =
return;
}
let turnoElegido = userData[TURNO_ELEGIDO];
let resp = await is.crearTurno(userData[TIPO_DOCUMENTO], userData[NUMERO_DOCUMENTO], fechaArgToFechaUsa(userData[FECHA_NACIMIENTO]),
userData[SEXO], userData[CORREO], 0, turnoElegido.horarioId, turnoElegido.fechaHora);
let resp = await is.crearTurno(existeUsuario.id_persona_federada, turnoElegido.horarioId, turnoElegido.fechaHora);
if(resp.success === true){
let fechaHoraArg = fechaHoraUsaToFechaHoraArg(turnoElegido.fechaHora);
let fechaArg = fechaHoraArg.split(" ")[0];
......@@ -445,7 +445,8 @@ module.exports =
}
else{
await crisp.sendTextMessage(website_id, session_id,'Ha ocurrido un error al reservar el turno, intente nuevamente');
await crisp.updateUserData(website_id, session_id, {});
userData = {};
await crisp.updateUserData(website_id, session_id, userData);
await this.ask_reservar_turno(message, userData, website_id, session_id);
}
},
......
module.exports = Object.freeze({
BIENVENIDA: 'bienvenida',
ASK_ACEPTA_CONDICIONES: 'ask_acepta_condiciones',
RESP_ACEPTA_CONDICIONES: 'resp_acepta_condiciones',
ASK_TIPO_DOCUMENTO: 'ask_tipo_documento',
RESP_TIPO_DOCUMENTO: 'resp_tipo_documento',
ASK_NUMERO_DOCUMENTO: 'ask_numero_documento',
RESP_NUMERO_DOCUMENTO: 'resp_numero_documento',
ASK_FECHA_NACIMIENTO: 'ask_fecha_nacimiento',
RESP_FECHA_NACIMIENTO: 'resp_fecha_nacimiento',
ASK_SEXO: 'ask_sexo',
RESP_SEXO: 'resp_sexo',
ASK_TELEFONO: 'ask_telefono',
RESP_TELEFONO: 'resp_telefono',
ASK_CORREO: 'ask_correo',
RESP_CORREO: 'resp_correo'
});
\ No newline at end of file
const axios = require('axios');
const config = require('config');
const handlers = require('./handlers.js');
const handlerTurnosProgramados = require('./handlers/is_turnos_programados.js');
const handlerTurnosBajoDemanda = require('./handlers/ips_turnos_bajo_demanda');
const crisp = require('./crisp.js');
const utils = require('./utils.js');
const pasos = require('./pasos.js');
const pasosTurnosProgramados = require('./handlers/pasos_is_turnos_programados.js');
const pasosIpsTurnosBajoDemanda = require('./handlers/pasos_ips_turnos_bajo_demanda');
const is = require('./endpoints/is.js');
const sendinblue = require('./endpoints/sendinblue.js');
const WEBSITE_ID_IPS_TURNOS_BAJO_DEMANDA = config.get('crispWebsiteIdIpsTurnosBajoDemanda');
const WEBSITE_ID_TURNOS_PROGRAMADOS = config.get('crispWebsiteIdIsTurnosProgramados');
crisp.CrispClient.userProfile.get().then(function(myProfile) {
console.log(`El chatbot esta escuchando eventos (profile name: ${myProfile.first_name})`);
});
crisp.CrispClient.on("message:updated", async function (message) {
darSiguientePaso(message, message.website_id, message.session_id);
})
async function darSiguientePaso(message, website_id, session_id) {
let siguientePaso = await crisp.getSiguientePaso(message.website_id, message.session_id);
let userData = await crisp.getUserData(website_id, session_id);
handlers[siguientePaso](message, userData, website_id, session_id);
}
crisp.CrispClient.on("message:send", async function (message) {
if(message.content.toUpperCase() === 'REINICIAR'){
await crisp.updateUserData(message.website_id, message.session_id, {});
}
let siguientePaso = await crisp.getSiguientePaso(message.website_id, message.session_id);
if (siguientePaso == null) {
if(message.website_id === WEBSITE_ID_TURNOS_PROGRAMADOS){
enviarUserAListaSendingblue(message.website_id, message.session_id, config.get('sendingblueListId'));
await crisp.setSiguientePaso(message.website_id, message.session_id, pasos.ASK_RESERVAR_TURNO)
await crisp.setSiguientePaso(message.website_id, message.session_id, pasosTurnosProgramados.ASK_RESERVAR_TURNO)
}
if(message.website_id === WEBSITE_ID_IPS_TURNOS_BAJO_DEMANDA){
await crisp.setSiguientePaso(message.website_id, message.session_id, pasosIpsTurnosBajoDemanda.BIENVENIDA)
}
}
await darSiguientePaso(message, message.website_id, message.session_id);
});
async function darSiguientePaso(message, website_id, session_id) {
let siguientePaso = await crisp.getSiguientePaso(message.website_id, message.session_id);
let userData = await crisp.getUserData(website_id, session_id);
if(website_id === WEBSITE_ID_TURNOS_PROGRAMADOS){
handlerTurnosProgramados[siguientePaso](message, userData, website_id, session_id);
}
if(website_id === WEBSITE_ID_IPS_TURNOS_BAJO_DEMANDA){
handlerTurnosBajoDemanda[siguientePaso](message, userData, website_id, session_id);
}
}
async function enviarUserAListaSendingblue(website_id, session_id, listId){
try{
let crispUsrData = await crisp.getCrispData(website_id, session_id);
......
......@@ -4,7 +4,7 @@
"description": "Servidor para chatbot de Crisp",
"main": "index.js",
"scripts": {
"start": "node index.js",
"start": "nodemon index.js",
"autoload": "nodemon index.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment