@arisnetxsolutions/qwa-sdk 0.0.1
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 +204 -0
- package/dist/index.cjs +80 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +88 -0
- package/dist/index.d.ts +88 -0
- package/dist/index.js +77 -0
- package/dist/index.js.map +1 -0
- package/package.json +55 -0
package/README.md
ADDED
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
# @arisnetxsolutions/qwa-sdk
|
|
2
|
+
|
|
3
|
+
SDK oficial para la API de **QOpenWA** — envía mensajes de WhatsApp de forma sencilla, rápida y con tipado completo.
|
|
4
|
+
|
|
5
|
+
## Instalación
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @arisnetxsolutions/qwa-sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Modo de uso
|
|
12
|
+
|
|
13
|
+
### 1. Configuración básica
|
|
14
|
+
|
|
15
|
+
Importa `QWAClient` y crea una instancia con tus credenciales:
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
import { QWAClient } from '@arisnetxsolutions/qwa-sdk';
|
|
19
|
+
|
|
20
|
+
const client = new QWAClient({
|
|
21
|
+
baseUrl: 'https://api.wa.a.arisnetxsolutions.com',
|
|
22
|
+
sessionId: 'c7cb0771-3fb8-4fe4-98b8-34c5f294bd80',
|
|
23
|
+
chatId: '120363040929106526@g.us',
|
|
24
|
+
apiKey: 'owa_k1_...',
|
|
25
|
+
});
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
> **💡 Recomendación:** No hardcodees las credenciales. Usa variables de entorno:
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
const client = new QWAClient({
|
|
32
|
+
baseUrl: process.env.QWA_BASE_URL!,
|
|
33
|
+
sessionId: process.env.QWA_SESSION_ID!,
|
|
34
|
+
chatId: process.env.QWA_CHAT_ID!,
|
|
35
|
+
apiKey: process.env.QWA_API_KEY!,
|
|
36
|
+
});
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### 2. Enviar un mensaje de texto
|
|
40
|
+
|
|
41
|
+
```typescript
|
|
42
|
+
// Forma explícita (con objeto)
|
|
43
|
+
const result = await client.sendText({
|
|
44
|
+
text: '¡Hola, mundo! 👋',
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
console.log(result);
|
|
48
|
+
// ↑ { success: true, message?: string, data?: {...} }
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### 3. Shorthand (solo el texto)
|
|
52
|
+
|
|
53
|
+
Si no necesitas personalizar `chatId` ni `previewUrl`, pasa directamente un `string`:
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
const result = await client.sendText('¡Hola, mundo! 👋');
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
El SDK usa automáticamente el `chatId` que configuraste al crear el cliente.
|
|
60
|
+
|
|
61
|
+
### 4. Enviar a un chat diferente
|
|
62
|
+
|
|
63
|
+
Puedes sobrescribir el `chatId` por mensaje:
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
66
|
+
await client.sendText({
|
|
67
|
+
chatId: '5215512345678@c.us', // chat específico para este mensaje
|
|
68
|
+
text: 'Mensaje para otro destino',
|
|
69
|
+
});
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### 5. Desactivar vista previa de URLs
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
await client.sendText({
|
|
76
|
+
text: 'Visita https://arisnetxsolutions.com',
|
|
77
|
+
previewUrl: false, // no mostrar preview del link
|
|
78
|
+
});
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### 6. Manejo de errores
|
|
82
|
+
|
|
83
|
+
El SDK lanza un error `QWAError` cuando la API responde con un código distinto a 2xx:
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
import { QWAClient, QWAError } from '@arisnetxsolutions/qwa-sdk';
|
|
87
|
+
|
|
88
|
+
const client = new QWAClient({ ... });
|
|
89
|
+
|
|
90
|
+
try {
|
|
91
|
+
const result = await client.sendText('Hola');
|
|
92
|
+
console.log('✅ Enviado:', result);
|
|
93
|
+
} catch (error) {
|
|
94
|
+
if (error instanceof QWAError) {
|
|
95
|
+
console.error('❌ Error de API:', error.message);
|
|
96
|
+
console.error(' Status:', error.statusCode);
|
|
97
|
+
console.error(' Body:', error.body);
|
|
98
|
+
} else {
|
|
99
|
+
console.error('❌ Error de red:', error);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### 7. Ejemplo completo (Node.js + variables de entorno)
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
// app.ts
|
|
108
|
+
import { QWAClient, QWAError } from '@arisnetxsolutions/qwa-sdk';
|
|
109
|
+
|
|
110
|
+
const client = new QWAClient({
|
|
111
|
+
baseUrl: process.env.QWA_BASE_URL!,
|
|
112
|
+
sessionId: process.env.QWA_SESSION_ID!,
|
|
113
|
+
chatId: process.env.QWA_CHAT_ID!,
|
|
114
|
+
apiKey: process.env.QWA_API_KEY!,
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
async function main() {
|
|
118
|
+
try {
|
|
119
|
+
const result = await client.sendText(
|
|
120
|
+
`¡Hola! La hora actual es ${new Date().toLocaleString()}`,
|
|
121
|
+
);
|
|
122
|
+
console.log('✅ Mensaje enviado:', result);
|
|
123
|
+
} catch (error) {
|
|
124
|
+
if (error instanceof QWAError) {
|
|
125
|
+
console.error(`❌ [${error.statusCode}] ${error.message}`);
|
|
126
|
+
} else {
|
|
127
|
+
console.error('❌ Error inesperado:', error);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
main();
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## API Reference
|
|
136
|
+
|
|
137
|
+
### `QWAClient`
|
|
138
|
+
|
|
139
|
+
#### `new QWAClient(config: QWAConfig)`
|
|
140
|
+
|
|
141
|
+
Crea una nueva instancia del cliente.
|
|
142
|
+
|
|
143
|
+
| Campo | Tipo | Descripción |
|
|
144
|
+
|-------------|----------|--------------------------------------------------|
|
|
145
|
+
| `baseUrl` | `string` | URL base de la API de QOpenWA |
|
|
146
|
+
| `sessionId` | `string` | ID de la sesión de WhatsApp |
|
|
147
|
+
| `chatId` | `string` | ID del chat o grupo de WhatsApp por defecto |
|
|
148
|
+
| `apiKey` | `string` | API key para autenticación |
|
|
149
|
+
|
|
150
|
+
> ⚠️ Todos los campos son obligatorios. Si falta alguno, el constructor lanza un error.
|
|
151
|
+
|
|
152
|
+
#### `sendText(payload: SendTextPayload | string): Promise<QWAResponse>`
|
|
153
|
+
|
|
154
|
+
Envía un mensaje de texto al chat especificado (o al configurado por defecto).
|
|
155
|
+
|
|
156
|
+
**Parámetros:**
|
|
157
|
+
|
|
158
|
+
| Parámetro | Tipo | Descripción |
|
|
159
|
+
|------------|-----------------------------|--------------------------------------------------|
|
|
160
|
+
| `payload` | `SendTextPayload \| string` | Mensaje a enviar. Acepta objeto o string directo |
|
|
161
|
+
|
|
162
|
+
**Cuando `payload` es un objeto (`SendTextPayload`):**
|
|
163
|
+
|
|
164
|
+
| Campo | Tipo | Obligatorio | Descripción |
|
|
165
|
+
|-------------|-----------|-------------|------------------------------------------------|
|
|
166
|
+
| `text` | `string` | ✅ Sí | Contenido del mensaje |
|
|
167
|
+
| `chatId` | `string` | ❌ No | ID del chat. Si se omite, usa el del config |
|
|
168
|
+
| `previewUrl`| `boolean` | ❌ No | Vista previa de URLs. Por defecto: `true` |
|
|
169
|
+
|
|
170
|
+
**Respuesta (`QWAResponse`):**
|
|
171
|
+
|
|
172
|
+
```typescript
|
|
173
|
+
// Éxito
|
|
174
|
+
{ success: true, message?: string, data?: Record<string, unknown> }
|
|
175
|
+
|
|
176
|
+
// Error
|
|
177
|
+
{ success: false, error: string, code?: string }
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### `QWAError`
|
|
181
|
+
|
|
182
|
+
Error personalizado lanzado cuando la API responde con un código HTTP de error.
|
|
183
|
+
|
|
184
|
+
| Propiedad | Tipo | Descripción |
|
|
185
|
+
|-------------|----------|----------------------------------|
|
|
186
|
+
| `message` | `string` | Descripción del error |
|
|
187
|
+
| `statusCode`| `number` | Código HTTP de la respuesta |
|
|
188
|
+
| `body` | `unknown`| Cuerpo de la respuesta (si aplica) |
|
|
189
|
+
|
|
190
|
+
## Tipos exportados
|
|
191
|
+
|
|
192
|
+
```typescript
|
|
193
|
+
import type {
|
|
194
|
+
QWAConfig, // Configuración del cliente
|
|
195
|
+
SendTextPayload, // Payload para sendText
|
|
196
|
+
QWAResponse, // Respuesta exitosa o de error
|
|
197
|
+
QWASuccessResponse,// Respuesta exitosa
|
|
198
|
+
QWAErrorResponse, // Respuesta de error
|
|
199
|
+
} from '@arisnetxsolutions/qwa-sdk';
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
## Licencia
|
|
203
|
+
|
|
204
|
+
MIT © Arisnetx Solutions
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/client.ts
|
|
4
|
+
var QWAClient = class {
|
|
5
|
+
config;
|
|
6
|
+
constructor(config) {
|
|
7
|
+
if (!config.baseUrl) throw new Error("baseUrl is required");
|
|
8
|
+
if (!config.sessionId) throw new Error("sessionId is required");
|
|
9
|
+
if (!config.chatId) throw new Error("chatId is required");
|
|
10
|
+
if (!config.apiKey) throw new Error("apiKey is required");
|
|
11
|
+
this.config = {
|
|
12
|
+
...config,
|
|
13
|
+
baseUrl: config.baseUrl.replace(/\/+$/, "")
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Get the HTTP headers used for all requests.
|
|
18
|
+
*/
|
|
19
|
+
get headers() {
|
|
20
|
+
return {
|
|
21
|
+
"Content-Type": "application/json",
|
|
22
|
+
"x-api-key": this.config.apiKey
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Make a POST request to the QOpenWA API.
|
|
27
|
+
*/
|
|
28
|
+
async post(endpoint, body) {
|
|
29
|
+
const url = `${this.config.baseUrl}/api/sessions/${this.config.sessionId}${endpoint}`;
|
|
30
|
+
const response = await fetch(url, {
|
|
31
|
+
method: "POST",
|
|
32
|
+
headers: this.headers,
|
|
33
|
+
body: JSON.stringify(body)
|
|
34
|
+
});
|
|
35
|
+
if (!response.ok) {
|
|
36
|
+
const errorBody = await response.json().catch(() => ({}));
|
|
37
|
+
throw new QWAError(
|
|
38
|
+
`API request failed: ${response.status} ${response.statusText}`,
|
|
39
|
+
response.status,
|
|
40
|
+
errorBody
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
return response.json();
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Send a text message to the configured chat.
|
|
47
|
+
*
|
|
48
|
+
* @param payload - The text message payload. If a string is passed, it will be
|
|
49
|
+
* used as the message text with the configured chatId.
|
|
50
|
+
* @returns The API response.
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```ts
|
|
54
|
+
* await client.sendText({ text: 'Hello, World!' });
|
|
55
|
+
* await client.sendText('Hello, World!'); // shorthand
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
async sendText(payload) {
|
|
59
|
+
const normalized = typeof payload === "string" ? { chatId: this.config.chatId, text: payload } : { ...payload, chatId: payload.chatId ?? this.config.chatId };
|
|
60
|
+
return this.post(
|
|
61
|
+
"/messages/send-text",
|
|
62
|
+
normalized
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
var QWAError = class extends Error {
|
|
67
|
+
statusCode;
|
|
68
|
+
body;
|
|
69
|
+
constructor(message, statusCode, body) {
|
|
70
|
+
super(message);
|
|
71
|
+
this.name = "QWAError";
|
|
72
|
+
this.statusCode = statusCode;
|
|
73
|
+
this.body = body;
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
exports.QWAClient = QWAClient;
|
|
78
|
+
exports.QWAError = QWAError;
|
|
79
|
+
//# sourceMappingURL=index.cjs.map
|
|
80
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/client.ts"],"names":[],"mappings":";;;AAuBO,IAAM,YAAN,MAAgB;AAAA,EACJ,MAAA;AAAA,EAEjB,YAAY,MAAA,EAAmB;AAC7B,IAAA,IAAI,CAAC,MAAA,CAAO,OAAA,EAAS,MAAM,IAAI,MAAM,qBAAqB,CAAA;AAC1D,IAAA,IAAI,CAAC,MAAA,CAAO,SAAA,EAAW,MAAM,IAAI,MAAM,uBAAuB,CAAA;AAC9D,IAAA,IAAI,CAAC,MAAA,CAAO,MAAA,EAAQ,MAAM,IAAI,MAAM,oBAAoB,CAAA;AACxD,IAAA,IAAI,CAAC,MAAA,CAAO,MAAA,EAAQ,MAAM,IAAI,MAAM,oBAAoB,CAAA;AAGxD,IAAA,IAAA,CAAK,MAAA,GAAS;AAAA,MACZ,GAAG,MAAA;AAAA,MACH,OAAA,EAAS,MAAA,CAAO,OAAA,CAAQ,OAAA,CAAQ,QAAQ,EAAE;AAAA,KAC5C;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,IAAY,OAAA,GAAkC;AAC5C,IAAA,OAAO;AAAA,MACL,cAAA,EAAgB,kBAAA;AAAA,MAChB,WAAA,EAAa,KAAK,MAAA,CAAO;AAAA,KAC3B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,IAAA,CACZ,QAAA,EACA,IAAA,EACoB;AACpB,IAAA,MAAM,GAAA,GAAM,CAAA,EAAG,IAAA,CAAK,MAAA,CAAO,OAAO,iBAAiB,IAAA,CAAK,MAAA,CAAO,SAAS,CAAA,EAAG,QAAQ,CAAA,CAAA;AAEnF,IAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,GAAA,EAAK;AAAA,MAChC,MAAA,EAAQ,MAAA;AAAA,MACR,SAAS,IAAA,CAAK,OAAA;AAAA,MACd,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,IAAI;AAAA,KAC1B,CAAA;AAED,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,MAAM,SAAA,GAAY,MAAM,QAAA,CAAS,IAAA,GAAO,KAAA,CAAM,OAAO,EAAC,CAAE,CAAA;AACxD,MAAA,MAAM,IAAI,QAAA;AAAA,QACR,CAAA,oBAAA,EAAuB,QAAA,CAAS,MAAM,CAAA,CAAA,EAAI,SAAS,UAAU,CAAA,CAAA;AAAA,QAC7D,QAAA,CAAS,MAAA;AAAA,QACT;AAAA,OACF;AAAA,IACF;AAEA,IAAA,OAAO,SAAS,IAAA,EAAK;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,MAAM,SACJ,OAAA,EACsB;AACtB,IAAA,MAAM,UAAA,GACJ,OAAO,OAAA,KAAY,QAAA,GACf,EAAE,MAAA,EAAQ,IAAA,CAAK,OAAO,MAAA,EAAQ,IAAA,EAAM,SAAQ,GAC5C,EAAE,GAAG,OAAA,EAAS,MAAA,EAAQ,QAAQ,MAAA,IAAU,IAAA,CAAK,OAAO,MAAA,EAAO;AAEjE,IAAA,OAAO,IAAA,CAAK,IAAA;AAAA,MACV,qBAAA;AAAA,MACA;AAAA,KACF;AAAA,EACF;AACF;AAKO,IAAM,QAAA,GAAN,cAAuB,KAAA,CAAM;AAAA,EAClB,UAAA;AAAA,EACA,IAAA;AAAA,EAEhB,WAAA,CAAY,OAAA,EAAiB,UAAA,EAAoB,IAAA,EAAe;AAC9D,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,IAAA,GAAO,UAAA;AACZ,IAAA,IAAA,CAAK,UAAA,GAAa,UAAA;AAClB,IAAA,IAAA,CAAK,IAAA,GAAO,IAAA;AAAA,EACd;AACF","file":"index.cjs","sourcesContent":["// ═══════════════════════════════════════════════\r\n// QOpenWA Client - Main SDK class\r\n// ═══════════════════════════════════════════════\r\n\r\nimport type { QWAConfig, SendTextPayload, QWAResponse } from './types.js';\r\n\r\n/**\r\n * QOpenWA Client for sending WhatsApp messages.\r\n *\r\n * @example\r\n * ```ts\r\n * import { QWAClient } from '@arisnetxsolutions/qwa-sdk';\r\n *\r\n * const client = new QWAClient({\r\n * baseUrl: 'https://api.wa.a.arisnetxsolutions.com',\r\n * sessionId: 'your-session-id',\r\n * chatId: 'your-chat-id',\r\n * apiKey: 'your-api-key',\r\n * });\r\n *\r\n * await client.sendText({ text: 'Hello from QWA SDK!' });\r\n * ```\r\n */\r\nexport class QWAClient {\r\n private readonly config: QWAConfig;\r\n\r\n constructor(config: QWAConfig) {\r\n if (!config.baseUrl) throw new Error('baseUrl is required');\r\n if (!config.sessionId) throw new Error('sessionId is required');\r\n if (!config.chatId) throw new Error('chatId is required');\r\n if (!config.apiKey) throw new Error('apiKey is required');\r\n\r\n // Normalize baseUrl: remove trailing slash\r\n this.config = {\r\n ...config,\r\n baseUrl: config.baseUrl.replace(/\\/+$/, ''),\r\n };\r\n }\r\n\r\n /**\r\n * Get the HTTP headers used for all requests.\r\n */\r\n private get headers(): Record<string, string> {\r\n return {\r\n 'Content-Type': 'application/json',\r\n 'x-api-key': this.config.apiKey,\r\n };\r\n }\r\n\r\n /**\r\n * Make a POST request to the QOpenWA API.\r\n */\r\n private async post<TBody, TResponse>(\r\n endpoint: string,\r\n body: TBody,\r\n ): Promise<TResponse> {\r\n const url = `${this.config.baseUrl}/api/sessions/${this.config.sessionId}${endpoint}`;\r\n\r\n const response = await fetch(url, {\r\n method: 'POST',\r\n headers: this.headers,\r\n body: JSON.stringify(body),\r\n });\r\n\r\n if (!response.ok) {\r\n const errorBody = await response.json().catch(() => ({}));\r\n throw new QWAError(\r\n `API request failed: ${response.status} ${response.statusText}`,\r\n response.status,\r\n errorBody,\r\n );\r\n }\r\n\r\n return response.json() as Promise<TResponse>;\r\n }\r\n\r\n /**\r\n * Send a text message to the configured chat.\r\n *\r\n * @param payload - The text message payload. If a string is passed, it will be\r\n * used as the message text with the configured chatId.\r\n * @returns The API response.\r\n *\r\n * @example\r\n * ```ts\r\n * await client.sendText({ text: 'Hello, World!' });\r\n * await client.sendText('Hello, World!'); // shorthand\r\n * ```\r\n */\r\n async sendText(\r\n payload: SendTextPayload | string,\r\n ): Promise<QWAResponse> {\r\n const normalized: SendTextPayload =\r\n typeof payload === 'string'\r\n ? { chatId: this.config.chatId, text: payload }\r\n : { ...payload, chatId: payload.chatId ?? this.config.chatId };\r\n\r\n return this.post<SendTextPayload, QWAResponse>(\r\n '/messages/send-text',\r\n normalized,\r\n );\r\n }\r\n}\r\n\r\n/**\r\n * Custom error class for QWA API errors.\r\n */\r\nexport class QWAError extends Error {\r\n public readonly statusCode: number;\r\n public readonly body: unknown;\r\n\r\n constructor(message: string, statusCode: number, body: unknown) {\r\n super(message);\r\n this.name = 'QWAError';\r\n this.statusCode = statusCode;\r\n this.body = body;\r\n }\r\n}\r\n"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/** Configuration options for the QOpenWA client */
|
|
2
|
+
interface QWAConfig {
|
|
3
|
+
/** Base URL of the QOpenWA API (e.g. https://api.wa.a.arisnetxsolutions.com) */
|
|
4
|
+
baseUrl: string;
|
|
5
|
+
/** Session identifier */
|
|
6
|
+
sessionId: string;
|
|
7
|
+
/** WhatsApp chat/group ID */
|
|
8
|
+
chatId: string;
|
|
9
|
+
/** API key for authentication */
|
|
10
|
+
apiKey: string;
|
|
11
|
+
}
|
|
12
|
+
/** Text message request payload */
|
|
13
|
+
interface SendTextPayload {
|
|
14
|
+
/** WhatsApp chat/group ID */
|
|
15
|
+
chatId: string;
|
|
16
|
+
/** Message text content */
|
|
17
|
+
text: string;
|
|
18
|
+
/** Optional: preview URL (default: true) */
|
|
19
|
+
previewUrl?: boolean;
|
|
20
|
+
}
|
|
21
|
+
/** Generic API success response */
|
|
22
|
+
interface QWASuccessResponse {
|
|
23
|
+
success: true;
|
|
24
|
+
message?: string;
|
|
25
|
+
data?: Record<string, unknown>;
|
|
26
|
+
}
|
|
27
|
+
/** Generic API error response */
|
|
28
|
+
interface QWAErrorResponse {
|
|
29
|
+
success: false;
|
|
30
|
+
error: string;
|
|
31
|
+
code?: string;
|
|
32
|
+
}
|
|
33
|
+
/** Union type for API responses */
|
|
34
|
+
type QWAResponse = QWASuccessResponse | QWAErrorResponse;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* QOpenWA Client for sending WhatsApp messages.
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```ts
|
|
41
|
+
* import { QWAClient } from '@arisnetxsolutions/qwa-sdk';
|
|
42
|
+
*
|
|
43
|
+
* const client = new QWAClient({
|
|
44
|
+
* baseUrl: 'https://api.wa.a.arisnetxsolutions.com',
|
|
45
|
+
* sessionId: 'your-session-id',
|
|
46
|
+
* chatId: 'your-chat-id',
|
|
47
|
+
* apiKey: 'your-api-key',
|
|
48
|
+
* });
|
|
49
|
+
*
|
|
50
|
+
* await client.sendText({ text: 'Hello from QWA SDK!' });
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
declare class QWAClient {
|
|
54
|
+
private readonly config;
|
|
55
|
+
constructor(config: QWAConfig);
|
|
56
|
+
/**
|
|
57
|
+
* Get the HTTP headers used for all requests.
|
|
58
|
+
*/
|
|
59
|
+
private get headers();
|
|
60
|
+
/**
|
|
61
|
+
* Make a POST request to the QOpenWA API.
|
|
62
|
+
*/
|
|
63
|
+
private post;
|
|
64
|
+
/**
|
|
65
|
+
* Send a text message to the configured chat.
|
|
66
|
+
*
|
|
67
|
+
* @param payload - The text message payload. If a string is passed, it will be
|
|
68
|
+
* used as the message text with the configured chatId.
|
|
69
|
+
* @returns The API response.
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* ```ts
|
|
73
|
+
* await client.sendText({ text: 'Hello, World!' });
|
|
74
|
+
* await client.sendText('Hello, World!'); // shorthand
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
sendText(payload: SendTextPayload | string): Promise<QWAResponse>;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Custom error class for QWA API errors.
|
|
81
|
+
*/
|
|
82
|
+
declare class QWAError extends Error {
|
|
83
|
+
readonly statusCode: number;
|
|
84
|
+
readonly body: unknown;
|
|
85
|
+
constructor(message: string, statusCode: number, body: unknown);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export { QWAClient, type QWAConfig, QWAError, type QWAErrorResponse, type QWAResponse, type QWASuccessResponse, type SendTextPayload };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/** Configuration options for the QOpenWA client */
|
|
2
|
+
interface QWAConfig {
|
|
3
|
+
/** Base URL of the QOpenWA API (e.g. https://api.wa.a.arisnetxsolutions.com) */
|
|
4
|
+
baseUrl: string;
|
|
5
|
+
/** Session identifier */
|
|
6
|
+
sessionId: string;
|
|
7
|
+
/** WhatsApp chat/group ID */
|
|
8
|
+
chatId: string;
|
|
9
|
+
/** API key for authentication */
|
|
10
|
+
apiKey: string;
|
|
11
|
+
}
|
|
12
|
+
/** Text message request payload */
|
|
13
|
+
interface SendTextPayload {
|
|
14
|
+
/** WhatsApp chat/group ID */
|
|
15
|
+
chatId: string;
|
|
16
|
+
/** Message text content */
|
|
17
|
+
text: string;
|
|
18
|
+
/** Optional: preview URL (default: true) */
|
|
19
|
+
previewUrl?: boolean;
|
|
20
|
+
}
|
|
21
|
+
/** Generic API success response */
|
|
22
|
+
interface QWASuccessResponse {
|
|
23
|
+
success: true;
|
|
24
|
+
message?: string;
|
|
25
|
+
data?: Record<string, unknown>;
|
|
26
|
+
}
|
|
27
|
+
/** Generic API error response */
|
|
28
|
+
interface QWAErrorResponse {
|
|
29
|
+
success: false;
|
|
30
|
+
error: string;
|
|
31
|
+
code?: string;
|
|
32
|
+
}
|
|
33
|
+
/** Union type for API responses */
|
|
34
|
+
type QWAResponse = QWASuccessResponse | QWAErrorResponse;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* QOpenWA Client for sending WhatsApp messages.
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```ts
|
|
41
|
+
* import { QWAClient } from '@arisnetxsolutions/qwa-sdk';
|
|
42
|
+
*
|
|
43
|
+
* const client = new QWAClient({
|
|
44
|
+
* baseUrl: 'https://api.wa.a.arisnetxsolutions.com',
|
|
45
|
+
* sessionId: 'your-session-id',
|
|
46
|
+
* chatId: 'your-chat-id',
|
|
47
|
+
* apiKey: 'your-api-key',
|
|
48
|
+
* });
|
|
49
|
+
*
|
|
50
|
+
* await client.sendText({ text: 'Hello from QWA SDK!' });
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
declare class QWAClient {
|
|
54
|
+
private readonly config;
|
|
55
|
+
constructor(config: QWAConfig);
|
|
56
|
+
/**
|
|
57
|
+
* Get the HTTP headers used for all requests.
|
|
58
|
+
*/
|
|
59
|
+
private get headers();
|
|
60
|
+
/**
|
|
61
|
+
* Make a POST request to the QOpenWA API.
|
|
62
|
+
*/
|
|
63
|
+
private post;
|
|
64
|
+
/**
|
|
65
|
+
* Send a text message to the configured chat.
|
|
66
|
+
*
|
|
67
|
+
* @param payload - The text message payload. If a string is passed, it will be
|
|
68
|
+
* used as the message text with the configured chatId.
|
|
69
|
+
* @returns The API response.
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* ```ts
|
|
73
|
+
* await client.sendText({ text: 'Hello, World!' });
|
|
74
|
+
* await client.sendText('Hello, World!'); // shorthand
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
sendText(payload: SendTextPayload | string): Promise<QWAResponse>;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Custom error class for QWA API errors.
|
|
81
|
+
*/
|
|
82
|
+
declare class QWAError extends Error {
|
|
83
|
+
readonly statusCode: number;
|
|
84
|
+
readonly body: unknown;
|
|
85
|
+
constructor(message: string, statusCode: number, body: unknown);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export { QWAClient, type QWAConfig, QWAError, type QWAErrorResponse, type QWAResponse, type QWASuccessResponse, type SendTextPayload };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
// src/client.ts
|
|
2
|
+
var QWAClient = class {
|
|
3
|
+
config;
|
|
4
|
+
constructor(config) {
|
|
5
|
+
if (!config.baseUrl) throw new Error("baseUrl is required");
|
|
6
|
+
if (!config.sessionId) throw new Error("sessionId is required");
|
|
7
|
+
if (!config.chatId) throw new Error("chatId is required");
|
|
8
|
+
if (!config.apiKey) throw new Error("apiKey is required");
|
|
9
|
+
this.config = {
|
|
10
|
+
...config,
|
|
11
|
+
baseUrl: config.baseUrl.replace(/\/+$/, "")
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Get the HTTP headers used for all requests.
|
|
16
|
+
*/
|
|
17
|
+
get headers() {
|
|
18
|
+
return {
|
|
19
|
+
"Content-Type": "application/json",
|
|
20
|
+
"x-api-key": this.config.apiKey
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Make a POST request to the QOpenWA API.
|
|
25
|
+
*/
|
|
26
|
+
async post(endpoint, body) {
|
|
27
|
+
const url = `${this.config.baseUrl}/api/sessions/${this.config.sessionId}${endpoint}`;
|
|
28
|
+
const response = await fetch(url, {
|
|
29
|
+
method: "POST",
|
|
30
|
+
headers: this.headers,
|
|
31
|
+
body: JSON.stringify(body)
|
|
32
|
+
});
|
|
33
|
+
if (!response.ok) {
|
|
34
|
+
const errorBody = await response.json().catch(() => ({}));
|
|
35
|
+
throw new QWAError(
|
|
36
|
+
`API request failed: ${response.status} ${response.statusText}`,
|
|
37
|
+
response.status,
|
|
38
|
+
errorBody
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
return response.json();
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Send a text message to the configured chat.
|
|
45
|
+
*
|
|
46
|
+
* @param payload - The text message payload. If a string is passed, it will be
|
|
47
|
+
* used as the message text with the configured chatId.
|
|
48
|
+
* @returns The API response.
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```ts
|
|
52
|
+
* await client.sendText({ text: 'Hello, World!' });
|
|
53
|
+
* await client.sendText('Hello, World!'); // shorthand
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
async sendText(payload) {
|
|
57
|
+
const normalized = typeof payload === "string" ? { chatId: this.config.chatId, text: payload } : { ...payload, chatId: payload.chatId ?? this.config.chatId };
|
|
58
|
+
return this.post(
|
|
59
|
+
"/messages/send-text",
|
|
60
|
+
normalized
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
var QWAError = class extends Error {
|
|
65
|
+
statusCode;
|
|
66
|
+
body;
|
|
67
|
+
constructor(message, statusCode, body) {
|
|
68
|
+
super(message);
|
|
69
|
+
this.name = "QWAError";
|
|
70
|
+
this.statusCode = statusCode;
|
|
71
|
+
this.body = body;
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
export { QWAClient, QWAError };
|
|
76
|
+
//# sourceMappingURL=index.js.map
|
|
77
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/client.ts"],"names":[],"mappings":";AAuBO,IAAM,YAAN,MAAgB;AAAA,EACJ,MAAA;AAAA,EAEjB,YAAY,MAAA,EAAmB;AAC7B,IAAA,IAAI,CAAC,MAAA,CAAO,OAAA,EAAS,MAAM,IAAI,MAAM,qBAAqB,CAAA;AAC1D,IAAA,IAAI,CAAC,MAAA,CAAO,SAAA,EAAW,MAAM,IAAI,MAAM,uBAAuB,CAAA;AAC9D,IAAA,IAAI,CAAC,MAAA,CAAO,MAAA,EAAQ,MAAM,IAAI,MAAM,oBAAoB,CAAA;AACxD,IAAA,IAAI,CAAC,MAAA,CAAO,MAAA,EAAQ,MAAM,IAAI,MAAM,oBAAoB,CAAA;AAGxD,IAAA,IAAA,CAAK,MAAA,GAAS;AAAA,MACZ,GAAG,MAAA;AAAA,MACH,OAAA,EAAS,MAAA,CAAO,OAAA,CAAQ,OAAA,CAAQ,QAAQ,EAAE;AAAA,KAC5C;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,IAAY,OAAA,GAAkC;AAC5C,IAAA,OAAO;AAAA,MACL,cAAA,EAAgB,kBAAA;AAAA,MAChB,WAAA,EAAa,KAAK,MAAA,CAAO;AAAA,KAC3B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,IAAA,CACZ,QAAA,EACA,IAAA,EACoB;AACpB,IAAA,MAAM,GAAA,GAAM,CAAA,EAAG,IAAA,CAAK,MAAA,CAAO,OAAO,iBAAiB,IAAA,CAAK,MAAA,CAAO,SAAS,CAAA,EAAG,QAAQ,CAAA,CAAA;AAEnF,IAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,GAAA,EAAK;AAAA,MAChC,MAAA,EAAQ,MAAA;AAAA,MACR,SAAS,IAAA,CAAK,OAAA;AAAA,MACd,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,IAAI;AAAA,KAC1B,CAAA;AAED,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,MAAM,SAAA,GAAY,MAAM,QAAA,CAAS,IAAA,GAAO,KAAA,CAAM,OAAO,EAAC,CAAE,CAAA;AACxD,MAAA,MAAM,IAAI,QAAA;AAAA,QACR,CAAA,oBAAA,EAAuB,QAAA,CAAS,MAAM,CAAA,CAAA,EAAI,SAAS,UAAU,CAAA,CAAA;AAAA,QAC7D,QAAA,CAAS,MAAA;AAAA,QACT;AAAA,OACF;AAAA,IACF;AAEA,IAAA,OAAO,SAAS,IAAA,EAAK;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,MAAM,SACJ,OAAA,EACsB;AACtB,IAAA,MAAM,UAAA,GACJ,OAAO,OAAA,KAAY,QAAA,GACf,EAAE,MAAA,EAAQ,IAAA,CAAK,OAAO,MAAA,EAAQ,IAAA,EAAM,SAAQ,GAC5C,EAAE,GAAG,OAAA,EAAS,MAAA,EAAQ,QAAQ,MAAA,IAAU,IAAA,CAAK,OAAO,MAAA,EAAO;AAEjE,IAAA,OAAO,IAAA,CAAK,IAAA;AAAA,MACV,qBAAA;AAAA,MACA;AAAA,KACF;AAAA,EACF;AACF;AAKO,IAAM,QAAA,GAAN,cAAuB,KAAA,CAAM;AAAA,EAClB,UAAA;AAAA,EACA,IAAA;AAAA,EAEhB,WAAA,CAAY,OAAA,EAAiB,UAAA,EAAoB,IAAA,EAAe;AAC9D,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,IAAA,GAAO,UAAA;AACZ,IAAA,IAAA,CAAK,UAAA,GAAa,UAAA;AAClB,IAAA,IAAA,CAAK,IAAA,GAAO,IAAA;AAAA,EACd;AACF","file":"index.js","sourcesContent":["// ═══════════════════════════════════════════════\r\n// QOpenWA Client - Main SDK class\r\n// ═══════════════════════════════════════════════\r\n\r\nimport type { QWAConfig, SendTextPayload, QWAResponse } from './types.js';\r\n\r\n/**\r\n * QOpenWA Client for sending WhatsApp messages.\r\n *\r\n * @example\r\n * ```ts\r\n * import { QWAClient } from '@arisnetxsolutions/qwa-sdk';\r\n *\r\n * const client = new QWAClient({\r\n * baseUrl: 'https://api.wa.a.arisnetxsolutions.com',\r\n * sessionId: 'your-session-id',\r\n * chatId: 'your-chat-id',\r\n * apiKey: 'your-api-key',\r\n * });\r\n *\r\n * await client.sendText({ text: 'Hello from QWA SDK!' });\r\n * ```\r\n */\r\nexport class QWAClient {\r\n private readonly config: QWAConfig;\r\n\r\n constructor(config: QWAConfig) {\r\n if (!config.baseUrl) throw new Error('baseUrl is required');\r\n if (!config.sessionId) throw new Error('sessionId is required');\r\n if (!config.chatId) throw new Error('chatId is required');\r\n if (!config.apiKey) throw new Error('apiKey is required');\r\n\r\n // Normalize baseUrl: remove trailing slash\r\n this.config = {\r\n ...config,\r\n baseUrl: config.baseUrl.replace(/\\/+$/, ''),\r\n };\r\n }\r\n\r\n /**\r\n * Get the HTTP headers used for all requests.\r\n */\r\n private get headers(): Record<string, string> {\r\n return {\r\n 'Content-Type': 'application/json',\r\n 'x-api-key': this.config.apiKey,\r\n };\r\n }\r\n\r\n /**\r\n * Make a POST request to the QOpenWA API.\r\n */\r\n private async post<TBody, TResponse>(\r\n endpoint: string,\r\n body: TBody,\r\n ): Promise<TResponse> {\r\n const url = `${this.config.baseUrl}/api/sessions/${this.config.sessionId}${endpoint}`;\r\n\r\n const response = await fetch(url, {\r\n method: 'POST',\r\n headers: this.headers,\r\n body: JSON.stringify(body),\r\n });\r\n\r\n if (!response.ok) {\r\n const errorBody = await response.json().catch(() => ({}));\r\n throw new QWAError(\r\n `API request failed: ${response.status} ${response.statusText}`,\r\n response.status,\r\n errorBody,\r\n );\r\n }\r\n\r\n return response.json() as Promise<TResponse>;\r\n }\r\n\r\n /**\r\n * Send a text message to the configured chat.\r\n *\r\n * @param payload - The text message payload. If a string is passed, it will be\r\n * used as the message text with the configured chatId.\r\n * @returns The API response.\r\n *\r\n * @example\r\n * ```ts\r\n * await client.sendText({ text: 'Hello, World!' });\r\n * await client.sendText('Hello, World!'); // shorthand\r\n * ```\r\n */\r\n async sendText(\r\n payload: SendTextPayload | string,\r\n ): Promise<QWAResponse> {\r\n const normalized: SendTextPayload =\r\n typeof payload === 'string'\r\n ? { chatId: this.config.chatId, text: payload }\r\n : { ...payload, chatId: payload.chatId ?? this.config.chatId };\r\n\r\n return this.post<SendTextPayload, QWAResponse>(\r\n '/messages/send-text',\r\n normalized,\r\n );\r\n }\r\n}\r\n\r\n/**\r\n * Custom error class for QWA API errors.\r\n */\r\nexport class QWAError extends Error {\r\n public readonly statusCode: number;\r\n public readonly body: unknown;\r\n\r\n constructor(message: string, statusCode: number, body: unknown) {\r\n super(message);\r\n this.name = 'QWAError';\r\n this.statusCode = statusCode;\r\n this.body = body;\r\n }\r\n}\r\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@arisnetxsolutions/qwa-sdk",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "SDK para la API de QOpenWA - Envío de mensajes de WhatsApp",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"whatsapp",
|
|
7
|
+
"qopenwa",
|
|
8
|
+
"sdk",
|
|
9
|
+
"api",
|
|
10
|
+
"messages"
|
|
11
|
+
],
|
|
12
|
+
"homepage": "https://github.com/arisnetxsolutions/qwa-sdk#readme",
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "git+https://github.com/arisnetxsolutions/qwa-sdk.git"
|
|
16
|
+
},
|
|
17
|
+
"license": "MIT",
|
|
18
|
+
"author": "Arisnetx Solutions",
|
|
19
|
+
"type": "module",
|
|
20
|
+
"exports": {
|
|
21
|
+
".": {
|
|
22
|
+
"import": {
|
|
23
|
+
"types": "./dist/index.d.ts",
|
|
24
|
+
"default": "./dist/index.js"
|
|
25
|
+
},
|
|
26
|
+
"require": {
|
|
27
|
+
"types": "./dist/index.d.cts",
|
|
28
|
+
"default": "./dist/index.cjs"
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"main": "./dist/index.cjs",
|
|
33
|
+
"module": "./dist/index.js",
|
|
34
|
+
"types": "./dist/index.d.ts",
|
|
35
|
+
"files": [
|
|
36
|
+
"dist",
|
|
37
|
+
"README.md",
|
|
38
|
+
"LICENSE"
|
|
39
|
+
],
|
|
40
|
+
"scripts": {
|
|
41
|
+
"build": "tsup",
|
|
42
|
+
"dev": "tsup --watch",
|
|
43
|
+
"prepublishOnly": "npm run build"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"tsup": "^8.2.0",
|
|
47
|
+
"typescript": "^5.5.0"
|
|
48
|
+
},
|
|
49
|
+
"engines": {
|
|
50
|
+
"node": ">=18"
|
|
51
|
+
},
|
|
52
|
+
"publishConfig": {
|
|
53
|
+
"access": "public"
|
|
54
|
+
}
|
|
55
|
+
}
|