Inicio rápido
Esta guía te llevará desde cero hasta tener el SDK operativo con un escenario real de gestión de casos en Shori.
Elige tu plataforma
import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem';
Continúa leyendo — esta guía está orientada a Java con Maven.
npm install shori-sdk-ts
import { ShoriClientBuilder, ShoriEnvironment } from "shori-sdk-ts";
const client = new ShoriClientBuilder()
.environment(ShoriEnvironment.UAT)
.portalId("tu-portal-id")
.tenantId("tu-tenant-id")
.apiKey("tu-api-key")
.build();
// Agregar comentario
const result = await client.caso().comment().add(
AddCommentRequest.builder()
.casoId("caso-uuid")
.comment("Procesado correctamente")
.build()
);
Instalación:
# Manage palette → Install → busca: axetflow-shori-nodes
# O por línea de comandos:
cd ~/.node-red
npm install axetflow-shori-nodes
Flujo básico en 3 pasos:
- Arrastra shori-config → configura
portalId,tenantId,apiKeyy el ambiente - Conecta el nodo de acción que necesitas (crear caso, buscar, comentar, etc.)
- Los datos se pasan por
msg.payloado se configuran directamente en el formulario del nodo
[inject] → [shori-config] → [shori-create-case] → [shori-next-state] → [debug]
30 nodos disponibles cubriendo todos los módulos del SDK — sin escribir una sola línea de código.
npm install shori-sdk-ts
// shori.module.ts
@Module({
providers: [
{
provide: 'SHORI_CLIENT',
useFactory: () => new ShoriClientBuilder()
.environment(ShoriEnvironment.PROD)
.portalId(process.env.SHORI_PORTAL_ID)
.tenantId(process.env.SHORI_TENANT_ID)
.apiKey(process.env.SHORI_API_KEY)
.build(),
},
],
exports: ['SHORI_CLIENT'],
})
export class ShoriModule {}
npm install shori-sdk-ts
import express from "express";
import { ShoriClientBuilder, ShoriEnvironment } from "shori-sdk-ts";
const app = express();
const client = new ShoriClientBuilder()
.environment(ShoriEnvironment.PROD)
.portalId(process.env.SHORI_PORTAL_ID!)
.tenantId(process.env.SHORI_TENANT_ID!)
.apiKey(process.env.SHORI_API_KEY!)
.build();
app.get("/cases/:id", async (req, res) => {
const caso = await client.caso().findById(req.params.id);
res.json(caso);
});
Prerrequisitos (Java)
Antes de comenzar, asegúrate de tener:
- ✅ Java 17 o superior instalado
- ✅ Maven 3.6+ configurado
- ✅ Credenciales de acceso a Shori:
portalId,tenantIdyapiKey - ✅ Los UUIDs de tu
casoTypeIdyformId(proporcionados por el equipo de Shori)
Contacta al equipo de Shori de NTT DATA para obtener las credenciales de acceso a los ambientes UAT (pruebas) y PROD (producción).
Paso 1 — Agregar la dependencia
Añade el repositorio y la dependencia en tu pom.xml:
<!-- 1. Repositorio del SDK (GitLab Package Registry — público) -->
<repositories>
<repository>
<id>gitlab-maven</id>
<url>https://gitlab.com/api/v4/projects/84253138/packages/maven</url>
</repository>
</repositories>
<!-- 2. Dependencia -->
<dependency>
<groupId>com.nttdata.shori</groupId>
<artifactId>shori-api-client</artifactId>
<version>1.0.0</version>
</dependency>
El Package Registry es público. No necesitas configurar credenciales para descargar el artefacto.
Paso 2 — Inicializar el cliente
Crea una instancia de ShoriClient con tus credenciales:
import com.nttdata.shori.client.ShoriClient;
import com.nttdata.shori.config.ShoriEnvironment;
ShoriClient client = ShoriClient.builder()
.environment(ShoriEnvironment.UAT) // DEV | UAT | PROD
.portalId("tu-portal-id")
.tenantId("tu-tenant-id")
.apiKey("tu-api-key")
.timeoutSeconds(30) // opcional, default: 30s
.build();
Crea el cliente una sola vez y reutilízalo. Es thread-safe y mantiene internamente el pool de conexiones HTTP y el token de autenticación.
maxConnections)Por defecto el SDK mantiene hasta 5 conexiones simultáneas por módulo (caso, repo, identify). Para automatizaciones con alta concurrencia, aumenta este valor:
ShoriClient client = ShoriClient.builder()
...
.maxConnections(10) // 10 por módulo = 30 conexiones totales
.build();
Si usas el SDK en una aplicación de escritorio con múltiples ventanas o automatizaciones,
usa ShoriClientRegistry para gestionar los clientes de forma centralizada.
Ver la guía completa en Instalación y Configuración → Integración con JavaFX.
Si usas Spring Boot, declara el cliente como un @Bean en tu clase de configuración. Spring gestionará automáticamente su ciclo de vida:
@Configuration
public class ShoriConfiguration {
@Value("${shori.portal-id}")
private String portalId;
@Value("${shori.tenant-id}")
private String tenantId;
@Value("${shori.api-key}")
private String apiKey;
@Bean(destroyMethod = "close")
public ShoriClient shoriClient() {
return ShoriClient.builder()
.environment(ShoriEnvironment.PROD)
.portalId(portalId)
.tenantId(tenantId)
.apiKey(apiKey)
.build();
}
}
Luego inyéctalo donde lo necesites:
@Service
public class MiServicio {
private final ShoriClient shoriClient;
public MiServicio(ShoriClient shoriClient) {
this.shoriClient = shoriClient;
}
}
Para la configuración completa en application.properties / application.yml consulta Instalación y Configuración.
Paso 3 — Escenario completo: gestión de solicitudes de servicio
El siguiente ejemplo muestra un flujo BPO completo: obtener los estados del proceso, crear un caso, buscarlo y avanzar su estado.
3.1 Obtener el tipo de caso y sus estados
import com.nttdata.shori.modules.caso.dto.response.ProductResponse;
import com.nttdata.shori.util.ShoriUtils;
import java.util.List;
// Obtener la definición del tipo de caso (incluye estados disponibles)
ProductResponse tipoCaso = client.caso().casoType()
.findById("D0480B5C-8730-4CD9-858A-151AF7C0D852");
System.out.println("Tipo de caso: " + tipoCaso.getName());
// Obtener los IDs de los estados "abiertos" (para filtrar búsquedas)
List<String> estadosAbiertos = ShoriUtils.openStatesIds(tipoCaso);
System.out.println("Estados abiertos: " + estadosAbiertos.size());
3.2 Crear un nuevo caso
import com.nttdata.shori.modules.caso.dto.request.CasoCreateRequest;
import com.nttdata.shori.modules.caso.dto.response.CasoCreateResponse;
import java.util.Map;
CasoCreateRequest solicitud = CasoCreateRequest.builder()
.casoTypeId("D0480B5C-8730-4CD9-858A-151AF7C0D852")
.formId("F1234567-ABCD-1234-EFGH-123456789012")
.priority("B2345678-ABCD-1234-EFGH-123456789012")
.submittedData(Map.of(
"nombreCliente", "Ana García López",
"tipoDocumento", "DNI",
"numeroDocumento","12345678",
"telefono", "+51987654321",
"tipoServicio", "PORTABILIDAD",
"observaciones", "Cliente solicita portabilidad de número fijo"
))
.build();
CasoCreateResponse resultado = client.caso().create(solicitud);
String casoId = resultado.getCaso();
System.out.println("Caso creado con ID: " + casoId);
System.out.println("Número de caso: " + resultado.getCasoNumber());
3.3 Consultar el caso creado
import com.nttdata.shori.modules.caso.dto.response.CasoResponse;
CasoResponse caso = client.caso().findById(casoId);
System.out.println("Estado actual: " + caso.getWorkingSubStateName());
System.out.println("Creado el: " + caso.getCreatedAt());
3.4 Buscar casos abiertos del proceso
import com.nttdata.shori.modules.caso.filter.CaseFilter;
import com.nttdata.shori.modules.caso.filter.FilterOperator;
import com.nttdata.shori.modules.caso.dto.response.CasoSearchResponse;
List<CasoSearchResponse> casosAbiertos = client.caso().searchAll(
CaseFilter.builder()
.casoTypeId(FilterOperator.EQ, "D0480B5C-8730-4CD9-858A-151AF7C0D852")
.workingSubStateId(FilterOperator.IN, estadosAbiertos.toArray(new String[0]))
.pageSize(100)
.build()
);
System.out.println("Total casos abiertos: " + casosAbiertos.size());
casosAbiertos.forEach(c ->
System.out.printf(" [%s] %s - %s%n",
c.getCasoNumber(), c.getCasoId(), c.getWorkingSubStateName())
);
3.5 Avanzar el estado del caso
import com.nttdata.shori.modules.caso.dto.request.NextStateRequest;
// Obtener el ID del siguiente estado desde la definición del tipo de caso
String siguienteEstadoId = tipoCaso.getStates().stream()
.filter(s -> s.getName().equals("EN PROCESO"))
.map(s -> s.getId())
.findFirst()
.orElseThrow();
NextStateRequest cambioEstado = NextStateRequest.builder()
.casoId(casoId)
.stateId(siguienteEstadoId)
.build();
boolean exito = client.caso().state().next(cambioEstado);
System.out.println("Estado actualizado: " + exito);
3.6 Agregar un comentario
import com.nttdata.shori.modules.caso.dto.request.AddCommentRequest;
AddCommentRequest comentario = AddCommentRequest.builder()
.casoId(casoId)
.comment("Caso asignado al equipo de portabilidad. Tiempo estimado: 48h.")
.build();
client.caso().comment().add(comentario);
System.out.println("Comentario registrado correctamente.");
3.7 Adjuntar un documento
import com.nttdata.shori.modules.repo.dto.request.UploadDocumentRequest;
import java.io.File;
File contrato = new File("/ruta/al/contrato-firmado.pdf");
String documentId = client.repo().document().upload(
UploadDocumentRequest.builder()
.file(contrato)
.casoId(casoId)
.casoTypeId("D0480B5C-8730-4CD9-858A-151AF7C0D852")
.isValid(true)
.isDeleted(false)
.encrypted(false)
.build()
);
System.out.println("Documento subido con ID: " + documentId);
Paso 4 — Cerrar el cliente
Cuando tu aplicación termine de usar el SDK, libera los recursos del pool de conexiones HTTP.
Opción A — try-with-resources (scripts, tests, jobs de corta duración):
// close() se llama automáticamente al salir del bloque, incluso si hay excepción
try (ShoriClient client = ShoriClient.builder()
.environment(ShoriEnvironment.UAT)
.portalId("tu-portal-id")
.tenantId("tu-tenant-id")
.apiKey("tu-api-key")
.build()) {
List<CasoSearchResponse> casos = client.caso().searchAll(filter);
// ...
}
Opción B — Manual (cuando no usas try-with-resources):
client.close();
En Spring Boot, declara el cliente como @Bean con destroyMethod = "close". Spring llama close() automáticamente al apagar el servidor — no necesitas gestionar el ciclo de vida manualmente:
@Bean(destroyMethod = "close")
public ShoriClient shoriClient() {
return ShoriClient.builder()
.environment(ShoriEnvironment.PROD)
.portalId(portalId)
.tenantId(tenantId)
.apiKey(apiKey)
.build();
}
Manejo de errores
El SDK lanza excepciones específicas según el tipo de error:
import com.nttdata.shori.exception.*;
try {
CasoResponse caso = client.caso().findById("uuid-inexistente");
} catch (ResourceNotFoundException e) {
// HTTP 404 — El recurso no existe
System.err.println("Caso no encontrado: " + e.getMessage());
} catch (AuthenticationException e) {
// Error de autenticación — revisa tu apiKey
System.err.println("Error de autenticación: " + e.getMessage());
} catch (ApiException e) {
// HTTP 400, 500, etc — Error del API
System.err.printf("Error HTTP %d: %s%n", e.getStatusCode(), e.getMessage());
} catch (ValidationException e) {
// Configuración inválida del SDK
System.err.println("Error de configuración: " + e.getMessage());
}
Próximos pasos
- 📖 Instalación y configuración avanzada — SSL, timeouts, Spring Boot, ambientes
- 📦 Módulo de Casos — CRUD, búsqueda paginada, attachments
- 📁 Archivos adjuntos — Subir, descargar y eliminar documentos
- 🔄 Estados del caso — Avanzar el flujo de trabajo
- 💬 Comentarios — Registrar notas en un caso
- 🏷️ Producto (casoType) — Obtener definición y estados disponibles
- 🏢 Servicios (primaryLevel) — Buscar, crear, actualizar, activar/desactivar servicios y sus working substates
- ⚙️ Procesos (secondaryLevel) — Buscar, crear, actualizar, activar/desactivar procesos
- 👤 Usuarios (user) — Asignar y desasignar usuarios responsables o participantes en casos
- 🗃️ Tipología de archivos (fileTypology) — Tipologías y categorías de archivos
- 🗂️ Repositorio de documentos — Gestión centralizada de archivos
- 📤 Subir y eliminar documentos — Sub-módulo de escritura del repositorio
- 📥 Descargar documentos — Descarga por ID, versión o exportación
- 👤 Identificación de usuarios — Buscar usuarios en Shori
- 🗒️ Gestión de Formularios — Creación, actualización y búsqueda de formularios
- ⚠️ Manejo de errores — Jerarquía de excepciones