@begapp/sdk 1.1.3 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +44 -1
- package/index.js +2 -1
- package/package.json +25 -20
- package/src/client.js +2 -10
- package/src/notificaciones.js +84 -13
- package/src/crypMensaje.js +0 -24
package/README.md
CHANGED
|
@@ -2,9 +2,52 @@
|
|
|
2
2
|
|
|
3
3
|
Librería cliente para consumir los servicios de BegaApp desde cualquier aplicación externa. Permite configurar la API Key y consumir fácilmente endpoints.
|
|
4
4
|
|
|
5
|
+
## Audiencia dinámica
|
|
6
|
+
|
|
7
|
+
Los avisos estáticos mantienen la firma existente:
|
|
8
|
+
|
|
9
|
+
```js
|
|
10
|
+
await crearNotificacionBegaApp('RECEPCION_CREADA', data);
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Para un aviso dinámico, la aplicación origen identifica al destinatario usando
|
|
14
|
+
su identidad externa. Bega resuelve el vínculo y valida que el usuario esté
|
|
15
|
+
autorizado en la definición del aviso:
|
|
16
|
+
|
|
17
|
+
```js
|
|
18
|
+
await crearNotificacionBegaApp('RECEPCION_ELIMINADA', data, {
|
|
19
|
+
recipients: {
|
|
20
|
+
users: [{ source: 'easy-bodega', externalId: creadorId }]
|
|
21
|
+
},
|
|
22
|
+
context: {
|
|
23
|
+
actor: { source: 'easy-bodega', externalId: usuarioActualId }
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Las mismas opciones están disponibles como cuarto argumento de
|
|
29
|
+
`crearNotificacionFileBegaApp(codigoAviso, data, files, options)`.
|
|
30
|
+
|
|
31
|
+
### Suprimir el correo en una ejecución
|
|
32
|
+
|
|
33
|
+
Si el aviso tiene correo habilitado en Bega, la aplicación origen puede decidir
|
|
34
|
+
que una ejecución concreta se entregue solo por chat y campanita:
|
|
35
|
+
|
|
36
|
+
```js
|
|
37
|
+
await crearNotificacionBegaApp('RECEPCION_ACTUALIZADA', data, {
|
|
38
|
+
delivery: { email: false }
|
|
39
|
+
});
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Omitir `delivery.email` conserva el comportamiento configurado en Bega. Enviar
|
|
43
|
+
`true` no habilita el correo si la definición del aviso lo tiene desactivado.
|
|
44
|
+
|
|
45
|
+
Durante la transición el servidor también acepta el `ObjectId` histórico, pero
|
|
46
|
+
las integraciones nuevas deben usar el código estable configurado en Bega.
|
|
47
|
+
|
|
5
48
|
---
|
|
6
49
|
|
|
7
50
|
## 🚀 Instalación
|
|
8
51
|
|
|
9
52
|
```bash
|
|
10
|
-
npm install @begaapp/sdk
|
|
53
|
+
npm install @begaapp/sdk
|
package/index.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { configurarSDKBegaApp } from './src/client.js';
|
|
2
|
-
import { crearNotificacionBegaApp } from './src/notificaciones.js';
|
|
2
|
+
import { crearNotificacionBegaApp, crearNotificacionFileBegaApp } from './src/notificaciones.js';
|
|
3
3
|
|
|
4
4
|
export {
|
|
5
5
|
configurarSDKBegaApp,
|
|
6
6
|
crearNotificacionBegaApp,
|
|
7
|
+
crearNotificacionFileBegaApp
|
|
7
8
|
};
|
package/package.json
CHANGED
|
@@ -1,20 +1,25 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@begapp/sdk",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "SDK para interactuar con el servicio de notificaciones de Bega App",
|
|
5
|
-
"main": "index.js",
|
|
6
|
-
"type": "module",
|
|
7
|
-
"
|
|
8
|
-
"
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
"
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
"
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "@begapp/sdk",
|
|
3
|
+
"version": "2.1.0",
|
|
4
|
+
"description": "SDK para interactuar con el servicio de notificaciones de Bega App",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"files": [
|
|
8
|
+
"index.js",
|
|
9
|
+
"src",
|
|
10
|
+
"README.md"
|
|
11
|
+
],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"test": "node --test"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [],
|
|
16
|
+
"author": "Bega App",
|
|
17
|
+
"license": "MIT",
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"axios": "^1.9.0",
|
|
20
|
+
"crypto-js": "^4.2.0"
|
|
21
|
+
},
|
|
22
|
+
"publishConfig": {
|
|
23
|
+
"access": "public"
|
|
24
|
+
}
|
|
25
|
+
}
|
package/src/client.js
CHANGED
|
@@ -6,9 +6,9 @@ var claveSecreta = '';
|
|
|
6
6
|
export function configurarSDKBegaApp({ apiKey, urlApi, secretKey }) {
|
|
7
7
|
if (!apiKey) throw new Error("Debes proporcionar una API key");
|
|
8
8
|
if (!urlApi) throw new Error("Debes proporcionar la URL de la API Bega");
|
|
9
|
-
if (!secretKey) throw new Error("Debes proporcionar la
|
|
9
|
+
// if (!secretKey) throw new Error("Debes proporcionar la Secret Key de la API Bega");
|
|
10
10
|
|
|
11
|
-
claveSecreta = secretKey;
|
|
11
|
+
// claveSecreta = secretKey;
|
|
12
12
|
|
|
13
13
|
axiosInstance = axios.create({
|
|
14
14
|
baseURL: urlApi,
|
|
@@ -25,12 +25,4 @@ export function getClient() {
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
return axiosInstance;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export function getClaveSecreta() {
|
|
31
|
-
if (claveSecreta === '') {
|
|
32
|
-
throw new Error("No se ha configurado la Clave secreta para encriptar los mensajes");
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
return claveSecreta;
|
|
36
28
|
}
|
package/src/notificaciones.js
CHANGED
|
@@ -1,18 +1,89 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { encryptMensaje } from './crypMensaje.js';
|
|
1
|
+
import { getClient } from './client.js';
|
|
3
2
|
|
|
4
|
-
|
|
5
|
-
if (!
|
|
6
|
-
throw new Error("crearNotificacion requiere un
|
|
3
|
+
function buildNotificationPayload(identifier, data, options = {}) {
|
|
4
|
+
if (!identifier || !data || typeof data !== 'object' || Array.isArray(data)) {
|
|
5
|
+
throw new Error("crearNotificacion requiere un identificador y un objeto data.");
|
|
7
6
|
}
|
|
7
|
+
// `id` se conserva durante la transición para servidores SDK anteriores.
|
|
8
|
+
const payload = { identifier, id: identifier, data };
|
|
9
|
+
if (options.context) payload.context = options.context;
|
|
10
|
+
if (options.recipients) payload.recipients = options.recipients;
|
|
11
|
+
if (options.delivery) payload.delivery = options.delivery;
|
|
12
|
+
if (options.attachments) payload.attachments = options.attachments;
|
|
13
|
+
return payload;
|
|
14
|
+
}
|
|
8
15
|
|
|
9
|
-
|
|
16
|
+
function sdkError(error) {
|
|
17
|
+
return {
|
|
18
|
+
status: "error",
|
|
19
|
+
code: error.response?.data?.code,
|
|
20
|
+
message: error.response?.data?.message || error.message,
|
|
21
|
+
details: error.response?.data?.details
|
|
22
|
+
};
|
|
23
|
+
}
|
|
10
24
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
data,
|
|
15
|
-
});
|
|
25
|
+
export async function crearNotificacionBegaApp(identifier, data, options = {}) {
|
|
26
|
+
try {
|
|
27
|
+
const client = getClient();
|
|
28
|
+
const res = await client.post("/notification/create-notification", buildNotificationPayload(identifier, data, options));
|
|
16
29
|
|
|
17
|
-
|
|
18
|
-
}
|
|
30
|
+
return { status: "success", data: res.data };
|
|
31
|
+
} catch (error) {
|
|
32
|
+
return sdkError(error);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export async function crearNotificacionFileBegaApp(identifier, data, files, options = {}) {
|
|
37
|
+
try {
|
|
38
|
+
if (!identifier || typeof data !== 'object') {
|
|
39
|
+
throw new Error("crearNotificacionFileBegaApp requiere un identificador y un objeto data.");
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (!files || files.length <= 0) {
|
|
43
|
+
throw new Error("crearNotificacionFileBegaApp requiere al menos un archivo");
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const client = getClient();
|
|
47
|
+
|
|
48
|
+
const attachments = await Promise.all(
|
|
49
|
+
files.map(async ({ name, file }) => {
|
|
50
|
+
|
|
51
|
+
const form = new FormData();
|
|
52
|
+
form.append('file', file, `${name}.pdf`);
|
|
53
|
+
form.append('meta', JSON.stringify({ generatedAt: new Date().toISOString() }));
|
|
54
|
+
form.append('id', identifier);
|
|
55
|
+
|
|
56
|
+
console.log("ASÍ ESTOY ARMANDO EL FORM: ", form);
|
|
57
|
+
|
|
58
|
+
const respFile = await client.post("uploads/document-notification", form, {
|
|
59
|
+
headers: {
|
|
60
|
+
// No pongas application/json. Deja que el browser ponga el Content-Type con boundary.
|
|
61
|
+
// En axios está bien poner 'multipart/form-data' — el browser añadirá el boundary.
|
|
62
|
+
'Content-Type': 'multipart/form-data'
|
|
63
|
+
},
|
|
64
|
+
onUploadProgress: (e) => {
|
|
65
|
+
if (!e.total) return;
|
|
66
|
+
const pct = Math.round((e.loaded * 100) / e.total);
|
|
67
|
+
console.log(`${name}: Progreso de subida: ${pct}%`);
|
|
68
|
+
},
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
if (respFile?.data?.status !== 'success') {
|
|
72
|
+
throw new Error(`Upload fallido para ${name}: ${respFile?.data?.message ?? 'sin mensaje'}`);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return respFile.data.attachment;
|
|
76
|
+
})
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
console.log("ESTE ES MI ATTACHMENTS: ", attachments);
|
|
80
|
+
|
|
81
|
+
const res = await client.post("/notification/create-notification", buildNotificationPayload(identifier, data, { ...options, attachments }));
|
|
82
|
+
|
|
83
|
+
return { status: "success", data: res.data };
|
|
84
|
+
} catch (error) {
|
|
85
|
+
return sdkError(error);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export { buildNotificationPayload };
|
package/src/crypMensaje.js
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import CryptoJS from "crypto-js";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Cifra un objeto JSON como string
|
|
5
|
-
* @param {Object} data - El objeto con los datos (por ejemplo { cliente, estado })
|
|
6
|
-
* @param {string} claveSecreta - Clave AES
|
|
7
|
-
* @returns {string} - Texto cifrado
|
|
8
|
-
*/
|
|
9
|
-
export function encryptMensaje(data, claveSecreta) {
|
|
10
|
-
const stringData = JSON.stringify(data);
|
|
11
|
-
return CryptoJS.AES.encrypt(stringData, claveSecreta).toString();
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Descifra un string cifrado a objeto JSON
|
|
16
|
-
* @param {string} mensajeCifrado - Texto cifrado
|
|
17
|
-
* @param {string} claveSecreta - Clave AES
|
|
18
|
-
* @returns {Object} - Objeto original
|
|
19
|
-
*/
|
|
20
|
-
export function decryptMensaje(mensajeCifrado, claveSecreta) {
|
|
21
|
-
const bytes = CryptoJS.AES.decrypt(mensajeCifrado, claveSecreta);
|
|
22
|
-
const textoPlano = bytes.toString(CryptoJS.enc.Utf8);
|
|
23
|
-
return JSON.parse(textoPlano);
|
|
24
|
-
}
|