@green-api/greenapi-integration 0.7.0 → 0.7.2

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.ru.md CHANGED
@@ -1,4 +1,4 @@
1
- [# Универсальная интеграционная платформа для GREEN-API
1
+ # Универсальная интеграционная платформа для GREEN-API
2
2
 
3
3
  ## Поддержка
4
4
 
@@ -24,10 +24,9 @@
24
24
 
25
25
  - [Установка](#установка)
26
26
  - [Основные компоненты](#основные-компоненты)
27
- - [Руководство разработчика](#руководство-разработчика)
27
+ - [Руководство для разработчика](#руководство-для-разработчика)
28
28
  - [Рабочий пример](#рабочий-пример)
29
29
  - [Реальные примеры](#реальные-примеры)
30
- - [Лучшие практики](#лучшие-практики)
31
30
 
32
31
  ## Установка
33
32
 
@@ -43,14 +42,14 @@ npm install @green-api/greenapi-integration
43
42
 
44
43
  ```typescript
45
44
  abstract class BaseAdapter<TPlatformWebhook, TPlatformMessage> {
46
- public constructor(
47
- transformer: MessageTransformer<TPlatformWebhook, TPlatformMessage>,
48
- storage: StorageProvider
49
- );
45
+ public constructor(
46
+ transformer: MessageTransformer<TPlatformWebhook, TPlatformMessage>,
47
+ storage: StorageProvider
48
+ );
50
49
 
51
- public abstract createPlatformClient(params: any): Promise<any>;
50
+ public abstract createPlatformClient(params: any): Promise<any>;
52
51
 
53
- public abstract sendToPlatform(message: TPlatformMessage, instance: TInstance): Promise<void>;
52
+ public abstract sendToPlatform(message: TPlatformMessage, instance: TInstance): Promise<void>;
54
53
  }
55
54
  ```
56
55
 
@@ -100,28 +99,28 @@ await adapter.updateUser(userEmail, updateData);
100
99
  ```typescript
101
100
  // Конечная точка для вебхуков платформы
102
101
  app.post('/webhook/platform', async (req, res) => {
103
- try {
104
- await adapter.handlePlatformWebhook(req.body, instanceId);
105
- res.status(200).send();
106
- } catch (error) {
107
- console.error('Не удалось обработать вебхук платформы:', error);
108
- res.status(500).send();
109
- }
102
+ try {
103
+ await adapter.handlePlatformWebhook(req.body, instanceId);
104
+ res.status(200).send();
105
+ } catch (error) {
106
+ console.error('Не удалось обработать вебхук платформы:', error);
107
+ res.status(500).send();
108
+ }
110
109
  });
111
110
 
112
111
  // Конечная точка для вебхуков GREEN-API
113
112
  app.post('/webhook/green-api', async (req, res) => {
114
- try {
115
- // Обработка определенных типов вебхуков
116
- await adapter.handleGreenApiWebhook(req.body, [
117
- 'incomingMessageReceived',
118
- 'outgoingMessageStatus'
119
- ]);
120
- res.status(200).send();
121
- } catch (error) {
122
- console.error('Не удалось обработать вебхук GREEN-API:', error);
123
- res.status(500).send();
124
- }
113
+ try {
114
+ // Обработка определенных типов вебхуков
115
+ await adapter.handleGreenApiWebhook(req.body, [
116
+ 'incomingMessageReceived',
117
+ 'outgoingMessageStatus'
118
+ ]);
119
+ res.status(200).send();
120
+ } catch (error) {
121
+ console.error('Не удалось обработать вебхук GREEN-API:', error);
122
+ res.status(500).send();
123
+ }
125
124
  });
126
125
  ```
127
126
 
@@ -131,9 +130,9 @@ app.post('/webhook/green-api', async (req, res) => {
131
130
 
132
131
  ```typescript
133
132
  abstract class MessageTransformer<TPlatformWebhook, TPlatformMessage> {
134
- abstract toPlatformMessage(webhook: GreenApiWebhook): TPlatformMessage;
133
+ abstract toPlatformMessage(webhook: GreenApiWebhook): TPlatformMessage;
135
134
 
136
- abstract toGreenApiMessage(message: TPlatformWebhook): Message;
135
+ abstract toGreenApiMessage(message: TPlatformWebhook): Message;
137
136
  }
138
137
  ```
139
138
 
@@ -143,17 +142,17 @@ abstract class MessageTransformer<TPlatformWebhook, TPlatformMessage> {
143
142
 
144
143
  ```typescript
145
144
  abstract class StorageProvider<TUser extends BaseUser = BaseUser, TInstance extends BaseInstance = Instance> {
146
- abstract createInstance(instance: BaseInstance, userId: bigint | number): Promise<TInstance>;
145
+ abstract createInstance(instance: BaseInstance, userId: bigint | number): Promise<TInstance>;
147
146
 
148
- abstract getInstance(idInstance: number | bigint): Promise<TInstance | null>;
147
+ abstract getInstance(idInstance: number | bigint): Promise<TInstance | null>;
149
148
 
150
- abstract removeInstance(instanceId: number | bigint): Promise<TInstance>;
149
+ abstract removeInstance(instanceId: number | bigint): Promise<TInstance>;
151
150
 
152
- abstract createUser(data: any): Promise<TUser>;
151
+ abstract createUser(data: any): Promise<TUser>;
153
152
 
154
- abstract findUser(identifier: string): Promise<TUser | null>;
153
+ abstract findUser(identifier: string): Promise<TUser | null>;
155
154
 
156
- abstract updateUser(identifier: string, data: any): Promise<TUser>;
155
+ abstract updateUser(identifier: string, data: any): Promise<TUser>;
157
156
  }
158
157
  ```
159
158
 
@@ -163,10 +162,10 @@ abstract class StorageProvider<TUser extends BaseUser = BaseUser, TInstance exte
163
162
 
164
163
  ```typescript
165
164
  abstract class BaseGreenApiAuthGuard<T extends BaseRequest = BaseRequest> {
166
- constructor(protected storage: StorageProvider);
165
+ constructor(protected storage: StorageProvider);
167
166
 
168
- // Валидация входящих вебхуков
169
- async validateRequest(request: T): Promise<boolean>;
167
+ // Валидация входящих вебхуков
168
+ async validateRequest(request: T): Promise<boolean>;
170
169
  }
171
170
  ```
172
171
 
@@ -174,24 +173,24 @@ abstract class BaseGreenApiAuthGuard<T extends BaseRequest = BaseRequest> {
174
173
 
175
174
  ```typescript
176
175
  class YourAuthGuard extends BaseGreenApiAuthGuard<YourRequest> {
177
- constructor(storage: StorageProvider) {
178
- super(storage);
179
- }
176
+ constructor(storage: StorageProvider) {
177
+ super(storage);
178
+ }
180
179
  }
181
180
 
182
181
  // Использование с Express
183
182
  app.post('/webhook', async (req, res) => {
184
- const guard = new YourAuthGuard(storage);
185
- try {
186
- await guard.validateRequest(req);
187
- // Обработка вебхука ...
188
- } catch (error) {
189
- if (error instanceof AuthenticationError) {
190
- res.status(401).json({error: error.message});
191
- return;
192
- }
193
- res.status(500).json({error: 'Internal server error'});
194
- }
183
+ const guard = new YourAuthGuard(storage);
184
+ try {
185
+ await guard.validateRequest(req);
186
+ // Обработка вебхука ...
187
+ } catch (error) {
188
+ if (error instanceof AuthenticationError) {
189
+ res.status(401).json({error: error.message});
190
+ return;
191
+ }
192
+ res.status(500).json({error: 'Internal server error'});
193
+ }
195
194
  });
196
195
  ```
197
196
 
@@ -212,12 +211,12 @@ logger.fatal("Fatal error", {critical: true});
212
211
 
213
212
  // Логирование ошибок с контекстом
214
213
  try {
215
- await someOperation();
214
+ await someOperation();
216
215
  } catch (error) {
217
- logger.logErrorResponse(error, "Operation failed", {
218
- operationId: "123",
219
- additionalInfo: "some context"
220
- });
216
+ logger.logErrorResponse(error, "Operation failed", {
217
+ operationId: "123",
218
+ additionalInfo: "some context"
219
+ });
221
220
  }
222
221
  ```
223
222
 
@@ -243,20 +242,20 @@ try {
243
242
 
244
243
  ```json
245
244
  {
246
- "timestamp": "30/01/2025, 04:34:49",
247
- "level": "error",
248
- "context": "CoreService",
249
- "message": "Operation failed",
250
- "error": "Failed to process request",
251
- "stack": [
252
- "Error: Failed to process request",
253
- " at CoreService.process (/app/service.js:123:45)",
254
- " at async Router.handle (/app/router.js:67:89)"
255
- ],
256
- "additionalContext": {
257
- "requestId": "abc-123",
258
- "userId": "user_456"
259
- }
245
+ "timestamp": "30/01/2025, 04:34:49",
246
+ "level": "error",
247
+ "context": "CoreService",
248
+ "message": "Operation failed",
249
+ "error": "Failed to process request",
250
+ "stack": [
251
+ "Error: Failed to process request",
252
+ " at CoreService.process (/app/service.js:123:45)",
253
+ " at async Router.handle (/app/router.js:67:89)"
254
+ ],
255
+ "additionalContext": {
256
+ "requestId": "abc-123",
257
+ "userId": "user_456"
258
+ }
260
259
  }
261
260
  ```
262
261
 
@@ -265,12 +264,12 @@ try {
265
264
  ```typescript
266
265
  // Обработка ошибок Axios
267
266
  try {
268
- await apiRequest();
267
+ await apiRequest();
269
268
  } catch (error) {
270
- logger.logErrorResponse(error, "API Request failed", {
271
- endpoint: "/users",
272
- method: "POST"
273
- });
269
+ logger.logErrorResponse(error, "API Request failed", {
270
+ endpoint: "/users",
271
+ method: "POST"
272
+ });
274
273
  }
275
274
  ```
276
275
 
@@ -278,18 +277,18 @@ try {
278
277
 
279
278
  ```json
280
279
  {
281
- "timestamp": "30/01/2025, 04:34:49",
282
- "level": "error",
283
- "context": "ApiService",
284
- "message": "API Request failed - API Error:",
285
- "status": 400,
286
- "statusText": "Bad Request",
287
- "data": {
288
- "error": "Invalid input"
289
- },
290
- "url": "https://api.example.com/users",
291
- "method": "POST",
292
- "endpoint": "/users"
280
+ "timestamp": "30/01/2025, 04:34:49",
281
+ "level": "error",
282
+ "context": "ApiService",
283
+ "message": "API Request failed - API Error:",
284
+ "status": 400,
285
+ "statusText": "Bad Request",
286
+ "data": {
287
+ "error": "Invalid input"
288
+ },
289
+ "url": "https://api.example.com/users",
290
+ "method": "POST",
291
+ "endpoint": "/users"
293
292
  }
294
293
  ```
295
294
 
@@ -300,18 +299,18 @@ try {
300
299
  ```typescript
301
300
  // Пример с NestJS
302
301
  const app = await NestFactory.create(AppModule, {
303
- logger: GreenApiLogger.getInstance("NestJS")
302
+ logger: GreenApiLogger.getInstance("NestJS")
304
303
  });
305
304
 
306
305
  // Пример с Express
307
306
  app.use((err, req, res, next) => {
308
- const logger = GreenApiLogger.getInstance("Express");
309
- logger.error("Request failed", {
310
- path: req.path,
311
- method: req.method,
312
- error: err.message
313
- });
314
- next(err);
307
+ const logger = GreenApiLogger.getInstance("Express");
308
+ logger.error("Request failed", {
309
+ path: req.path,
310
+ method: req.method,
311
+ error: err.message
312
+ });
313
+ next(err);
315
314
  });
316
315
  ```
317
316
 
@@ -325,7 +324,7 @@ app.use((err, req, res, next) => {
325
324
  ```typescript
326
325
  // main.ts
327
326
  const app = await NestFactory.create(AppModule, {
328
- logger: false // Отключение логера NestJS
327
+ logger: false // Отключение логера NestJS
329
328
  });
330
329
  ```
331
330
 
@@ -356,69 +355,17 @@ gaLogger = GreenApiLogger.getInstance(YourClass.name);
356
355
  - `getInstance(context: string = "Global"): GreenApiLogger`: Получение или создание экземпляра логгера для указанного
357
356
  контекста
358
357
 
359
- #### Лучшие практики
360
-
361
- 1. **Используйте последовательные имена контекста**
362
-
363
- ```typescript
364
- // В вашем компоненте/сервисе
365
- private readonly
366
- logger = GreenApiLogger.getInstance(YourService.name);
367
- ```
368
-
369
- 2. **Включайте релевантный контекст**
370
-
371
- ```typescript
372
- logger.info("User action completed", {
373
- userId: user.id,
374
- action: "profile_update",
375
- duration: timeTaken
376
- });
377
- ```
378
-
379
- 3. **Правильная обработка ошибок**
380
-
381
- ```typescript
382
- try {
383
- await complexOperation();
384
- } catch (error) {
385
- logger.logErrorResponse(error, "Complex operation failed", {
386
- operationId: id,
387
- parameters: params
388
- });
389
- }
390
- ```
391
-
392
- 4. **Используйте соответствующие уровни логирования**
393
-
394
- ```typescript
395
- // Debug для детальной информации
396
- logger.debug("Processing chunk", {chunkId: 123, size: 1024});
397
-
398
- // Info для общей информации о работе
399
- logger.info("User logged in", {userId: 456});
400
-
401
- // Warn для потенциальных проблем
402
- logger.warn("High memory usage", {memoryUsage: "85%"});
403
-
404
- // Error для реальных проблем
405
- logger.error("Database connection failed", {dbHost: "primary"});
406
-
407
- // Fatal для критических проблем
408
- logger.fatal("System shutdown required", {reason: "data corruption"});
409
- ```
410
-
411
358
  ### 6. GreenApiClient
412
359
 
413
360
  Прямой интерфейс к методам GREEN-API.
414
361
 
415
362
  ```typescript
416
363
  const client = new GreenApiClient({
417
- idInstance: 'your_instance_id',
418
- apiTokenInstance: 'your_token'
364
+ idInstance: 'your_instance_id',
365
+ apiTokenInstance: 'your_token'
419
366
  });
420
367
 
421
- // Примеры специальных операций:
368
+ // Примеры вызовы методов:
422
369
  await client.setProfilePicture(fileBlob);
423
370
  await client.getAuthorizationCode(phoneNumber);
424
371
  await client.getQR();
@@ -480,17 +427,17 @@ graph TB
480
427
  ```typescript
481
428
  // types/types.ts
482
429
  export interface YourPlatformWebhook {
483
- id: string;
484
- from: string;
485
- message: string;
486
- timestamp: number;
487
- // Добавьте другие поля, специфичные для вашей платформы
430
+ id: string;
431
+ from: string;
432
+ message: string;
433
+ timestamp: number;
434
+ // Добавьте другие поля, специфичные для вашей платформы
488
435
  }
489
436
 
490
437
  export interface YourPlatformMessage {
491
- recipient: string;
492
- content: string;
493
- // Добавьте другие поля, специфичные для вашей платформы
438
+ recipient: string;
439
+ content: string;
440
+ // Добавьте другие поля, специфичные для вашей платформы
494
441
  }
495
442
  ```
496
443
 
@@ -504,22 +451,22 @@ import { MessageTransformer, Message, GreenApiWebhook } from '@green-api/greenap
504
451
  import { YourPlatformWebhook, YourPlatformMessage } from '../types/types';
505
452
 
506
453
  export class YourTransformer extends MessageTransformer<YourPlatformWebhook, YourPlatformMessage> {
507
- toPlatformMessage(webhook: GreenApiWebhook): YourPlatformMessage {
508
- // Преобразование вебхука GREEN-API в формат вашей платформы
509
- return {
510
- recipient: webhook.senderData.sender,
511
- content: webhook.messageData.textMessageData?.textMessage || '',
512
- };
513
- }
514
-
515
- toGreenApiMessage(message: YourPlatformWebhook): Message {
516
- // Преобразование вебхука вашей платформы в формат GREEN-API
517
- return {
518
- type: 'text',
519
- chatId: message.from,
520
- message: message.message,
521
- };
522
- }
454
+ toPlatformMessage(webhook: GreenApiWebhook): YourPlatformMessage {
455
+ // Преобразование вебхука GREEN-API в формат вашей платформы
456
+ return {
457
+ recipient: webhook.senderData.sender,
458
+ content: webhook.messageData.textMessageData?.textMessage || '',
459
+ };
460
+ }
461
+
462
+ toGreenApiMessage(message: YourPlatformWebhook): Message {
463
+ // Преобразование вебхука вашей платформы в формат GREEN-API
464
+ return {
465
+ type: 'text',
466
+ chatId: message.from,
467
+ message: message.message,
468
+ };
469
+ }
523
470
  }
524
471
  ```
525
472
 
@@ -534,24 +481,24 @@ import { StorageProvider, BaseUser, Instance, Settings } from '@green-api/greena
534
481
  import { PrismaClient } from '@prisma/client'; // Or your database client
535
482
 
536
483
  export class YourStorage extends StorageProvider {
537
- private db: PrismaClient;
538
-
539
- constructor() {
540
- this.db = new PrismaClient();
541
- }
542
-
543
- async createInstance(instance: Instance, userId: bigint) {
544
- return this.db.instance.create({
545
- data: {
546
- idInstance: instance.idInstance,
547
- apiTokenInstance: instance.apiTokenInstance,
548
- userId,
549
- settings: instance.settings || {},
550
- },
551
- });
552
- }
553
-
554
- // Остальные методы
484
+ private db: PrismaClient;
485
+
486
+ constructor() {
487
+ this.db = new PrismaClient();
488
+ }
489
+
490
+ async createInstance(instance: Instance, userId: bigint) {
491
+ return this.db.instance.create({
492
+ data: {
493
+ idInstance: instance.idInstance,
494
+ apiTokenInstance: instance.apiTokenInstance,
495
+ userId,
496
+ settings: instance.settings || {},
497
+ },
498
+ });
499
+ }
500
+
501
+ // Остальные методы
555
502
  }
556
503
  ```
557
504
 
@@ -566,17 +513,17 @@ import { YourPlatformClient } from 'your-platform-sdk';
566
513
  import { YourPlatformWebhook, YourPlatformMessage } from '../types/types';
567
514
 
568
515
  export class YourAdapter extends BaseAdapter<YourPlatformWebhook, YourPlatformMessage> {
569
- async createPlatformClient(config: { apiKey: string, apiUrl: string }) {
570
- return new YourPlatformClient({
571
- baseUrl: config.apiUrl,
572
- apiKey: config.apiKey,
573
- });
574
- }
575
-
576
- async sendToPlatform(message: YourPlatformMessage, instance: Instance) {
577
- const client = await this.createPlatformClient(instance.config);
578
- await client.sendMessage(message);
579
- }
516
+ async createPlatformClient(config: { apiKey: string, apiUrl: string }) {
517
+ return new YourPlatformClient({
518
+ baseUrl: config.apiUrl,
519
+ apiKey: config.apiKey,
520
+ });
521
+ }
522
+
523
+ async sendToPlatform(message: YourPlatformMessage, instance: Instance) {
524
+ const client = await this.createPlatformClient(instance.config);
525
+ await client.sendMessage(message);
526
+ }
580
527
  }
581
528
  ```
582
529
 
@@ -597,72 +544,72 @@ const transformer = new YourTransformer();
597
544
  const adapter = new YourAdapter(transformer, storage);
598
545
 
599
546
  class WebhookGuard extends BaseGreenApiAuthGuard {
600
- constructor(storage: StorageProvider) {
601
- super(storage);
602
- }
547
+ constructor(storage: StorageProvider) {
548
+ super(storage);
549
+ }
603
550
  }
604
551
 
605
552
  const guard = new WebhookGuard(storage);
606
553
 
607
554
  // Эндпоинты для вебхуков
608
555
  router.post('/green-api', async (req, res) => {
609
- try {
610
- // Проверка вебхука
611
- await guard.validateRequest(req);
612
-
613
- // Обработка вебхука после проверки.
614
- // В списке вторым параметром укажите типы вебхуков, которые необходимо обработать
615
- await adapter.handleGreenApiWebhook(req.body, ['incomingMessageReceived']);
616
- res.status(200).json({status: 'ok'});
617
- } catch (error) {
618
- if (error instanceof AuthenticationError) {
619
- res.status(401).json({error: 'Ошибка аутентификации'});
620
- return;
621
- }
622
- console.error('Ошибка обработки вебхука:', error);
623
- res.status(500).json({error: 'Внутренняя ошибка сервера'});
624
- }
556
+ try {
557
+ // Проверка вебхука
558
+ await guard.validateRequest(req);
559
+
560
+ // Обработка вебхука после проверки.
561
+ // В списке вторым параметром укажите типы вебхуков, которые необходимо обработать
562
+ await adapter.handleGreenApiWebhook(req.body, ['incomingMessageReceived']);
563
+ res.status(200).json({status: 'ok'});
564
+ } catch (error) {
565
+ if (error instanceof AuthenticationError) {
566
+ res.status(401).json({error: 'Ошибка аутентификации'});
567
+ return;
568
+ }
569
+ console.error('Ошибка обработки вебхука:', error);
570
+ res.status(500).json({error: 'Внутренняя ошибка сервера'});
571
+ }
625
572
  });
626
573
 
627
574
  router.post('/platform', async (req, res) => {
628
- try {
629
- const instanceId = req.query.instanceId;
630
- await adapter.handlePlatformWebhook(req.body, instanceId);
631
- res.status(200).json({status: 'ok'});
632
- } catch (error) {
633
- console.error('Ошибка обработки вебхука платформы:', error);
634
- res.status(500).json({error: 'Внутренняя ошибка сервера'});
635
- }
575
+ try {
576
+ const instanceId = req.query.instanceId;
577
+ await adapter.handlePlatformWebhook(req.body, instanceId);
578
+ res.status(200).json({status: 'ok'});
579
+ } catch (error) {
580
+ console.error('Ошибка обработки вебхука платформы:', error);
581
+ res.status(500).json({error: 'Внутренняя ошибка сервера'});
582
+ }
636
583
  });
637
584
 
638
585
  router.post('/instance', async (req, res) => {
639
- try {
640
- const {idInstance, apiTokenInstance, userEmail} = req.body;
641
-
642
- if (!idInstance || !apiTokenInstance || !userEmail) {
643
- throw new BadRequestError('Отсутствуют обязательные поля');
644
- }
645
-
646
- const instance = await adapter.createInstance({
647
- idInstance: Number(idInstance),
648
- apiTokenInstance,
649
- settings: {
650
- webhookUrl: `${process.env.APP_URL}/webhook/green-api`,
651
- webhookUrlToken: `token_${Date.now()}`,
652
- incomingWebhook: 'yes'
653
- }
654
- }, userEmail);
655
-
656
- res.status(200).json({
657
- status: 'ok',
658
- data: instance,
659
- message: 'Инстанс успешно создан. Подождите 2 минуты для применения настроек.'
660
- });
661
-
662
- } catch (error) {
663
- console.error('Ошибка создания инстанса:', error);
664
- res.status(500).json({error: 'Не удалось создать инстанс'});
665
- }
586
+ try {
587
+ const {idInstance, apiTokenInstance, userEmail} = req.body;
588
+
589
+ if (!idInstance || !apiTokenInstance || !userEmail) {
590
+ throw new BadRequestError('Отсутствуют обязательные поля');
591
+ }
592
+
593
+ const instance = await adapter.createInstance({
594
+ idInstance: Number(idInstance),
595
+ apiTokenInstance,
596
+ settings: {
597
+ webhookUrl: `${process.env.APP_URL}/webhook/green-api`,
598
+ webhookUrlToken: `token_${Date.now()}`,
599
+ incomingWebhook: 'yes'
600
+ }
601
+ }, userEmail);
602
+
603
+ res.status(200).json({
604
+ status: 'ok',
605
+ data: instance,
606
+ message: 'Инстанс успешно создан. Подождите 2 минуты для применения настроек.'
607
+ });
608
+
609
+ } catch (error) {
610
+ console.error('Ошибка создания инстанса:', error);
611
+ res.status(500).json({error: 'Не удалось создать инстанс'});
612
+ }
666
613
  });
667
614
 
668
615
  export default router;
@@ -686,25 +633,25 @@ import { YourStorage } from './core/storage';
686
633
  dotenv.config();
687
634
 
688
635
  async function bootstrap() {
689
- // Инициализация компонентов
690
- const storage = new YourStorage();
691
- const transformer = new YourTransformer();
692
- const adapter = new YourAdapter(transformer, storage);
636
+ // Инициализация компонентов
637
+ const storage = new YourStorage();
638
+ const transformer = new YourTransformer();
639
+ const adapter = new YourAdapter(transformer, storage);
693
640
 
694
- // Создание Express приложения
695
- const app = express();
696
- app.use(bodyParser.json());
641
+ // Создание Express приложения
642
+ const app = express();
643
+ app.use(bodyParser.json());
697
644
 
698
- // Настройка маршрутов для вебхуков
699
- app.use('/webhook', webhookRouter);
645
+ // Настройка маршрутов для вебхуков
646
+ app.use('/webhook', webhookRouter);
700
647
 
701
- // Запуск сервера
702
- const port = process.env.PORT || 3000;
703
- app.listen(port, () => {
704
- console.log(`Сервер запущен на порту ${port}`);
705
- });
648
+ // Запуск сервера
649
+ const port = process.env.PORT || 3000;
650
+ app.listen(port, () => {
651
+ console.log(`Сервер запущен на порту ${port}`);
652
+ });
706
653
 
707
- console.log('Интеграционная платформа готова!');
654
+ console.log('Интеграционная платформа готова!');
708
655
  }
709
656
 
710
657
  // Обработка ошибок
@@ -720,10 +667,10 @@ import { AppModule } from './app.module';
720
667
  import helmet from 'helmet';
721
668
 
722
669
  async function bootstrap() {
723
- const app = await NestFactory.create(AppModule);
724
- app.setGlobalPrefix('api');
725
- app.use(helmet());
726
- await app.listen(process.env.PORT ?? 3000);
670
+ const app = await NestFactory.create(AppModule);
671
+ app.setGlobalPrefix('api');
672
+ app.use(helmet());
673
+ await app.listen(process.env.PORT ?? 3000);
727
674
  }
728
675
 
729
676
  bootstrap();
@@ -735,20 +682,20 @@ bootstrap();
735
682
 
736
683
  ```json
737
684
  {
738
- "name": "greenapi-integration-yourplatform",
739
- "version": "1.0.0",
740
- "main": "dist/index.js",
741
- "types": "dist/index.d.ts",
742
- "scripts": {
743
- "build": "tsc",
744
- "prepublishOnly": "npm run build"
745
- },
746
- "dependencies": {
747
- "@green-api/greenapi-integration": "^0.4.0",
748
- "@prisma/client": "^5.0.0",
749
- "express": "^4.18.2"
750
- // другие зависимости
751
- }
685
+ "name": "greenapi-integration-yourplatform",
686
+ "version": "1.0.0",
687
+ "main": "dist/index.js",
688
+ "types": "dist/index.d.ts",
689
+ "scripts": {
690
+ "build": "tsc",
691
+ "prepublishOnly": "npm run build"
692
+ },
693
+ "dependencies": {
694
+ "@green-api/greenapi-integration": "^0.4.0",
695
+ "@prisma/client": "^5.0.0",
696
+ "express": "^4.18.2"
697
+ // другие зависимости
698
+ }
752
699
  }
753
700
  ```
754
701
 
@@ -814,16 +761,16 @@ examples/
814
761
 
815
762
  ```typescript
816
763
  interface SimplePlatformWebhook {
817
- messageId: string;
818
- from: string;
819
- text: string;
820
- timestamp: number;
764
+ messageId: string;
765
+ from: string;
766
+ text: string;
767
+ timestamp: number;
821
768
  }
822
769
 
823
770
  interface SimplePlatformMessage {
824
- to: string;
825
- content: string;
826
- replyTo?: string;
771
+ to: string;
772
+ content: string;
773
+ replyTo?: string;
827
774
  }
828
775
  ```
829
776
 
@@ -831,35 +778,35 @@ interface SimplePlatformMessage {
831
778
 
832
779
  ```typescript
833
780
  import {
834
- MessageTransformer,
835
- Message,
836
- GreenApiWebhook,
837
- formatPhoneNumber,
838
- IntegrationError
781
+ MessageTransformer,
782
+ Message,
783
+ GreenApiWebhook,
784
+ formatPhoneNumber,
785
+ IntegrationError
839
786
  } from '@green-api/greenapi-integration';
840
787
 
841
788
  export class SimpleTransformer extends MessageTransformer<SimplePlatformWebhook, SimplePlatformMessage> {
842
- toPlatformMessage(webhook: GreenApiWebhook): SimplePlatformMessage {
843
- if (webhook.typeWebhook === "incomingMessageReceived") {
844
- if (webhook.messageData.typeMessage !== "extendedTextMessage") {
845
- throw new IntegrationError("Поддерживаются только текстовые сообщения", "BAD_REQUEST_ERROR", 400);
846
- }
847
-
848
- return {
849
- to: webhook.senderData.sender,
850
- content: webhook.messageData.extendedTextMessageData?.text || "",
851
- };
852
- }
853
- throw new IntegrationError("Поддерживаются только вебхуки вида incomingMessageReceived", "INTEGRATION_ERROR", 500);
854
- }
855
-
856
- toGreenApiMessage(message: SimplePlatformWebhook): Message {
857
- return {
858
- type: 'text',
859
- chatId: formatPhoneNumber(message.from),
860
- message: message.text,
861
- };
862
- }
789
+ toPlatformMessage(webhook: GreenApiWebhook): SimplePlatformMessage {
790
+ if (webhook.typeWebhook === "incomingMessageReceived") {
791
+ if (webhook.messageData.typeMessage !== "extendedTextMessage") {
792
+ throw new IntegrationError("Поддерживаются только текстовые сообщения", "BAD_REQUEST_ERROR", 400);
793
+ }
794
+
795
+ return {
796
+ to: webhook.senderData.sender,
797
+ content: webhook.messageData.extendedTextMessageData?.text || "",
798
+ };
799
+ }
800
+ throw new IntegrationError("Поддерживаются только вебхуки вида incomingMessageReceived", "INTEGRATION_ERROR", 500);
801
+ }
802
+
803
+ toGreenApiMessage(message: SimplePlatformWebhook): Message {
804
+ return {
805
+ type: 'text',
806
+ chatId: formatPhoneNumber(message.from),
807
+ message: message.text,
808
+ };
809
+ }
863
810
  }
864
811
  ```
865
812
 
@@ -869,44 +816,44 @@ export class SimpleTransformer extends MessageTransformer<SimplePlatformWebhook,
869
816
  import { StorageProvider, BaseUser, Instance, Settings } from '@green-api/greenapi-integration';
870
817
 
871
818
  export class SimpleStorage extends StorageProvider {
872
- private users: Map<string, BaseUser> = new Map();
873
- private instances: Map<number, Instance> = new Map();
874
-
875
- async createInstance(instance: Instance, userId: bigint): Promise<Instance> {
876
- this.instances.set(Number(instance.idInstance), {
877
- ...instance,
878
- });
879
- return instance;
880
- }
881
-
882
- async getInstance(idInstance: number): Promise<Instance | null> {
883
- return this.instances.get(idInstance) || null;
884
- }
885
-
886
- async removeInstance(instanceId: number): Promise<Instance> {
887
- const instance = this.instances.get(instanceId);
888
- if (!instance) throw new Error('Инстанс не найден');
889
- this.instances.delete(instanceId);
890
- return instance;
891
- }
892
-
893
- async createUser(data: any): Promise<BaseUser> {
894
- const user = {id: Date.now(), ...data};
895
- this.users.set(data.email, user);
896
- return user;
897
- }
898
-
899
- async findUser(identifier: string): Promise<BaseUser | null> {
900
- return this.users.get(identifier) || null;
901
- }
902
-
903
- async updateUser(identifier: string, data: any): Promise<BaseUser> {
904
- const user = await this.findUser(identifier);
905
- if (!user) throw new Error('Пользователь не найден');
906
- const updated = {...user, ...data};
907
- this.users.set(identifier, updated);
908
- return updated;
909
- }
819
+ private users: Map<string, BaseUser> = new Map();
820
+ private instances: Map<number, Instance> = new Map();
821
+
822
+ async createInstance(instance: Instance, userId: bigint): Promise<Instance> {
823
+ this.instances.set(Number(instance.idInstance), {
824
+ ...instance,
825
+ });
826
+ return instance;
827
+ }
828
+
829
+ async getInstance(idInstance: number): Promise<Instance | null> {
830
+ return this.instances.get(idInstance) || null;
831
+ }
832
+
833
+ async removeInstance(instanceId: number): Promise<Instance> {
834
+ const instance = this.instances.get(instanceId);
835
+ if (!instance) throw new Error('Инстанс не найден');
836
+ this.instances.delete(instanceId);
837
+ return instance;
838
+ }
839
+
840
+ async createUser(data: any): Promise<BaseUser> {
841
+ const user = {id: Date.now(), ...data};
842
+ this.users.set(data.email, user);
843
+ return user;
844
+ }
845
+
846
+ async findUser(identifier: string): Promise<BaseUser | null> {
847
+ return this.users.get(identifier) || null;
848
+ }
849
+
850
+ async updateUser(identifier: string, data: any): Promise<BaseUser> {
851
+ const user = await this.findUser(identifier);
852
+ if (!user) throw new Error('Пользователь не найден');
853
+ const updated = {...user, ...data};
854
+ this.users.set(identifier, updated);
855
+ return updated;
856
+ }
910
857
  }
911
858
  ```
912
859
 
@@ -917,38 +864,38 @@ import { BaseAdapter, Instance } from "@green-api/greenapi-integration";
917
864
  import axios from 'axios';
918
865
 
919
866
  export class SimpleAdapter extends BaseAdapter<SimplePlatformWebhook, SimplePlatformMessage> {
920
- async createPlatformClient(config: { apiKey: string, apiUrl: string }) {
921
- return axios.create({
922
- baseURL: config.apiUrl,
923
- headers: {
924
- 'Authorization': `Bearer ${config.apiKey}`,
925
- 'Content-Type': 'application/json'
926
- }
927
- });
928
- }
929
-
930
- async sendToPlatform(message: SimplePlatformMessage, instance: Instance): Promise<void> {
931
- // В реальной реализации мы бы отправляли сообщение на платформу
932
- // Для демонстрации просто логируем и симулируем ответ
933
- console.log('Платформа получила сообщение:', message);
934
-
935
- // Симулируем обработку и ответ платформы
936
- setTimeout(() => {
937
- console.log('Обработка платформой завершена, отправляем ответ...');
938
- this.simulatePlatformResponse(message, instance.idInstance);
939
- }, 1000);
940
- }
941
-
942
- private async simulatePlatformResponse(originalMessage: SimplePlatformMessage, idInstance: number | bigint) {
943
- const platformWebhook: SimplePlatformWebhook = {
944
- messageId: `resp_${Date.now()}`,
945
- from: originalMessage.to.replace('@c.us', ''),
946
- text: `Спасибо за ваше сообщение: "${originalMessage.content}". Это автоматический ответ.`,
947
- timestamp: Date.now()
948
- };
949
-
950
- await this.handlePlatformWebhook(platformWebhook, idInstance);
951
- }
867
+ async createPlatformClient(config: { apiKey: string, apiUrl: string }) {
868
+ return axios.create({
869
+ baseURL: config.apiUrl,
870
+ headers: {
871
+ 'Authorization': `Bearer ${config.apiKey}`,
872
+ 'Content-Type': 'application/json'
873
+ }
874
+ });
875
+ }
876
+
877
+ async sendToPlatform(message: SimplePlatformMessage, instance: Instance): Promise<void> {
878
+ // В реальной реализации мы бы отправляли сообщение на платформу
879
+ // Для демонстрации просто логируем и симулируем ответ
880
+ console.log('Платформа получила сообщение:', message);
881
+
882
+ // Симулируем обработку и ответ платформы
883
+ setTimeout(() => {
884
+ console.log('Обработка платформой завершена, отправляем ответ...');
885
+ this.simulatePlatformResponse(message, instance.idInstance);
886
+ }, 1000);
887
+ }
888
+
889
+ private async simulatePlatformResponse(originalMessage: SimplePlatformMessage, idInstance: number | bigint) {
890
+ const platformWebhook: SimplePlatformWebhook = {
891
+ messageId: `resp_${Date.now()}`,
892
+ from: originalMessage.to.replace('@c.us', ''),
893
+ text: `Спасибо за ваше сообщение: "${originalMessage.content}". Это автоматический ответ.`,
894
+ timestamp: Date.now()
895
+ };
896
+
897
+ await this.handlePlatformWebhook(platformWebhook, idInstance);
898
+ }
952
899
  }
953
900
  ```
954
901
 
@@ -966,92 +913,80 @@ import * as dotenv from "dotenv";
966
913
  dotenv.config();
967
914
 
968
915
  async function main() {
969
- // Инициализация компонентов
970
- const transformer = new SimpleTransformer();
971
- const storage = new SimpleStorage();
972
- const adapter = new SimpleAdapter(transformer, storage);
973
-
974
- // Конфигурация обоих инстансов
975
- const visitorInstance = {
976
- idInstance: Number(process.env.VISITOR_ID_INSTANCE),
977
- apiTokenInstance: process.env.VISITOR_API_TOKEN!,
978
- };
979
-
980
- const agentInstance = {
981
- idInstance: Number(process.env.AGENT_ID_INSTANCE),
982
- apiTokenInstance: process.env.AGENT_API_TOKEN!,
983
- };
984
-
985
- // Создание клиента GREEN-API для посетителя (для отправки начального сообщения)
986
- const visitorClient = new GreenApiClient(visitorInstance);
987
-
988
- // Настройка инстанса агента
989
- console.log("Настройка инстанса агента...");
990
- const user = await adapter.createUser("agent@example.com", {
991
- email: "agent@example.com",
992
- name: "Agent",
993
- });
994
-
995
- const instance = await adapter.createInstance({
996
- idInstance: agentInstance.idInstance, apiTokenInstance: agentInstance.apiTokenInstance, settings: {
997
- webhookUrl: process.env.WEBHOOK_URL + "/webhook/green-api",
998
- webhookUrlToken: "your-secure-token",
999
- incomingWebhook: "yes",
1000
- },
1001
- }, user.email);
1002
-
1003
- console.log("Ожидание 2 минуты для применения настроек...");
1004
- await new Promise(resolve => setTimeout(resolve, 120000));
1005
- console.log("Инстанс готов!");
1006
-
1007
- // Настройка веб-сервера
1008
- const app = express();
1009
- app.use(bodyParser.json());
1010
-
1011
- // Обработка вебхуков от GREEN-API
1012
- app.post("/webhook/green-api", async (req, res) => {
1013
- try {
1014
- console.log("Получен вебхук от GREEN-API:", req.body);
1015
- await adapter.handleGreenApiWebhook(req.body, ["incomingMessageReceived"]);
1016
- res.status(200).json({status: "ok"});
1017
- } catch (error) {
1018
- console.error("Ошибка обработки вебхука:", error);
1019
- res.status(500).json({error: "Внутренняя ошибка сервера"});
1020
- }
1021
- });
1022
-
1023
- // Запуск сервера
1024
- const port = Number(process.env.PORT) || 3000;
1025
- app.listen(port, () => {
1026
- console.log(`Сервер вебхуков запущен на порту ${port}`);
1027
- });
1028
-
1029
- // Отправка начального сообщения от посетителя
1030
- console.log("Отправка начального сообщения от посетителя...");
1031
- await visitorClient.sendMessage({
1032
- chatId: formatPhoneNumber(process.env.AGENT_PHONE_NUMBER!),
1033
- message: "Здравствуйте! Это тестовое сообщение от посетителя.",
1034
- type: "text",
1035
- });
1036
-
1037
- console.log("Начальное сообщение отправлено! Проверьте WhatsApp агента для просмотра ответа.");
916
+ // Инициализация компонентов
917
+ const transformer = new SimpleTransformer();
918
+ const storage = new SimpleStorage();
919
+ const adapter = new SimpleAdapter(transformer, storage);
920
+
921
+ // Конфигурация обоих инстансов
922
+ const visitorInstance = {
923
+ idInstance: Number(process.env.VISITOR_ID_INSTANCE),
924
+ apiTokenInstance: process.env.VISITOR_API_TOKEN!,
925
+ };
926
+
927
+ const agentInstance = {
928
+ idInstance: Number(process.env.AGENT_ID_INSTANCE),
929
+ apiTokenInstance: process.env.AGENT_API_TOKEN!,
930
+ };
931
+
932
+ // Создание клиента GREEN-API для посетителя (для отправки начального сообщения)
933
+ const visitorClient = new GreenApiClient(visitorInstance);
934
+
935
+ // Настройка инстанса агента
936
+ console.log("Настройка инстанса агента...");
937
+ const user = await adapter.createUser("agent@example.com", {
938
+ email: "agent@example.com",
939
+ name: "Agent",
940
+ });
941
+
942
+ const instance = await adapter.createInstance({
943
+ idInstance: agentInstance.idInstance, apiTokenInstance: agentInstance.apiTokenInstance, settings: {
944
+ webhookUrl: process.env.WEBHOOK_URL + "/webhook/green-api",
945
+ webhookUrlToken: "your-secure-token",
946
+ incomingWebhook: "yes",
947
+ },
948
+ }, user.email);
949
+
950
+ console.log("Ожидание 2 минуты для применения настроек...");
951
+ await new Promise(resolve => setTimeout(resolve, 120000));
952
+ console.log("Инстанс готов!");
953
+
954
+ // Настройка веб-сервера
955
+ const app = express();
956
+ app.use(bodyParser.json());
957
+
958
+ // Обработка вебхуков от GREEN-API
959
+ app.post("/webhook/green-api", async (req, res) => {
960
+ try {
961
+ console.log("Получен вебхук от GREEN-API:", req.body);
962
+ await adapter.handleGreenApiWebhook(req.body, ["incomingMessageReceived"]);
963
+ res.status(200).json({status: "ok"});
964
+ } catch (error) {
965
+ console.error("Ошибка обработки вебхука:", error);
966
+ res.status(500).json({error: "Внутренняя ошибка сервера"});
967
+ }
968
+ });
969
+
970
+ // Запуск сервера
971
+ const port = Number(process.env.PORT) || 3000;
972
+ app.listen(port, () => {
973
+ console.log(`Сервер вебхуков запущен на порту ${port}`);
974
+ });
975
+
976
+ // Отправка начального сообщения от посетителя
977
+ console.log("Отправка начального сообщения от посетителя...");
978
+ await visitorClient.sendMessage({
979
+ chatId: formatPhoneNumber(process.env.AGENT_PHONE_NUMBER!),
980
+ message: "Здравствуйте! Это тестовое сообщение от посетителя.",
981
+ type: "text",
982
+ });
983
+
984
+ console.log("Начальное сообщение отправлено! Проверьте WhatsApp агента для просмотра ответа.");
1038
985
  }
1039
-
986
+
1040
987
  main().catch(console.error);
1041
988
  ```
1042
989
 
1043
- ### .env
1044
-
1045
- ```env
1046
- VISITOR_ID_INSTANCE=your_visitor_instance_id
1047
- VISITOR_API_TOKEN=your_visitor_instance_token
1048
- AGENT_ID_INSTANCE=your_agent_instance_id
1049
- AGENT_API_TOKEN=your_agent_instance_token
1050
- AGENT_PHONE_NUMBER=your_agent_phone_number
1051
- WEBHOOK_URL=your_webhook_url
1052
- PORT=3000
1053
- ```
1054
-
1055
990
  ## Реальные примеры
1056
991
 
1057
992
  Для полных примеров реальных интеграций, смотрите:
@@ -1078,10 +1013,10 @@ isValidSettingValue('webhookUrl', 'https://example.com') // Возвращает
1078
1013
 
1079
1014
  // Очистка настроек
1080
1015
  const input = {
1081
- webhookUrl: 'https://example.com',
1082
- outgoingWebhook: 'yes',
1083
- invalidKey: 'value',
1084
- delaySendMessagesMilliseconds: 'invalid'
1016
+ webhookUrl: 'https://example.com',
1017
+ outgoingWebhook: 'yes',
1018
+ invalidKey: 'value',
1019
+ delaySendMessagesMilliseconds: 'invalid'
1085
1020
  }
1086
1021
  validateAndCleanSettings(input) // Возвращает { webhookUrl: 'https://example.com', outgoingWebhook: 'yes' }
1087
1022
  ```
@@ -1089,4 +1024,3 @@ validateAndCleanSettings(input) // Возвращает { webhookUrl: 'https://e
1089
1024
  ## Лицензия
1090
1025
 
1091
1026
  MIT
1092
- ]()