@green-api/greenapi-integration 0.5.0 → 0.6.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 +220 -17
- package/README.ru.md +203 -5
- package/dist/core/base-adapter.d.ts +3 -1
- package/dist/core/base-adapter.js +11 -3
- package/dist/core/green-api.client.d.ts +1 -0
- package/dist/core/green-api.client.js +10 -0
- package/dist/core/guard.d.ts +2 -1
- package/dist/core/guard.js +4 -1
- package/dist/core/logger.d.ts +128 -0
- package/dist/core/logger.js +217 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +3 -1
- package/dist/types/types.d.ts +1 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -39,10 +39,12 @@ npm install @green-api/greenapi-integration
|
|
|
39
39
|
The foundation of your integration. Handles message & instance management, and platform-specific logic.
|
|
40
40
|
|
|
41
41
|
```typescript
|
|
42
|
-
abstract class BaseAdapter<TPlatformWebhook, TPlatformMessage> {
|
|
42
|
+
abstract class BaseAdapter<TPlatformWebhook, TPlatformMessage, TUser extends BaseUser = BaseUser, TInstance extends Instance = Instance> {
|
|
43
|
+
private readonly gaLogger = GreenApiLogger.getInstance(this.constructor.name);
|
|
44
|
+
|
|
43
45
|
public constructor(
|
|
44
46
|
transformer: MessageTransformer<TPlatformWebhook, TPlatformMessage>,
|
|
45
|
-
storage: StorageProvider
|
|
47
|
+
storage: StorageProvider<TUser, TInstance>,
|
|
46
48
|
);
|
|
47
49
|
|
|
48
50
|
public abstract createPlatformClient(params: any): Promise<any>;
|
|
@@ -58,8 +60,7 @@ When extending BaseAdapter, your implementation has access to several methods:
|
|
|
58
60
|
##### Webhook Handling
|
|
59
61
|
|
|
60
62
|
These webhook handling methods call your message transformation methods automatically, without the need to use them
|
|
61
|
-
directly in
|
|
62
|
-
your code.
|
|
63
|
+
directly in your code.
|
|
63
64
|
|
|
64
65
|
```typescript
|
|
65
66
|
// Handle webhooks from your platform
|
|
@@ -140,18 +141,23 @@ abstract class MessageTransformer<TPlatformWebhook, TPlatformMessage> {
|
|
|
140
141
|
Interface for data persistence operations.
|
|
141
142
|
|
|
142
143
|
```typescript
|
|
143
|
-
abstract class StorageProvider<
|
|
144
|
-
|
|
144
|
+
abstract class StorageProvider<
|
|
145
|
+
TUser extends BaseUser = BaseUser,
|
|
146
|
+
TInstance extends Instance = Instance,
|
|
147
|
+
TUserCreate extends Record<string, any> = any,
|
|
148
|
+
TUserUpdate extends Record<string, any> = any
|
|
149
|
+
> {
|
|
150
|
+
abstract createInstance(instance: Instance): Promise<TInstance>;
|
|
145
151
|
|
|
146
152
|
abstract getInstance(idInstance: number | bigint): Promise<TInstance | null>;
|
|
147
153
|
|
|
148
154
|
abstract removeInstance(instanceId: number | bigint): Promise<TInstance>;
|
|
149
155
|
|
|
150
|
-
abstract createUser(data:
|
|
156
|
+
abstract createUser(data: TUserCreate): Promise<TUser>;
|
|
151
157
|
|
|
152
158
|
abstract findUser(identifier: string): Promise<TUser | null>;
|
|
153
159
|
|
|
154
|
-
abstract updateUser(identifier: string, data:
|
|
160
|
+
abstract updateUser(identifier: string, data: Partial<TUserUpdate>): Promise<TUser>;
|
|
155
161
|
}
|
|
156
162
|
```
|
|
157
163
|
|
|
@@ -161,6 +167,8 @@ Handles webhook authentication for incoming GREEN-API requests.
|
|
|
161
167
|
|
|
162
168
|
```typescript
|
|
163
169
|
abstract class BaseGreenApiAuthGuard<T extends BaseRequest = BaseRequest> {
|
|
170
|
+
private readonly gaLogger = GreenApiLogger.getInstance(this.constructor.name);
|
|
171
|
+
|
|
164
172
|
constructor(protected storage: StorageProvider);
|
|
165
173
|
|
|
166
174
|
// Validates incoming webhook requests
|
|
@@ -193,7 +201,196 @@ app.post('/webhook', async (req, res) => {
|
|
|
193
201
|
});
|
|
194
202
|
```
|
|
195
203
|
|
|
196
|
-
### 5.
|
|
204
|
+
### 5. GreenApiLogger
|
|
205
|
+
|
|
206
|
+
A structured JSON logger with colored output. Provides consistent logging format across your application with
|
|
207
|
+
proper error handling and serialization support.
|
|
208
|
+
|
|
209
|
+
```typescript
|
|
210
|
+
const logger = GreenApiLogger.getInstance("YourComponent");
|
|
211
|
+
|
|
212
|
+
// Basic logging
|
|
213
|
+
logger.debug("Debug message", {someContext: "value"});
|
|
214
|
+
logger.info("Info message", {userId: 123});
|
|
215
|
+
logger.warn("Warning message", {alert: true});
|
|
216
|
+
logger.error("Error occurred", {errorCode: 500});
|
|
217
|
+
logger.fatal("Fatal error", {critical: true});
|
|
218
|
+
|
|
219
|
+
// Error logging with full context
|
|
220
|
+
try {
|
|
221
|
+
await someOperation();
|
|
222
|
+
} catch (error) {
|
|
223
|
+
logger.logErrorResponse(error, "Operation failed", {
|
|
224
|
+
operationId: "123",
|
|
225
|
+
additionalInfo: "some context"
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
#### Features
|
|
231
|
+
|
|
232
|
+
- Structured JSON logging with consistent format
|
|
233
|
+
- Colored output based on log level (debug=cyan, info=green, warn=yellow, error=red, fatal=magenta)
|
|
234
|
+
- Built-in error handling with stack trace formatting
|
|
235
|
+
- Automatic serialization
|
|
236
|
+
- Framework agnostic - works with any Node.js application
|
|
237
|
+
- Special handling for Axios errors with detailed request/response info
|
|
238
|
+
|
|
239
|
+
#### Log Levels
|
|
240
|
+
|
|
241
|
+
- `debug` - Detailed information for debugging
|
|
242
|
+
- `info` - General information about system operation
|
|
243
|
+
- `warn` - Warning messages for potentially harmful situations
|
|
244
|
+
- `error` - Error messages for serious problems
|
|
245
|
+
- `fatal` - Critical errors that require immediate attention
|
|
246
|
+
- `log` - Alternative to info (for compatibility)
|
|
247
|
+
|
|
248
|
+
#### Output Format
|
|
249
|
+
|
|
250
|
+
```json
|
|
251
|
+
{
|
|
252
|
+
"timestamp": "30/01/2025, 04:34:49",
|
|
253
|
+
"level": "error",
|
|
254
|
+
"context": "CoreService",
|
|
255
|
+
"message": "Operation failed",
|
|
256
|
+
"error": "Failed to process request",
|
|
257
|
+
"stack": [
|
|
258
|
+
"Error: Failed to process request",
|
|
259
|
+
" at CoreService.process (/app/service.js:123:45)",
|
|
260
|
+
" at async Router.handle (/app/router.js:67:89)"
|
|
261
|
+
],
|
|
262
|
+
"additionalContext": {
|
|
263
|
+
"requestId": "abc-123",
|
|
264
|
+
"userId": "user_456"
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
#### Error Handling
|
|
270
|
+
|
|
271
|
+
```typescript
|
|
272
|
+
// Axios error handling
|
|
273
|
+
try {
|
|
274
|
+
await apiRequest();
|
|
275
|
+
} catch (error) {
|
|
276
|
+
logger.logErrorResponse(error, "API Request failed", {
|
|
277
|
+
endpoint: "/users",
|
|
278
|
+
method: "POST"
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
// Will output detailed API error info:
|
|
284
|
+
|
|
285
|
+
```
|
|
286
|
+
{
|
|
287
|
+
"timestamp": "30/01/2025, 04:34:49",
|
|
288
|
+
"level": "error",
|
|
289
|
+
"context": "ApiService",
|
|
290
|
+
"message": "API Request failed - API Error:",
|
|
291
|
+
"status": 400,
|
|
292
|
+
"statusText": "Bad Request",
|
|
293
|
+
"data": { "error": "Invalid input" },
|
|
294
|
+
"url": "https://api.example.com/users",
|
|
295
|
+
"method": "POST",
|
|
296
|
+
"endpoint": "/users"
|
|
297
|
+
}
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
#### Using with Frameworks
|
|
301
|
+
|
|
302
|
+
The logger is framework-agnostic but can be easily integrated with any framework:
|
|
303
|
+
|
|
304
|
+
```typescript
|
|
305
|
+
// NestJS example
|
|
306
|
+
const app = await NestFactory.create(AppModule, {
|
|
307
|
+
logger: GreenApiLogger.getInstance("NestJS")
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
// Express example
|
|
311
|
+
app.use((err, req, res, next) => {
|
|
312
|
+
const logger = GreenApiLogger.getInstance("Express");
|
|
313
|
+
logger.error("Request failed", {
|
|
314
|
+
path: req.path,
|
|
315
|
+
method: req.method,
|
|
316
|
+
error: err.message
|
|
317
|
+
});
|
|
318
|
+
next(err);
|
|
319
|
+
});
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
#### Methods
|
|
323
|
+
|
|
324
|
+
##### Basic Logging Methods
|
|
325
|
+
|
|
326
|
+
- `debug(message: string, context?: Record<string, any>)`: Log debug level message
|
|
327
|
+
- `info(message: string, context?: Record<string, any>)`: Log info level message
|
|
328
|
+
- `warn(message: string, context?: Record<string, any>)`: Log warning level message
|
|
329
|
+
- `error(message: string, context?: Record<string, any>)`: Log error level message
|
|
330
|
+
- `fatal(message: string, context?: Record<string, any>)`: Log fatal level message
|
|
331
|
+
- `log(message: string, context?: string)`: Alternative to info method
|
|
332
|
+
|
|
333
|
+
##### Special Methods
|
|
334
|
+
|
|
335
|
+
- `logErrorResponse(error: any, context: string, additionalContext?: Record<string, any>)`:
|
|
336
|
+
Enhanced error logging with special handling for Axios errors and stack traces
|
|
337
|
+
|
|
338
|
+
##### Utility Methods
|
|
339
|
+
|
|
340
|
+
- `getInstance(context: string = "Global"): GreenApiLogger`: Get or create logger instance for specified context
|
|
341
|
+
|
|
342
|
+
#### Best Practices
|
|
343
|
+
|
|
344
|
+
1. **Use Consistent Context Names**
|
|
345
|
+
|
|
346
|
+
```typescript
|
|
347
|
+
// In your component/service
|
|
348
|
+
private readonly logger = GreenApiLogger.getInstance(YourService.name);
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
2. **Include Relevant Context**
|
|
352
|
+
|
|
353
|
+
```typescript
|
|
354
|
+
logger.info("User action completed", {
|
|
355
|
+
userId: user.id,
|
|
356
|
+
action: "profile_update",
|
|
357
|
+
duration: timeTaken
|
|
358
|
+
});
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
3. **Proper Error Handling**
|
|
362
|
+
|
|
363
|
+
```typescript
|
|
364
|
+
try {
|
|
365
|
+
await complexOperation();
|
|
366
|
+
} catch (error) {
|
|
367
|
+
logger.logErrorResponse(error, "Complex operation failed", {
|
|
368
|
+
operationId: id,
|
|
369
|
+
parameters: params
|
|
370
|
+
});
|
|
371
|
+
}
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
4. **Use Appropriate Log Levels**
|
|
375
|
+
|
|
376
|
+
```typescript
|
|
377
|
+
// Debug for detailed information
|
|
378
|
+
logger.debug("Processing chunk", {chunkId: 123, size: 1024});
|
|
379
|
+
|
|
380
|
+
// Info for general operation
|
|
381
|
+
logger.info("User logged in", {userId: 456});
|
|
382
|
+
|
|
383
|
+
// Warn for potential issues
|
|
384
|
+
logger.warn("High memory usage", {memoryUsage: "85%"});
|
|
385
|
+
|
|
386
|
+
// Error for actual problems
|
|
387
|
+
logger.error("Database connection failed", {dbHost: "primary"});
|
|
388
|
+
|
|
389
|
+
// Fatal for critical issues
|
|
390
|
+
logger.fatal("System shutdown required", {reason: "data corruption"});
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
### 6. GreenApiClient
|
|
197
394
|
|
|
198
395
|
Direct interface to GREEN-API methods.
|
|
199
396
|
|
|
@@ -324,12 +521,16 @@ export class YourStorage extends StorageProvider {
|
|
|
324
521
|
this.db = new PrismaClient();
|
|
325
522
|
}
|
|
326
523
|
|
|
327
|
-
async
|
|
524
|
+
async findUserByEmail(email: string) {
|
|
525
|
+
return this.db.user.findUnique({where: {email}});
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
async createInstance(instance: Instance) {
|
|
328
529
|
return this.db.instance.create({
|
|
329
530
|
data: {
|
|
330
531
|
idInstance: instance.idInstance,
|
|
331
532
|
apiTokenInstance: instance.apiTokenInstance,
|
|
332
|
-
userId,
|
|
533
|
+
userId: instance.userId,
|
|
333
534
|
settings: instance.settings || {},
|
|
334
535
|
},
|
|
335
536
|
});
|
|
@@ -427,6 +628,7 @@ router.post('/instance', async (req, res) => {
|
|
|
427
628
|
throw new BadRequestError('Required fields missing');
|
|
428
629
|
}
|
|
429
630
|
|
|
631
|
+
const user = await storage.findUserByEmail(userEmail);
|
|
430
632
|
const instance = await adapter.createInstance({
|
|
431
633
|
idInstance: Number(idInstance),
|
|
432
634
|
apiTokenInstance,
|
|
@@ -434,8 +636,9 @@ router.post('/instance', async (req, res) => {
|
|
|
434
636
|
webhookUrl: `${process.env.APP_URL}/webhook/green-api`,
|
|
435
637
|
webhookUrlToken: `token_${Date.now()}`,
|
|
436
638
|
incomingWebhook: 'yes'
|
|
437
|
-
}
|
|
438
|
-
|
|
639
|
+
},
|
|
640
|
+
userId: user.id
|
|
641
|
+
});
|
|
439
642
|
|
|
440
643
|
res.status(200).json({
|
|
441
644
|
status: 'ok',
|
|
@@ -845,10 +1048,10 @@ isValidSettingValue('webhookUrl', 'https://example.com') // Returns true
|
|
|
845
1048
|
|
|
846
1049
|
// Clean settings
|
|
847
1050
|
const input = {
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
1051
|
+
webhookUrl: 'https://example.com',
|
|
1052
|
+
outgoingWebhook: 'yes',
|
|
1053
|
+
invalidKey: 'value',
|
|
1054
|
+
delaySendMessagesMilliseconds: 'invalid'
|
|
852
1055
|
}
|
|
853
1056
|
validateAndCleanSettings(input) // Returns { webhookUrl: 'https://example.com', outgoingWebhook: 'yes' }
|
|
854
1057
|
```
|
package/README.ru.md
CHANGED
|
@@ -192,10 +192,202 @@ app.post('/webhook', async (req, res) => {
|
|
|
192
192
|
});
|
|
193
193
|
```
|
|
194
194
|
|
|
195
|
-
### 5.
|
|
195
|
+
### 5. GreenApiLogger
|
|
196
196
|
|
|
197
|
-
|
|
198
|
-
|
|
197
|
+
Структурированный JSON-логгер с цветным выводом. Обеспечивает единый формат логирования в вашем приложении с корректной
|
|
198
|
+
обработкой ошибок и сериализацией.
|
|
199
|
+
|
|
200
|
+
```typescript
|
|
201
|
+
const logger = GreenApiLogger.getInstance("YourComponent");
|
|
202
|
+
|
|
203
|
+
// Базовое логирование
|
|
204
|
+
logger.debug("Debug message", {someContext: "value"});
|
|
205
|
+
logger.info("Info message", {userId: 123});
|
|
206
|
+
logger.warn("Warning message", {alert: true});
|
|
207
|
+
logger.error("Error occurred", {errorCode: 500});
|
|
208
|
+
logger.fatal("Fatal error", {critical: true});
|
|
209
|
+
|
|
210
|
+
// Логирование ошибок с контекстом
|
|
211
|
+
try {
|
|
212
|
+
await someOperation();
|
|
213
|
+
} catch (error) {
|
|
214
|
+
logger.logErrorResponse(error, "Operation failed", {
|
|
215
|
+
operationId: "123",
|
|
216
|
+
additionalInfo: "some context"
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
#### Возможности
|
|
222
|
+
|
|
223
|
+
- Структурированное JSON-логирование в едином формате
|
|
224
|
+
- Цветной вывод в зависимости от уровня лога (debug=голубой, info=зеленый, warn=желтый, error=красный, fatal=пурпурный)
|
|
225
|
+
- Встроенная обработка ошибок с форматированием стека вызовов
|
|
226
|
+
- Автоматическая сериализация
|
|
227
|
+
- Независимость от фреймворка - работает с любым Node.js приложением
|
|
228
|
+
- Специальная обработка ошибок Axios с подробной информацией о запросе/ответе
|
|
229
|
+
|
|
230
|
+
#### Уровни логирования
|
|
231
|
+
|
|
232
|
+
- `debug` - Подробная информация для отладки
|
|
233
|
+
- `info` - Общая информация о работе системы
|
|
234
|
+
- `warn` - Предупреждения о потенциально опасных ситуациях
|
|
235
|
+
- `error` - Сообщения об ошибках
|
|
236
|
+
- `fatal` - Критические ошибки, требующие немедленного внимания
|
|
237
|
+
- `log` - Альтернатива info (для совместимости)
|
|
238
|
+
|
|
239
|
+
#### Формат вывода
|
|
240
|
+
|
|
241
|
+
```json
|
|
242
|
+
{
|
|
243
|
+
"timestamp": "30/01/2025, 04:34:49",
|
|
244
|
+
"level": "error",
|
|
245
|
+
"context": "CoreService",
|
|
246
|
+
"message": "Operation failed",
|
|
247
|
+
"error": "Failed to process request",
|
|
248
|
+
"stack": [
|
|
249
|
+
"Error: Failed to process request",
|
|
250
|
+
" at CoreService.process (/app/service.js:123:45)",
|
|
251
|
+
" at async Router.handle (/app/router.js:67:89)"
|
|
252
|
+
],
|
|
253
|
+
"additionalContext": {
|
|
254
|
+
"requestId": "abc-123",
|
|
255
|
+
"userId": "user_456"
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
#### Обработка ошибок
|
|
261
|
+
|
|
262
|
+
```typescript
|
|
263
|
+
// Обработка ошибок Axios
|
|
264
|
+
try {
|
|
265
|
+
await apiRequest();
|
|
266
|
+
} catch (error) {
|
|
267
|
+
logger.logErrorResponse(error, "API Request failed", {
|
|
268
|
+
endpoint: "/users",
|
|
269
|
+
method: "POST"
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
// Получим подробную информацию об ошибке API:
|
|
275
|
+
|
|
276
|
+
```json
|
|
277
|
+
{
|
|
278
|
+
"timestamp": "30/01/2025, 04:34:49",
|
|
279
|
+
"level": "error",
|
|
280
|
+
"context": "ApiService",
|
|
281
|
+
"message": "API Request failed - API Error:",
|
|
282
|
+
"status": 400,
|
|
283
|
+
"statusText": "Bad Request",
|
|
284
|
+
"data": {
|
|
285
|
+
"error": "Invalid input"
|
|
286
|
+
},
|
|
287
|
+
"url": "https://api.example.com/users",
|
|
288
|
+
"method": "POST",
|
|
289
|
+
"endpoint": "/users"
|
|
290
|
+
}
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
#### Использование с фреймворками
|
|
294
|
+
|
|
295
|
+
Логгер независим от фреймворков, но легко интегрируется с любым из них:
|
|
296
|
+
|
|
297
|
+
```typescript
|
|
298
|
+
// Пример с NestJS
|
|
299
|
+
const app = await NestFactory.create(AppModule, {
|
|
300
|
+
logger: GreenApiLogger.getInstance("NestJS")
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
// Пример с Express
|
|
304
|
+
app.use((err, req, res, next) => {
|
|
305
|
+
const logger = GreenApiLogger.getInstance("Express");
|
|
306
|
+
logger.error("Request failed", {
|
|
307
|
+
path: req.path,
|
|
308
|
+
method: req.method,
|
|
309
|
+
error: err.message
|
|
310
|
+
});
|
|
311
|
+
next(err);
|
|
312
|
+
});
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
#### Методы
|
|
316
|
+
|
|
317
|
+
##### Основные методы логирования
|
|
318
|
+
|
|
319
|
+
- `debug(message: string, context?: Record<string, any>)`: Логирование отладочной информации
|
|
320
|
+
- `info(message: string, context?: Record<string, any>)`: Логирование информационных сообщений
|
|
321
|
+
- `warn(message: string, context?: Record<string, any>)`: Логирование предупреждений
|
|
322
|
+
- `error(message: string, context?: Record<string, any>)`: Логирование ошибок
|
|
323
|
+
- `fatal(message: string, context?: Record<string, any>)`: Логирование критических ошибок
|
|
324
|
+
- `log(message: string, context?: string)`: Альтернатива методу info
|
|
325
|
+
|
|
326
|
+
##### Специальные методы
|
|
327
|
+
|
|
328
|
+
- `logErrorResponse(error: any, context: string, additionalContext?: Record<string, any>)`:
|
|
329
|
+
Расширенное логирование ошибок со специальной обработкой ошибок Axios и стека вызовов
|
|
330
|
+
|
|
331
|
+
##### Вспомогательные методы
|
|
332
|
+
|
|
333
|
+
- `getInstance(context: string = "Global"): GreenApiLogger`: Получение или создание экземпляра логгера для указанного
|
|
334
|
+
контекста
|
|
335
|
+
|
|
336
|
+
#### Лучшие практики
|
|
337
|
+
|
|
338
|
+
1. **Используйте последовательные имена контекста**
|
|
339
|
+
|
|
340
|
+
```typescript
|
|
341
|
+
// В вашем компоненте/сервисе
|
|
342
|
+
private readonly
|
|
343
|
+
logger = GreenApiLogger.getInstance(YourService.name);
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
2. **Включайте релевантный контекст**
|
|
347
|
+
|
|
348
|
+
```typescript
|
|
349
|
+
logger.info("User action completed", {
|
|
350
|
+
userId: user.id,
|
|
351
|
+
action: "profile_update",
|
|
352
|
+
duration: timeTaken
|
|
353
|
+
});
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
3. **Правильная обработка ошибок**
|
|
357
|
+
|
|
358
|
+
```typescript
|
|
359
|
+
try {
|
|
360
|
+
await complexOperation();
|
|
361
|
+
} catch (error) {
|
|
362
|
+
logger.logErrorResponse(error, "Complex operation failed", {
|
|
363
|
+
operationId: id,
|
|
364
|
+
parameters: params
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
4. **Используйте соответствующие уровни логирования**
|
|
370
|
+
|
|
371
|
+
```typescript
|
|
372
|
+
// Debug для детальной информации
|
|
373
|
+
logger.debug("Processing chunk", {chunkId: 123, size: 1024});
|
|
374
|
+
|
|
375
|
+
// Info для общей информации о работе
|
|
376
|
+
logger.info("User logged in", {userId: 456});
|
|
377
|
+
|
|
378
|
+
// Warn для потенциальных проблем
|
|
379
|
+
logger.warn("High memory usage", {memoryUsage: "85%"});
|
|
380
|
+
|
|
381
|
+
// Error для реальных проблем
|
|
382
|
+
logger.error("Database connection failed", {dbHost: "primary"});
|
|
383
|
+
|
|
384
|
+
// Fatal для критических проблем
|
|
385
|
+
logger.fatal("System shutdown required", {reason: "data corruption"});
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
### 6. GreenApiClient
|
|
389
|
+
|
|
390
|
+
Прямой интерфейс к методам GREEN-API.
|
|
199
391
|
|
|
200
392
|
```typescript
|
|
201
393
|
const client = new GreenApiClient({
|
|
@@ -209,7 +401,7 @@ await client.getAuthorizationCode(phoneNumber);
|
|
|
209
401
|
await client.getQR();
|
|
210
402
|
```
|
|
211
403
|
|
|
212
|
-
## Руководство разработчика
|
|
404
|
+
## Руководство для разработчика
|
|
213
405
|
|
|
214
406
|
Это руководство проведет вас через процесс создания вашей первой интеграции с WhatsApp шлюзом GREEN-API.
|
|
215
407
|
|
|
@@ -615,7 +807,13 @@ interface SimplePlatformMessage {
|
|
|
615
807
|
### simple-transformer.ts
|
|
616
808
|
|
|
617
809
|
```typescript
|
|
618
|
-
import {
|
|
810
|
+
import {
|
|
811
|
+
MessageTransformer,
|
|
812
|
+
Message,
|
|
813
|
+
GreenApiWebhook,
|
|
814
|
+
formatPhoneNumber,
|
|
815
|
+
IntegrationError
|
|
816
|
+
} from '@green-api/greenapi-integration';
|
|
619
817
|
|
|
620
818
|
export class SimpleTransformer extends MessageTransformer<SimplePlatformWebhook, SimplePlatformMessage> {
|
|
621
819
|
toPlatformMessage(webhook: GreenApiWebhook): SimplePlatformMessage {
|
|
@@ -2,6 +2,7 @@ import { GreenApiClient } from "./green-api.client";
|
|
|
2
2
|
import { MessageTransformer } from "./message-transformer";
|
|
3
3
|
import { BaseUser, ForwardMessagesResponse, GreenApiWebhook, Instance, SendResponse, StateInstanceWebhook, WebhookType } from "../types/types";
|
|
4
4
|
import { StorageProvider } from "./storage-provider";
|
|
5
|
+
import { GreenApiLogger } from "./logger";
|
|
5
6
|
/**
|
|
6
7
|
* Base adapter for platform integrations with GREEN-API.
|
|
7
8
|
* This class handles the core integration logic between your platform and GREEN-API's WhatsApp gateway.
|
|
@@ -29,13 +30,14 @@ import { StorageProvider } from "./storage-provider";
|
|
|
29
30
|
export declare abstract class BaseAdapter<TPlatformWebhook, TPlatformMessage, TUser extends BaseUser = BaseUser, TInstance extends Instance = Instance> {
|
|
30
31
|
protected transformer: MessageTransformer<TPlatformWebhook, TPlatformMessage>;
|
|
31
32
|
protected storage: StorageProvider<TUser, TInstance>;
|
|
33
|
+
protected readonly gaLogger: GreenApiLogger;
|
|
32
34
|
/**
|
|
33
35
|
* Creates an instance of BaseAdapter.
|
|
34
36
|
*
|
|
35
37
|
* @param transformer - Message transformer for converting between platform and GREEN-API formats
|
|
36
38
|
* @param storage - Storage provider for user and instance data
|
|
37
39
|
*/
|
|
38
|
-
constructor(transformer: MessageTransformer<TPlatformWebhook, TPlatformMessage>, storage: StorageProvider<TUser, TInstance>);
|
|
40
|
+
protected constructor(transformer: MessageTransformer<TPlatformWebhook, TPlatformMessage>, storage: StorageProvider<TUser, TInstance>);
|
|
39
41
|
/**
|
|
40
42
|
* Sends a message to your platform. This method must be implemented to define how
|
|
41
43
|
* messages are sent to your specific platform.
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.BaseAdapter = void 0;
|
|
4
4
|
const green_api_client_1 = require("./green-api.client");
|
|
5
5
|
const errors_1 = require("./errors");
|
|
6
|
+
const logger_1 = require("./logger");
|
|
6
7
|
/**
|
|
7
8
|
* Base adapter for platform integrations with GREEN-API.
|
|
8
9
|
* This class handles the core integration logic between your platform and GREEN-API's WhatsApp gateway.
|
|
@@ -37,6 +38,7 @@ class BaseAdapter {
|
|
|
37
38
|
constructor(transformer, storage) {
|
|
38
39
|
this.transformer = transformer;
|
|
39
40
|
this.storage = storage;
|
|
41
|
+
this.gaLogger = logger_1.GreenApiLogger.getInstance(this.constructor.name);
|
|
40
42
|
}
|
|
41
43
|
/**
|
|
42
44
|
* Handles instance state change webhooks from GREEN-API.
|
|
@@ -86,6 +88,7 @@ class BaseAdapter {
|
|
|
86
88
|
*/
|
|
87
89
|
async handlePlatformWebhook(message, idInstance) {
|
|
88
90
|
try {
|
|
91
|
+
this.gaLogger.info("Handling platform webhook", { platformWebhook: message, idInstance });
|
|
89
92
|
const instance = await this.storage.getInstance(idInstance);
|
|
90
93
|
if (!instance) {
|
|
91
94
|
throw new errors_1.IntegrationError("Instance not found", "INSTANCE_NOT_FOUND", 404);
|
|
@@ -124,10 +127,15 @@ class BaseAdapter {
|
|
|
124
127
|
* @throws {IntegrationError} If webhook handling fails
|
|
125
128
|
*/
|
|
126
129
|
async handleGreenApiWebhook(webhook, allowedTypes) {
|
|
127
|
-
if (!allowedTypes.includes(webhook.typeWebhook)) {
|
|
128
|
-
return;
|
|
129
|
-
}
|
|
130
130
|
try {
|
|
131
|
+
this.gaLogger.info("Handling GREEN-API webhook", { webhook, allowedTypes });
|
|
132
|
+
if (!allowedTypes.includes(webhook.typeWebhook)) {
|
|
133
|
+
this.gaLogger.warn(`Skipping GREEN-API webhook because the ${webhook.typeWebhook} is not allowed`, {
|
|
134
|
+
webhook,
|
|
135
|
+
allowedTypes,
|
|
136
|
+
});
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
131
139
|
if (webhook.typeWebhook === "stateInstanceChanged") {
|
|
132
140
|
await this.handleStateInstanceWebhook(webhook);
|
|
133
141
|
}
|
|
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.GreenApiClient = void 0;
|
|
7
7
|
const axios_1 = __importDefault(require("axios"));
|
|
8
8
|
const errors_1 = require("./errors");
|
|
9
|
+
const logger_1 = require("./logger");
|
|
9
10
|
/**
|
|
10
11
|
* Client for direct interaction with GREEN-API's WhatsApp gateway.
|
|
11
12
|
* Provides methods for sending messages, managing instances, and handling files.
|
|
@@ -35,6 +36,7 @@ class GreenApiClient {
|
|
|
35
36
|
constructor(instance) {
|
|
36
37
|
this.instance = instance;
|
|
37
38
|
this.baseUrl = "https://api.green-api.com";
|
|
39
|
+
this.gaLogger = logger_1.GreenApiLogger.getInstance(GreenApiClient.name);
|
|
38
40
|
this.client = axios_1.default.create({
|
|
39
41
|
baseURL: this.buildUrl(),
|
|
40
42
|
});
|
|
@@ -47,6 +49,14 @@ class GreenApiClient {
|
|
|
47
49
|
}
|
|
48
50
|
async makeRequest(method, endpoint, data, queryParams, config) {
|
|
49
51
|
try {
|
|
52
|
+
this.gaLogger.info("Making a request", {
|
|
53
|
+
idInstance: this.instance.idInstance,
|
|
54
|
+
endpoint,
|
|
55
|
+
method,
|
|
56
|
+
data,
|
|
57
|
+
queryParams,
|
|
58
|
+
config,
|
|
59
|
+
});
|
|
50
60
|
const url = this.buildEndpoint(endpoint) + (queryParams ? "?" + new URLSearchParams(Object.entries(queryParams).map(([key, value]) => [key, value.toString()])).toString() : "");
|
|
51
61
|
const response = await (method === "get"
|
|
52
62
|
? this.client.get(url, config)
|
package/dist/core/guard.d.ts
CHANGED
|
@@ -31,12 +31,13 @@ import { StorageProvider } from "./storage-provider";
|
|
|
31
31
|
*/
|
|
32
32
|
export declare abstract class BaseGreenApiAuthGuard<T extends BaseRequest = BaseRequest> {
|
|
33
33
|
protected storage: StorageProvider;
|
|
34
|
+
private readonly gaLogger;
|
|
34
35
|
/**
|
|
35
36
|
* Creates an instance of BaseGreenApiAuthGuard.
|
|
36
37
|
*
|
|
37
38
|
* @param storage - Storage provider for accessing instance data
|
|
38
39
|
*/
|
|
39
|
-
constructor(storage: StorageProvider);
|
|
40
|
+
protected constructor(storage: StorageProvider);
|
|
40
41
|
/**
|
|
41
42
|
* Validates an incoming webhook request.
|
|
42
43
|
* Checks for presence of authorization token and validates it against instance settings.
|
package/dist/core/guard.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.BaseGreenApiAuthGuard = void 0;
|
|
4
4
|
const errors_1 = require("./errors");
|
|
5
|
+
const logger_1 = require("./logger");
|
|
5
6
|
/**
|
|
6
7
|
* Base authentication guard for validating incoming GREEN-API webhooks.
|
|
7
8
|
* Ensures that webhooks are authenticated and come from valid instances.
|
|
@@ -39,6 +40,7 @@ class BaseGreenApiAuthGuard {
|
|
|
39
40
|
*/
|
|
40
41
|
constructor(storage) {
|
|
41
42
|
this.storage = storage;
|
|
43
|
+
this.gaLogger = logger_1.GreenApiLogger.getInstance(this.constructor.name);
|
|
42
44
|
}
|
|
43
45
|
/**
|
|
44
46
|
* Validates an incoming webhook request.
|
|
@@ -56,13 +58,14 @@ class BaseGreenApiAuthGuard {
|
|
|
56
58
|
if (!token) {
|
|
57
59
|
throw new errors_1.AuthenticationError("Authentication header is missing");
|
|
58
60
|
}
|
|
61
|
+
this.gaLogger.info("Request from GREEN-API", { body: request.body });
|
|
59
62
|
const idInstance = request.body?.instanceData?.idInstance;
|
|
60
63
|
if (!idInstance) {
|
|
61
64
|
throw new errors_1.AuthenticationError("Invalid webhook format");
|
|
62
65
|
}
|
|
63
66
|
const instance = await this.storage.getInstance(idInstance);
|
|
64
67
|
if (!instance) {
|
|
65
|
-
throw new errors_1.AuthenticationError(
|
|
68
|
+
throw new errors_1.AuthenticationError(`No instance with such ID ${idInstance}`);
|
|
66
69
|
}
|
|
67
70
|
if (instance.settings?.webhookUrlToken !== token.split(" ")[1]) {
|
|
68
71
|
throw new errors_1.AuthenticationError("Invalid token");
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Logger for GREEN-API integration library.
|
|
3
|
+
* Provides structured JSON logging with colored output and error handling.
|
|
4
|
+
* Uses singleton pattern to maintain consistent logging instances across the application.
|
|
5
|
+
*
|
|
6
|
+
* @category Core
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* const logger = GreenApiLogger.getInstance("MyComponent");
|
|
11
|
+
*
|
|
12
|
+
* // Basic logging
|
|
13
|
+
* logger.info("Operation successful", { userId: 123 });
|
|
14
|
+
*
|
|
15
|
+
* // Error logging
|
|
16
|
+
* try {
|
|
17
|
+
* // ... some code
|
|
18
|
+
* } catch (error) {
|
|
19
|
+
* logger.logErrorResponse(error, "Failed to process request");
|
|
20
|
+
* }
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export declare class GreenApiLogger {
|
|
24
|
+
private readonly context;
|
|
25
|
+
private static instances;
|
|
26
|
+
private readonly colors;
|
|
27
|
+
/**
|
|
28
|
+
* Private constructor to enforce singleton pattern
|
|
29
|
+
* @param context - The context (usually component name) for this logger instance
|
|
30
|
+
*/
|
|
31
|
+
private constructor();
|
|
32
|
+
/**
|
|
33
|
+
* Gets a logger instance for the specified context.
|
|
34
|
+
* Creates a new instance if one doesn't exist, otherwise returns existing instance.
|
|
35
|
+
*
|
|
36
|
+
* @param context - The context for the logger (default: "Global")
|
|
37
|
+
* @returns Logger instance for the specified context
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```typescript
|
|
41
|
+
* const logger = GreenApiLogger.getInstance("MyService");
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
static getInstance(context?: string): GreenApiLogger;
|
|
45
|
+
/**
|
|
46
|
+
* Formats timestamp in locale-specific format
|
|
47
|
+
* @returns Formatted timestamp string
|
|
48
|
+
* @private
|
|
49
|
+
*/
|
|
50
|
+
private formatTimestamp;
|
|
51
|
+
/**
|
|
52
|
+
* Sanitizes values for JSON serialization.
|
|
53
|
+
* Handles special cases like Error objects and BigInt values.
|
|
54
|
+
*
|
|
55
|
+
* @param value - Value to sanitize
|
|
56
|
+
* @returns Sanitized value safe for JSON serialization
|
|
57
|
+
* @private
|
|
58
|
+
*/
|
|
59
|
+
private sanitizeValue;
|
|
60
|
+
/**
|
|
61
|
+
* Creates and outputs a log entry
|
|
62
|
+
* @param level - Log level
|
|
63
|
+
* @param message - Log message
|
|
64
|
+
* @param additionalContext - Additional context data
|
|
65
|
+
* @private
|
|
66
|
+
*/
|
|
67
|
+
private logEntry;
|
|
68
|
+
/**
|
|
69
|
+
* Logs a debug message
|
|
70
|
+
* @param message - Debug message
|
|
71
|
+
* @param context - Additional context data
|
|
72
|
+
*/
|
|
73
|
+
debug(message: string, context?: Record<string, any>): void;
|
|
74
|
+
/**
|
|
75
|
+
* Logs an info message
|
|
76
|
+
* @param message - Info message
|
|
77
|
+
* @param context - Additional context data
|
|
78
|
+
*/
|
|
79
|
+
info(message: string, context?: Record<string, any>): void;
|
|
80
|
+
/**
|
|
81
|
+
* Logs a warning message
|
|
82
|
+
* @param message - Warning message
|
|
83
|
+
* @param context - Additional context data
|
|
84
|
+
*/
|
|
85
|
+
warn(message: string, context?: Record<string, any>): void;
|
|
86
|
+
/**
|
|
87
|
+
* Logs an error message
|
|
88
|
+
* @param message - Error message
|
|
89
|
+
* @param context - Additional context data
|
|
90
|
+
*/
|
|
91
|
+
error(message: string, context?: Record<string, any>): void;
|
|
92
|
+
/**
|
|
93
|
+
* Alternative method for logging info messages
|
|
94
|
+
* @param message - Log message
|
|
95
|
+
* @param context - Context string
|
|
96
|
+
*/
|
|
97
|
+
log(message: string, context?: string): void;
|
|
98
|
+
/**
|
|
99
|
+
* Logs a verbose debug message
|
|
100
|
+
* @param message - Debug message
|
|
101
|
+
* @param context - Context string
|
|
102
|
+
*/
|
|
103
|
+
verbose(message: string, context?: string): void;
|
|
104
|
+
/**
|
|
105
|
+
* Logs a fatal error message
|
|
106
|
+
* @param message - Fatal error message
|
|
107
|
+
* @param context - Additional context data
|
|
108
|
+
*/
|
|
109
|
+
fatal(message: string, context?: Record<string, any>): void;
|
|
110
|
+
/**
|
|
111
|
+
* Logs detailed error information, handling both Axios errors and regular errors.
|
|
112
|
+
* Particularly useful for API errors and exceptions.
|
|
113
|
+
*
|
|
114
|
+
* @param error - Error object (Axios error or regular error)
|
|
115
|
+
* @param context - Error context description
|
|
116
|
+
* @param additionalContext - Additional context data
|
|
117
|
+
*
|
|
118
|
+
* @example
|
|
119
|
+
* ```typescript
|
|
120
|
+
* try {
|
|
121
|
+
* await api.request();
|
|
122
|
+
* } catch (error) {
|
|
123
|
+
* logger.logErrorResponse(error, "API Request failed", { requestId: "123" });
|
|
124
|
+
* }
|
|
125
|
+
* ```
|
|
126
|
+
*/
|
|
127
|
+
logErrorResponse(error: any, context: string, additionalContext?: Record<string, any>): void;
|
|
128
|
+
}
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.GreenApiLogger = void 0;
|
|
7
|
+
const axios_1 = __importDefault(require("axios"));
|
|
8
|
+
/**
|
|
9
|
+
* Logger for GREEN-API integration library.
|
|
10
|
+
* Provides structured JSON logging with colored output and error handling.
|
|
11
|
+
* Uses singleton pattern to maintain consistent logging instances across the application.
|
|
12
|
+
*
|
|
13
|
+
* @category Core
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* const logger = GreenApiLogger.getInstance("MyComponent");
|
|
18
|
+
*
|
|
19
|
+
* // Basic logging
|
|
20
|
+
* logger.info("Operation successful", { userId: 123 });
|
|
21
|
+
*
|
|
22
|
+
* // Error logging
|
|
23
|
+
* try {
|
|
24
|
+
* // ... some code
|
|
25
|
+
* } catch (error) {
|
|
26
|
+
* logger.logErrorResponse(error, "Failed to process request");
|
|
27
|
+
* }
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
class GreenApiLogger {
|
|
31
|
+
/**
|
|
32
|
+
* Private constructor to enforce singleton pattern
|
|
33
|
+
* @param context - The context (usually component name) for this logger instance
|
|
34
|
+
*/
|
|
35
|
+
constructor(context) {
|
|
36
|
+
this.context = context;
|
|
37
|
+
this.colors = {
|
|
38
|
+
log: "\x1b[32m", // Same as info (green)
|
|
39
|
+
debug: "\x1b[36m", // Cyan
|
|
40
|
+
info: "\x1b[32m", // Green
|
|
41
|
+
warn: "\x1b[33m", // Yellow
|
|
42
|
+
error: "\x1b[31m", // Red
|
|
43
|
+
fatal: "\x1b[35m", // Magenta/Purple for fatal
|
|
44
|
+
reset: "\x1b[0m", // Reset
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Gets a logger instance for the specified context.
|
|
49
|
+
* Creates a new instance if one doesn't exist, otherwise returns existing instance.
|
|
50
|
+
*
|
|
51
|
+
* @param context - The context for the logger (default: "Global")
|
|
52
|
+
* @returns Logger instance for the specified context
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```typescript
|
|
56
|
+
* const logger = GreenApiLogger.getInstance("MyService");
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
59
|
+
static getInstance(context = "Global") {
|
|
60
|
+
if (!GreenApiLogger.instances.has(context)) {
|
|
61
|
+
GreenApiLogger.instances.set(context, new GreenApiLogger(context));
|
|
62
|
+
}
|
|
63
|
+
return GreenApiLogger.instances.get(context);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Formats timestamp in locale-specific format
|
|
67
|
+
* @returns Formatted timestamp string
|
|
68
|
+
* @private
|
|
69
|
+
*/
|
|
70
|
+
formatTimestamp() {
|
|
71
|
+
return new Date().toLocaleString("en-GB");
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Sanitizes values for JSON serialization.
|
|
75
|
+
* Handles special cases like Error objects and BigInt values.
|
|
76
|
+
*
|
|
77
|
+
* @param value - Value to sanitize
|
|
78
|
+
* @returns Sanitized value safe for JSON serialization
|
|
79
|
+
* @private
|
|
80
|
+
*/
|
|
81
|
+
sanitizeValue(value) {
|
|
82
|
+
if (value instanceof Error) {
|
|
83
|
+
return {
|
|
84
|
+
message: value.message,
|
|
85
|
+
stack: value.stack?.split("\n").map(line => line.trim()),
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
if (typeof value === "bigint") {
|
|
89
|
+
return value.toString();
|
|
90
|
+
}
|
|
91
|
+
if (Array.isArray(value)) {
|
|
92
|
+
return value.map(item => this.sanitizeValue(item));
|
|
93
|
+
}
|
|
94
|
+
if (value && typeof value === "object") {
|
|
95
|
+
return Object.fromEntries(Object.entries(value).map(([key, val]) => [key, this.sanitizeValue(val)]));
|
|
96
|
+
}
|
|
97
|
+
return value;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Creates and outputs a log entry
|
|
101
|
+
* @param level - Log level
|
|
102
|
+
* @param message - Log message
|
|
103
|
+
* @param additionalContext - Additional context data
|
|
104
|
+
* @private
|
|
105
|
+
*/
|
|
106
|
+
logEntry(level, message, additionalContext = {}) {
|
|
107
|
+
const entry = {
|
|
108
|
+
timestamp: this.formatTimestamp(),
|
|
109
|
+
level,
|
|
110
|
+
context: this.context,
|
|
111
|
+
message,
|
|
112
|
+
...this.sanitizeValue(additionalContext),
|
|
113
|
+
};
|
|
114
|
+
const color = this.colors[level];
|
|
115
|
+
const jsonString = JSON.stringify(entry);
|
|
116
|
+
console.log(`${color}${jsonString}${this.colors.reset}`);
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Logs a debug message
|
|
120
|
+
* @param message - Debug message
|
|
121
|
+
* @param context - Additional context data
|
|
122
|
+
*/
|
|
123
|
+
debug(message, context = {}) {
|
|
124
|
+
this.logEntry("debug", message, context);
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Logs an info message
|
|
128
|
+
* @param message - Info message
|
|
129
|
+
* @param context - Additional context data
|
|
130
|
+
*/
|
|
131
|
+
info(message, context = {}) {
|
|
132
|
+
this.logEntry("info", message, context);
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Logs a warning message
|
|
136
|
+
* @param message - Warning message
|
|
137
|
+
* @param context - Additional context data
|
|
138
|
+
*/
|
|
139
|
+
warn(message, context = {}) {
|
|
140
|
+
this.logEntry("warn", message, context);
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Logs an error message
|
|
144
|
+
* @param message - Error message
|
|
145
|
+
* @param context - Additional context data
|
|
146
|
+
*/
|
|
147
|
+
error(message, context = {}) {
|
|
148
|
+
this.logEntry("error", message, context);
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Alternative method for logging info messages
|
|
152
|
+
* @param message - Log message
|
|
153
|
+
* @param context - Context string
|
|
154
|
+
*/
|
|
155
|
+
log(message, context) {
|
|
156
|
+
this.logEntry("info", message, { context });
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Logs a verbose debug message
|
|
160
|
+
* @param message - Debug message
|
|
161
|
+
* @param context - Context string
|
|
162
|
+
*/
|
|
163
|
+
verbose(message, context) {
|
|
164
|
+
this.logEntry("debug", message, { context, level: "verbose" });
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Logs a fatal error message
|
|
168
|
+
* @param message - Fatal error message
|
|
169
|
+
* @param context - Additional context data
|
|
170
|
+
*/
|
|
171
|
+
fatal(message, context = {}) {
|
|
172
|
+
this.logEntry("error", message, context);
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Logs detailed error information, handling both Axios errors and regular errors.
|
|
176
|
+
* Particularly useful for API errors and exceptions.
|
|
177
|
+
*
|
|
178
|
+
* @param error - Error object (Axios error or regular error)
|
|
179
|
+
* @param context - Error context description
|
|
180
|
+
* @param additionalContext - Additional context data
|
|
181
|
+
*
|
|
182
|
+
* @example
|
|
183
|
+
* ```typescript
|
|
184
|
+
* try {
|
|
185
|
+
* await api.request();
|
|
186
|
+
* } catch (error) {
|
|
187
|
+
* logger.logErrorResponse(error, "API Request failed", { requestId: "123" });
|
|
188
|
+
* }
|
|
189
|
+
* ```
|
|
190
|
+
*/
|
|
191
|
+
logErrorResponse(error, context, additionalContext = {}) {
|
|
192
|
+
if (axios_1.default.isAxiosError(error)) {
|
|
193
|
+
const axiosError = error;
|
|
194
|
+
this.error(`${context} - API Error:`, {
|
|
195
|
+
status: axiosError.response?.status,
|
|
196
|
+
statusText: axiosError.response?.statusText,
|
|
197
|
+
data: axiosError.response?.data,
|
|
198
|
+
url: axiosError.config?.url,
|
|
199
|
+
method: axiosError.config?.method,
|
|
200
|
+
headers: axiosError.response?.headers,
|
|
201
|
+
timestamp: new Date().toISOString(),
|
|
202
|
+
...additionalContext,
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
const errorObject = {
|
|
207
|
+
message: error instanceof Error ? error.message : String(error),
|
|
208
|
+
stack: error instanceof Error ? error.stack?.split("\n").map(line => line.trim()) : undefined,
|
|
209
|
+
timestamp: new Date().toISOString(),
|
|
210
|
+
...additionalContext,
|
|
211
|
+
};
|
|
212
|
+
this.error(`${context} - Non-API Error:`, errorObject);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
exports.GreenApiLogger = GreenApiLogger;
|
|
217
|
+
GreenApiLogger.instances = new Map();
|
package/dist/index.d.ts
CHANGED
|
@@ -4,5 +4,6 @@ export { GreenApiClient } from "./core/green-api.client";
|
|
|
4
4
|
export { MessageTransformer } from "./core/message-transformer";
|
|
5
5
|
export { BaseGreenApiAuthGuard } from "./core/guard";
|
|
6
6
|
export { StorageProvider } from "./core/storage-provider";
|
|
7
|
+
export { GreenApiLogger } from "./core/logger";
|
|
7
8
|
export * from "./utils/helpers";
|
|
8
9
|
export * from "./core/errors";
|
package/dist/index.js
CHANGED
|
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.StorageProvider = exports.BaseGreenApiAuthGuard = exports.MessageTransformer = exports.GreenApiClient = exports.BaseAdapter = void 0;
|
|
17
|
+
exports.GreenApiLogger = exports.StorageProvider = exports.BaseGreenApiAuthGuard = exports.MessageTransformer = exports.GreenApiClient = exports.BaseAdapter = void 0;
|
|
18
18
|
__exportStar(require("./types/types"), exports);
|
|
19
19
|
var base_adapter_1 = require("./core/base-adapter");
|
|
20
20
|
Object.defineProperty(exports, "BaseAdapter", { enumerable: true, get: function () { return base_adapter_1.BaseAdapter; } });
|
|
@@ -26,5 +26,7 @@ var guard_1 = require("./core/guard");
|
|
|
26
26
|
Object.defineProperty(exports, "BaseGreenApiAuthGuard", { enumerable: true, get: function () { return guard_1.BaseGreenApiAuthGuard; } });
|
|
27
27
|
var storage_provider_1 = require("./core/storage-provider");
|
|
28
28
|
Object.defineProperty(exports, "StorageProvider", { enumerable: true, get: function () { return storage_provider_1.StorageProvider; } });
|
|
29
|
+
var logger_1 = require("./core/logger");
|
|
30
|
+
Object.defineProperty(exports, "GreenApiLogger", { enumerable: true, get: function () { return logger_1.GreenApiLogger; } });
|
|
29
31
|
__exportStar(require("./utils/helpers"), exports);
|
|
30
32
|
__exportStar(require("./core/errors"), exports);
|
package/dist/types/types.d.ts
CHANGED
|
@@ -191,7 +191,7 @@ export interface PollMessageData {
|
|
|
191
191
|
options: PollOption[];
|
|
192
192
|
multipleAnswers: boolean;
|
|
193
193
|
}
|
|
194
|
-
type QuotedMessage = {
|
|
194
|
+
export type QuotedMessage = {
|
|
195
195
|
stanzaId: string;
|
|
196
196
|
participant: string;
|
|
197
197
|
typeMessage: MessageType;
|
|
@@ -542,4 +542,3 @@ export interface BaseUser {
|
|
|
542
542
|
id: number | bigint;
|
|
543
543
|
[key: string]: any;
|
|
544
544
|
}
|
|
545
|
-
export {};
|