@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 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"]}
@@ -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 };
@@ -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
+ }