@green-api/greenapi-integration 0.3.0 → 0.5.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 +65 -39
- package/README.ru.md +56 -39
- package/dist/core/base-adapter.d.ts +1 -4
- package/dist/core/base-adapter.js +2 -17
- package/dist/core/green-api.client.d.ts +225 -1
- package/dist/core/green-api.client.js +287 -5
- package/dist/core/storage-provider.d.ts +1 -2
- package/dist/types/types.d.ts +223 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -129,7 +129,7 @@ Handles message format conversion between GREEN-API and your platform.
|
|
|
129
129
|
|
|
130
130
|
```typescript
|
|
131
131
|
abstract class MessageTransformer<TPlatformWebhook, TPlatformMessage> {
|
|
132
|
-
abstract toPlatformMessage(webhook:
|
|
132
|
+
abstract toPlatformMessage(webhook: GreenApiWebhook): TPlatformMessage;
|
|
133
133
|
|
|
134
134
|
abstract toGreenApiMessage(message: TPlatformWebhook): Message;
|
|
135
135
|
}
|
|
@@ -141,7 +141,7 @@ Interface for data persistence operations.
|
|
|
141
141
|
|
|
142
142
|
```typescript
|
|
143
143
|
abstract class StorageProvider<TUser extends BaseUser = BaseUser, TInstance extends BaseInstance = Instance> {
|
|
144
|
-
abstract createInstance(instance: BaseInstance, userId: bigint | number
|
|
144
|
+
abstract createInstance(instance: BaseInstance, userId: bigint | number): Promise<TInstance>;
|
|
145
145
|
|
|
146
146
|
abstract getInstance(idInstance: number | bigint): Promise<TInstance | null>;
|
|
147
147
|
|
|
@@ -285,11 +285,11 @@ Create a transformer that converts messages between your platform's format and G
|
|
|
285
285
|
|
|
286
286
|
```typescript
|
|
287
287
|
// core/transformer.ts
|
|
288
|
-
import { MessageTransformer, Message,
|
|
288
|
+
import { MessageTransformer, Message, GreenApiWebhook } from '@green-api/greenapi-integration';
|
|
289
289
|
import { YourPlatformWebhook, YourPlatformMessage } from '../types/types';
|
|
290
290
|
|
|
291
291
|
export class YourTransformer extends MessageTransformer<YourPlatformWebhook, YourPlatformMessage> {
|
|
292
|
-
toPlatformMessage(webhook:
|
|
292
|
+
toPlatformMessage(webhook: GreenApiWebhook): YourPlatformMessage {
|
|
293
293
|
// Transform GREEN-API webhook to your platform format
|
|
294
294
|
return {
|
|
295
295
|
recipient: webhook.senderData.sender,
|
|
@@ -314,7 +314,7 @@ Create a storage provider to manage users and instances. You can use any databas
|
|
|
314
314
|
|
|
315
315
|
```typescript
|
|
316
316
|
// core/storage.ts
|
|
317
|
-
import { StorageProvider, BaseUser,
|
|
317
|
+
import { StorageProvider, BaseUser, Instance, Settings } from '@green-api/greenapi-integration';
|
|
318
318
|
import { PrismaClient } from '@prisma/client'; // Or your database client
|
|
319
319
|
|
|
320
320
|
export class YourStorage extends StorageProvider {
|
|
@@ -324,13 +324,13 @@ export class YourStorage extends StorageProvider {
|
|
|
324
324
|
this.db = new PrismaClient();
|
|
325
325
|
}
|
|
326
326
|
|
|
327
|
-
async createInstance(instance:
|
|
327
|
+
async createInstance(instance: Instance, userId: bigint) {
|
|
328
328
|
return this.db.instance.create({
|
|
329
329
|
data: {
|
|
330
330
|
idInstance: instance.idInstance,
|
|
331
331
|
apiTokenInstance: instance.apiTokenInstance,
|
|
332
332
|
userId,
|
|
333
|
-
settings: settings || {},
|
|
333
|
+
settings: instance.settings || {},
|
|
334
334
|
},
|
|
335
335
|
});
|
|
336
336
|
}
|
|
@@ -357,7 +357,7 @@ export class YourAdapter extends BaseAdapter<YourPlatformWebhook, YourPlatformMe
|
|
|
357
357
|
});
|
|
358
358
|
}
|
|
359
359
|
|
|
360
|
-
async sendToPlatform(message: YourPlatformMessage, instance:
|
|
360
|
+
async sendToPlatform(message: YourPlatformMessage, instance: Instance) {
|
|
361
361
|
const client = await this.createPlatformClient(instance.config);
|
|
362
362
|
await client.sendMessage(message);
|
|
363
363
|
}
|
|
@@ -429,11 +429,12 @@ router.post('/instance', async (req, res) => {
|
|
|
429
429
|
|
|
430
430
|
const instance = await adapter.createInstance({
|
|
431
431
|
idInstance: Number(idInstance),
|
|
432
|
-
apiTokenInstance
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
432
|
+
apiTokenInstance,
|
|
433
|
+
settings: {
|
|
434
|
+
webhookUrl: `${process.env.APP_URL}/webhook/green-api`,
|
|
435
|
+
webhookUrlToken: `token_${Date.now()}`,
|
|
436
|
+
incomingWebhook: 'yes'
|
|
437
|
+
}
|
|
437
438
|
}, userEmail);
|
|
438
439
|
|
|
439
440
|
res.status(200).json({
|
|
@@ -509,7 +510,7 @@ bootstrap();
|
|
|
509
510
|
"prepublishOnly": "npm run build"
|
|
510
511
|
},
|
|
511
512
|
"dependencies": {
|
|
512
|
-
"@green-api/greenapi-integration": "^
|
|
513
|
+
"@green-api/greenapi-integration": "^0.4.0",
|
|
513
514
|
"express": "^4.18.2"
|
|
514
515
|
// other dependencies
|
|
515
516
|
}
|
|
@@ -593,23 +594,33 @@ interface SimplePlatformMessage {
|
|
|
593
594
|
### simple-transformer.ts
|
|
594
595
|
|
|
595
596
|
```typescript
|
|
596
|
-
import {
|
|
597
|
+
import {
|
|
598
|
+
MessageTransformer,
|
|
599
|
+
Message,
|
|
600
|
+
GreenApiWebhook,
|
|
601
|
+
formatPhoneNumber,
|
|
602
|
+
IntegrationError,
|
|
603
|
+
} from "@green-api/greenapi-integration";
|
|
604
|
+
import { SimplePlatformMessage, SimplePlatformWebhook } from "./types";
|
|
597
605
|
|
|
598
606
|
export class SimpleTransformer extends MessageTransformer<SimplePlatformWebhook, SimplePlatformMessage> {
|
|
599
|
-
toPlatformMessage(webhook:
|
|
600
|
-
if (webhook.
|
|
601
|
-
|
|
602
|
-
|
|
607
|
+
toPlatformMessage(webhook: GreenApiWebhook): SimplePlatformMessage {
|
|
608
|
+
if (webhook.typeWebhook === "incomingMessageReceived") {
|
|
609
|
+
if (webhook.messageData.typeMessage !== "extendedTextMessage") {
|
|
610
|
+
throw new IntegrationError("Only text messages are supported", "BAD_REQUEST_ERROR", 400);
|
|
611
|
+
}
|
|
603
612
|
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
613
|
+
return {
|
|
614
|
+
to: webhook.senderData.sender,
|
|
615
|
+
content: webhook.messageData.extendedTextMessageData?.text || "",
|
|
616
|
+
};
|
|
617
|
+
}
|
|
618
|
+
throw new IntegrationError("Only incomingMessageReceived type webhooks are supported", "INTEGRATION_ERROR", 500);
|
|
608
619
|
}
|
|
609
620
|
|
|
610
621
|
toGreenApiMessage(message: SimplePlatformWebhook): Message {
|
|
611
622
|
return {
|
|
612
|
-
type:
|
|
623
|
+
type: "text",
|
|
613
624
|
chatId: formatPhoneNumber(message.from),
|
|
614
625
|
message: message.text,
|
|
615
626
|
};
|
|
@@ -620,25 +631,24 @@ export class SimpleTransformer extends MessageTransformer<SimplePlatformWebhook,
|
|
|
620
631
|
### simple-storage.ts
|
|
621
632
|
|
|
622
633
|
```typescript
|
|
623
|
-
import { StorageProvider, BaseUser,
|
|
634
|
+
import { StorageProvider, BaseUser, Instance } from '@green-api/greenapi-integration';
|
|
624
635
|
|
|
625
636
|
export class SimpleStorage extends StorageProvider {
|
|
626
637
|
private users: Map<string, BaseUser> = new Map();
|
|
627
|
-
private instances: Map<number,
|
|
638
|
+
private instances: Map<number, Instance> = new Map();
|
|
628
639
|
|
|
629
|
-
async createInstance(instance:
|
|
640
|
+
async createInstance(instance: Instance, userId: bigint): Promise<Instance> {
|
|
630
641
|
this.instances.set(Number(instance.idInstance), {
|
|
631
642
|
...instance,
|
|
632
|
-
settings: settings || {}
|
|
633
643
|
});
|
|
634
644
|
return instance;
|
|
635
645
|
}
|
|
636
646
|
|
|
637
|
-
async getInstance(idInstance: number): Promise<
|
|
647
|
+
async getInstance(idInstance: number): Promise<Instance | null> {
|
|
638
648
|
return this.instances.get(idInstance) || null;
|
|
639
649
|
}
|
|
640
650
|
|
|
641
|
-
async removeInstance(instanceId: number): Promise<
|
|
651
|
+
async removeInstance(instanceId: number): Promise<Instance> {
|
|
642
652
|
const instance = this.instances.get(instanceId);
|
|
643
653
|
if (!instance) throw new Error('Instance not found');
|
|
644
654
|
this.instances.delete(instanceId);
|
|
@@ -668,7 +678,8 @@ export class SimpleStorage extends StorageProvider {
|
|
|
668
678
|
### simple-adapter.ts
|
|
669
679
|
|
|
670
680
|
```typescript
|
|
671
|
-
import { BaseAdapter,
|
|
681
|
+
import { BaseAdapter, Instance } from "@green-api/greenapi-integration";
|
|
682
|
+
import { SimplePlatformMessage, SimplePlatformWebhook } from "./types";
|
|
672
683
|
import axios from 'axios';
|
|
673
684
|
|
|
674
685
|
export class SimpleAdapter extends BaseAdapter<SimplePlatformWebhook, SimplePlatformMessage> {
|
|
@@ -682,7 +693,7 @@ export class SimpleAdapter extends BaseAdapter<SimplePlatformWebhook, SimplePlat
|
|
|
682
693
|
});
|
|
683
694
|
}
|
|
684
695
|
|
|
685
|
-
async sendToPlatform(message: SimplePlatformMessage, instance:
|
|
696
|
+
async sendToPlatform(message: SimplePlatformMessage, instance: Instance): Promise<void> {
|
|
686
697
|
// In a real implementation, we would send to the platform
|
|
687
698
|
// For demo, we'll just log and simulate a response
|
|
688
699
|
console.log('Platform received message:', message);
|
|
@@ -712,7 +723,7 @@ export class SimpleAdapter extends BaseAdapter<SimplePlatformWebhook, SimplePlat
|
|
|
712
723
|
```typescript
|
|
713
724
|
import express from "express";
|
|
714
725
|
import bodyParser from "body-parser";
|
|
715
|
-
import { formatPhoneNumber, GreenApiClient } from "greenapi-integration";
|
|
726
|
+
import { formatPhoneNumber, GreenApiClient } from "@green-api/greenapi-integration";
|
|
716
727
|
import { SimpleTransformer } from "./simple-transformer";
|
|
717
728
|
import { SimpleStorage } from "./simple-storage";
|
|
718
729
|
import { SimpleAdapter } from "./simple-adapter";
|
|
@@ -736,6 +747,7 @@ async function main() {
|
|
|
736
747
|
idInstance: Number(process.env.AGENT_ID_INSTANCE),
|
|
737
748
|
apiTokenInstance: process.env.AGENT_API_TOKEN!,
|
|
738
749
|
};
|
|
750
|
+
console.log(visitorInstance, agentInstance);
|
|
739
751
|
|
|
740
752
|
// Create visitor's GREEN-API client (for sending initial message)
|
|
741
753
|
const visitorClient = new GreenApiClient(visitorInstance);
|
|
@@ -747,10 +759,12 @@ async function main() {
|
|
|
747
759
|
name: "Agent",
|
|
748
760
|
});
|
|
749
761
|
|
|
750
|
-
const instance = await adapter.createInstance(
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
762
|
+
const instance = await adapter.createInstance({
|
|
763
|
+
idInstance: agentInstance.idInstance, apiTokenInstance: agentInstance.apiTokenInstance, settings: {
|
|
764
|
+
webhookUrl: process.env.WEBHOOK_URL + "/webhook/green-api",
|
|
765
|
+
webhookUrlToken: "your-secure-token",
|
|
766
|
+
incomingWebhook: "yes",
|
|
767
|
+
},
|
|
754
768
|
}, user.email);
|
|
755
769
|
|
|
756
770
|
console.log("Waiting 2 minutes for settings to apply...");
|
|
@@ -774,7 +788,7 @@ async function main() {
|
|
|
774
788
|
});
|
|
775
789
|
|
|
776
790
|
// Start the server
|
|
777
|
-
const port = process.env.PORT || 3000;
|
|
791
|
+
const port = Number(process.env.PORT) || 3000;
|
|
778
792
|
app.listen(port, () => {
|
|
779
793
|
console.log(`Webhook server listening on port ${port}`);
|
|
780
794
|
});
|
|
@@ -817,7 +831,7 @@ The platform provides several utility functions:
|
|
|
817
831
|
|
|
818
832
|
```typescript
|
|
819
833
|
// Format phone numbers for GREEN-API
|
|
820
|
-
formatPhoneNumber('1234567890') // Returns '1234567890@c.us'
|
|
834
|
+
formatPhoneNumber('+1234567890') // Returns '1234567890@c.us'
|
|
821
835
|
|
|
822
836
|
// Generate secure random tokens
|
|
823
837
|
generateRandomToken(32) // Returns a 32-character random token
|
|
@@ -825,6 +839,18 @@ generateRandomToken(32) // Returns a 32-character random token
|
|
|
825
839
|
// Extract phone number from vcard
|
|
826
840
|
const vcard = 'BEGIN:VCARD\nTEL:+1234567890\nEND:VCARD'
|
|
827
841
|
extractPhoneNumberFromVCard(vcard) // Returns '+1234567890'
|
|
842
|
+
|
|
843
|
+
// Validate settings values
|
|
844
|
+
isValidSettingValue('webhookUrl', 'https://example.com') // Returns true
|
|
845
|
+
|
|
846
|
+
// Clean settings
|
|
847
|
+
const input = {
|
|
848
|
+
webhookUrl: 'https://example.com',
|
|
849
|
+
outgoingWebhook: 'yes',
|
|
850
|
+
invalidKey: 'value',
|
|
851
|
+
delaySendMessagesMilliseconds: 'invalid'
|
|
852
|
+
}
|
|
853
|
+
validateAndCleanSettings(input) // Returns { webhookUrl: 'https://example.com', outgoingWebhook: 'yes' }
|
|
828
854
|
```
|
|
829
855
|
|
|
830
856
|
## License
|
package/README.ru.md
CHANGED
|
@@ -128,7 +128,7 @@ app.post('/webhook/green-api', async (req, res) => {
|
|
|
128
128
|
|
|
129
129
|
```typescript
|
|
130
130
|
abstract class MessageTransformer<TPlatformWebhook, TPlatformMessage> {
|
|
131
|
-
abstract toPlatformMessage(webhook:
|
|
131
|
+
abstract toPlatformMessage(webhook: GreenApiWebhook): TPlatformMessage;
|
|
132
132
|
|
|
133
133
|
abstract toGreenApiMessage(message: TPlatformWebhook): Message;
|
|
134
134
|
}
|
|
@@ -140,7 +140,7 @@ abstract class MessageTransformer<TPlatformWebhook, TPlatformMessage> {
|
|
|
140
140
|
|
|
141
141
|
```typescript
|
|
142
142
|
abstract class StorageProvider<TUser extends BaseUser = BaseUser, TInstance extends BaseInstance = Instance> {
|
|
143
|
-
abstract createInstance(instance: BaseInstance, userId: bigint | number
|
|
143
|
+
abstract createInstance(instance: BaseInstance, userId: bigint | number): Promise<TInstance>;
|
|
144
144
|
|
|
145
145
|
abstract getInstance(idInstance: number | bigint): Promise<TInstance | null>;
|
|
146
146
|
|
|
@@ -285,11 +285,11 @@ export interface YourPlatformMessage {
|
|
|
285
285
|
|
|
286
286
|
```typescript
|
|
287
287
|
// core/transformer.ts
|
|
288
|
-
import { MessageTransformer, Message,
|
|
288
|
+
import { MessageTransformer, Message, GreenApiWebhook } from '@green-api/greenapi-integration';
|
|
289
289
|
import { YourPlatformWebhook, YourPlatformMessage } from '../types/types';
|
|
290
290
|
|
|
291
291
|
export class YourTransformer extends MessageTransformer<YourPlatformWebhook, YourPlatformMessage> {
|
|
292
|
-
toPlatformMessage(webhook:
|
|
292
|
+
toPlatformMessage(webhook: GreenApiWebhook): YourPlatformMessage {
|
|
293
293
|
// Преобразование вебхука GREEN-API в формат вашей платформы
|
|
294
294
|
return {
|
|
295
295
|
recipient: webhook.senderData.sender,
|
|
@@ -315,7 +315,7 @@ ORM:
|
|
|
315
315
|
|
|
316
316
|
```typescript
|
|
317
317
|
// core/storage.ts
|
|
318
|
-
import { StorageProvider, BaseUser,
|
|
318
|
+
import { StorageProvider, BaseUser, Instance, Settings } from '@green-api/greenapi-integration';
|
|
319
319
|
import { PrismaClient } from '@prisma/client'; // Or your database client
|
|
320
320
|
|
|
321
321
|
export class YourStorage extends StorageProvider {
|
|
@@ -325,13 +325,13 @@ export class YourStorage extends StorageProvider {
|
|
|
325
325
|
this.db = new PrismaClient();
|
|
326
326
|
}
|
|
327
327
|
|
|
328
|
-
async createInstance(instance:
|
|
328
|
+
async createInstance(instance: Instance, userId: bigint) {
|
|
329
329
|
return this.db.instance.create({
|
|
330
330
|
data: {
|
|
331
331
|
idInstance: instance.idInstance,
|
|
332
332
|
apiTokenInstance: instance.apiTokenInstance,
|
|
333
333
|
userId,
|
|
334
|
-
settings: settings || {},
|
|
334
|
+
settings: instance.settings || {},
|
|
335
335
|
},
|
|
336
336
|
});
|
|
337
337
|
}
|
|
@@ -346,7 +346,7 @@ export class YourStorage extends StorageProvider {
|
|
|
346
346
|
|
|
347
347
|
```typescript
|
|
348
348
|
// core/adapter.ts
|
|
349
|
-
import { BaseAdapter,
|
|
349
|
+
import { BaseAdapter, Instance } from '@green-api/greenapi-integration';
|
|
350
350
|
import { YourPlatformClient } from 'your-platform-sdk';
|
|
351
351
|
import { YourPlatformWebhook, YourPlatformMessage } from '../types/types';
|
|
352
352
|
|
|
@@ -358,7 +358,7 @@ export class YourAdapter extends BaseAdapter<YourPlatformWebhook, YourPlatformMe
|
|
|
358
358
|
});
|
|
359
359
|
}
|
|
360
360
|
|
|
361
|
-
async sendToPlatform(message: YourPlatformMessage, instance:
|
|
361
|
+
async sendToPlatform(message: YourPlatformMessage, instance: Instance) {
|
|
362
362
|
const client = await this.createPlatformClient(instance.config);
|
|
363
363
|
await client.sendMessage(message);
|
|
364
364
|
}
|
|
@@ -430,11 +430,12 @@ router.post('/instance', async (req, res) => {
|
|
|
430
430
|
|
|
431
431
|
const instance = await adapter.createInstance({
|
|
432
432
|
idInstance: Number(idInstance),
|
|
433
|
-
apiTokenInstance
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
433
|
+
apiTokenInstance,
|
|
434
|
+
settings: {
|
|
435
|
+
webhookUrl: `${process.env.APP_URL}/webhook/green-api`,
|
|
436
|
+
webhookUrlToken: `token_${Date.now()}`,
|
|
437
|
+
incomingWebhook: 'yes'
|
|
438
|
+
}
|
|
438
439
|
}, userEmail);
|
|
439
440
|
|
|
440
441
|
res.status(200).json({
|
|
@@ -528,7 +529,7 @@ bootstrap();
|
|
|
528
529
|
"prepublishOnly": "npm run build"
|
|
529
530
|
},
|
|
530
531
|
"dependencies": {
|
|
531
|
-
"@green-api/greenapi-integration": "^
|
|
532
|
+
"@green-api/greenapi-integration": "^0.4.0",
|
|
532
533
|
"@prisma/client": "^5.0.0",
|
|
533
534
|
"express": "^4.18.2"
|
|
534
535
|
// другие зависимости
|
|
@@ -614,18 +615,21 @@ interface SimplePlatformMessage {
|
|
|
614
615
|
### simple-transformer.ts
|
|
615
616
|
|
|
616
617
|
```typescript
|
|
617
|
-
import { MessageTransformer, Message,
|
|
618
|
+
import { MessageTransformer, Message, GreenApiWebhook, formatPhoneNumber, IntegrationError } from '@green-api/greenapi-integration';
|
|
618
619
|
|
|
619
620
|
export class SimpleTransformer extends MessageTransformer<SimplePlatformWebhook, SimplePlatformMessage> {
|
|
620
|
-
toPlatformMessage(webhook:
|
|
621
|
-
if (webhook.
|
|
622
|
-
|
|
623
|
-
|
|
621
|
+
toPlatformMessage(webhook: GreenApiWebhook): SimplePlatformMessage {
|
|
622
|
+
if (webhook.typeWebhook === "incomingMessageReceived") {
|
|
623
|
+
if (webhook.messageData.typeMessage !== "extendedTextMessage") {
|
|
624
|
+
throw new IntegrationError("Поддерживаются только текстовые сообщения", "BAD_REQUEST_ERROR", 400);
|
|
625
|
+
}
|
|
624
626
|
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
627
|
+
return {
|
|
628
|
+
to: webhook.senderData.sender,
|
|
629
|
+
content: webhook.messageData.extendedTextMessageData?.text || "",
|
|
630
|
+
};
|
|
631
|
+
}
|
|
632
|
+
throw new IntegrationError("Поддерживаются только вебхуки вида incomingMessageReceived", "INTEGRATION_ERROR", 500);
|
|
629
633
|
}
|
|
630
634
|
|
|
631
635
|
toGreenApiMessage(message: SimplePlatformWebhook): Message {
|
|
@@ -641,25 +645,24 @@ export class SimpleTransformer extends MessageTransformer<SimplePlatformWebhook,
|
|
|
641
645
|
### simple-storage.ts
|
|
642
646
|
|
|
643
647
|
```typescript
|
|
644
|
-
import { StorageProvider, BaseUser,
|
|
648
|
+
import { StorageProvider, BaseUser, Instance, Settings } from '@green-api/greenapi-integration';
|
|
645
649
|
|
|
646
650
|
export class SimpleStorage extends StorageProvider {
|
|
647
651
|
private users: Map<string, BaseUser> = new Map();
|
|
648
|
-
private instances: Map<number,
|
|
652
|
+
private instances: Map<number, Instance> = new Map();
|
|
649
653
|
|
|
650
|
-
async createInstance(instance:
|
|
654
|
+
async createInstance(instance: Instance, userId: bigint): Promise<Instance> {
|
|
651
655
|
this.instances.set(Number(instance.idInstance), {
|
|
652
656
|
...instance,
|
|
653
|
-
settings: settings || {}
|
|
654
657
|
});
|
|
655
658
|
return instance;
|
|
656
659
|
}
|
|
657
660
|
|
|
658
|
-
async getInstance(idInstance: number): Promise<
|
|
661
|
+
async getInstance(idInstance: number): Promise<Instance | null> {
|
|
659
662
|
return this.instances.get(idInstance) || null;
|
|
660
663
|
}
|
|
661
664
|
|
|
662
|
-
async removeInstance(instanceId: number): Promise<
|
|
665
|
+
async removeInstance(instanceId: number): Promise<Instance> {
|
|
663
666
|
const instance = this.instances.get(instanceId);
|
|
664
667
|
if (!instance) throw new Error('Инстанс не найден');
|
|
665
668
|
this.instances.delete(instanceId);
|
|
@@ -689,7 +692,7 @@ export class SimpleStorage extends StorageProvider {
|
|
|
689
692
|
### simple-adapter.ts
|
|
690
693
|
|
|
691
694
|
```typescript
|
|
692
|
-
import { BaseAdapter,
|
|
695
|
+
import { BaseAdapter, Instance } from "@green-api/greenapi-integration";
|
|
693
696
|
import axios from 'axios';
|
|
694
697
|
|
|
695
698
|
export class SimpleAdapter extends BaseAdapter<SimplePlatformWebhook, SimplePlatformMessage> {
|
|
@@ -703,7 +706,7 @@ export class SimpleAdapter extends BaseAdapter<SimplePlatformWebhook, SimplePlat
|
|
|
703
706
|
});
|
|
704
707
|
}
|
|
705
708
|
|
|
706
|
-
async sendToPlatform(message: SimplePlatformMessage, instance:
|
|
709
|
+
async sendToPlatform(message: SimplePlatformMessage, instance: Instance): Promise<void> {
|
|
707
710
|
// В реальной реализации мы бы отправляли сообщение на платформу
|
|
708
711
|
// Для демонстрации просто логируем и симулируем ответ
|
|
709
712
|
console.log('Платформа получила сообщение:', message);
|
|
@@ -733,7 +736,7 @@ export class SimpleAdapter extends BaseAdapter<SimplePlatformWebhook, SimplePlat
|
|
|
733
736
|
```typescript
|
|
734
737
|
import express from "express";
|
|
735
738
|
import bodyParser from "body-parser";
|
|
736
|
-
import { formatPhoneNumber, GreenApiClient } from "greenapi-integration";
|
|
739
|
+
import { formatPhoneNumber, GreenApiClient } from "@green-api/greenapi-integration";
|
|
737
740
|
import { SimpleTransformer } from "./simple-transformer";
|
|
738
741
|
import { SimpleStorage } from "./simple-storage";
|
|
739
742
|
import { SimpleAdapter } from "./simple-adapter";
|
|
@@ -768,10 +771,12 @@ async function main() {
|
|
|
768
771
|
name: "Agent",
|
|
769
772
|
});
|
|
770
773
|
|
|
771
|
-
const instance = await adapter.createInstance(
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
774
|
+
const instance = await adapter.createInstance({
|
|
775
|
+
idInstance: agentInstance.idInstance, apiTokenInstance: agentInstance.apiTokenInstance, settings: {
|
|
776
|
+
webhookUrl: process.env.WEBHOOK_URL + "/webhook/green-api",
|
|
777
|
+
webhookUrlToken: "your-secure-token",
|
|
778
|
+
incomingWebhook: "yes",
|
|
779
|
+
},
|
|
775
780
|
}, user.email);
|
|
776
781
|
|
|
777
782
|
console.log("Ожидание 2 минуты для применения настроек...");
|
|
@@ -795,7 +800,7 @@ async function main() {
|
|
|
795
800
|
});
|
|
796
801
|
|
|
797
802
|
// Запуск сервера
|
|
798
|
-
const port = process.env.PORT || 3000;
|
|
803
|
+
const port = Number(process.env.PORT) || 3000;
|
|
799
804
|
app.listen(port, () => {
|
|
800
805
|
console.log(`Сервер вебхуков запущен на порту ${port}`);
|
|
801
806
|
});
|
|
@@ -838,7 +843,7 @@ PORT=3000
|
|
|
838
843
|
|
|
839
844
|
```typescript
|
|
840
845
|
// Форматирование телефонных номеров для GREEN-API
|
|
841
|
-
formatPhoneNumber('1234567890') // Возвращает '1234567890@c.us'
|
|
846
|
+
formatPhoneNumber('+1234567890') // Возвращает '1234567890@c.us'
|
|
842
847
|
|
|
843
848
|
// Генерация безопасных случайных токенов
|
|
844
849
|
generateRandomToken(32) // Возвращает 32-символьный случайный токен
|
|
@@ -846,6 +851,18 @@ generateRandomToken(32) // Возвращает 32-символьный случ
|
|
|
846
851
|
// Извлечение номера телефона из vcard
|
|
847
852
|
const vcard = 'BEGIN:VCARD\nTEL:+1234567890\nEND:VCARD'
|
|
848
853
|
extractPhoneNumberFromVCard(vcard) // Возвращает '+1234567890'
|
|
854
|
+
|
|
855
|
+
// Проверка значений настроек
|
|
856
|
+
isValidSettingValue('webhookUrl', 'https://example.com') // Возвращает true
|
|
857
|
+
|
|
858
|
+
// Очистка настроек
|
|
859
|
+
const input = {
|
|
860
|
+
webhookUrl: 'https://example.com',
|
|
861
|
+
outgoingWebhook: 'yes',
|
|
862
|
+
invalidKey: 'value',
|
|
863
|
+
delaySendMessagesMilliseconds: 'invalid'
|
|
864
|
+
}
|
|
865
|
+
validateAndCleanSettings(input) // Возвращает { webhookUrl: 'https://example.com', outgoingWebhook: 'yes' }
|
|
849
866
|
```
|
|
850
867
|
|
|
851
868
|
## Лицензия
|
|
@@ -120,12 +120,11 @@ export declare abstract class BaseAdapter<TPlatformWebhook, TPlatformMessage, TU
|
|
|
120
120
|
* Creates a new instance with specified settings.
|
|
121
121
|
*
|
|
122
122
|
* @param instance - The instance configuration
|
|
123
|
-
* @param userCred - User credentials
|
|
124
123
|
* @returns Promise resolving to the created instance
|
|
125
124
|
* @throws {NotFoundError} If user is not found
|
|
126
125
|
* @throws {IntegrationError} If instance creation fails
|
|
127
126
|
*/
|
|
128
|
-
createInstance(instance: Instance
|
|
127
|
+
createInstance(instance: Instance): Promise<TInstance>;
|
|
129
128
|
/**
|
|
130
129
|
* Removes an instance by ID.
|
|
131
130
|
*
|
|
@@ -157,8 +156,6 @@ export declare abstract class BaseAdapter<TPlatformWebhook, TPlatformMessage, TU
|
|
|
157
156
|
*
|
|
158
157
|
* @param userCred - User credentials
|
|
159
158
|
* @param data - User data
|
|
160
|
-
* @throws {BadRequestError} If user already exists
|
|
161
|
-
* @throws {IntegrationError} If creation fails
|
|
162
159
|
*/
|
|
163
160
|
createUser(userCred: any, data: any): Promise<TUser>;
|
|
164
161
|
}
|
|
@@ -148,17 +148,12 @@ class BaseAdapter {
|
|
|
148
148
|
* Creates a new instance with specified settings.
|
|
149
149
|
*
|
|
150
150
|
* @param instance - The instance configuration
|
|
151
|
-
* @param userCred - User credentials
|
|
152
151
|
* @returns Promise resolving to the created instance
|
|
153
152
|
* @throws {NotFoundError} If user is not found
|
|
154
153
|
* @throws {IntegrationError} If instance creation fails
|
|
155
154
|
*/
|
|
156
|
-
async createInstance(instance
|
|
155
|
+
async createInstance(instance) {
|
|
157
156
|
try {
|
|
158
|
-
const user = await this.storage.findUser(userCred);
|
|
159
|
-
if (!user) {
|
|
160
|
-
throw new errors_1.NotFoundError("No user with such credentials");
|
|
161
|
-
}
|
|
162
157
|
const client = this.createGreenApiClient(instance);
|
|
163
158
|
try {
|
|
164
159
|
await client.getSettings();
|
|
@@ -166,7 +161,7 @@ class BaseAdapter {
|
|
|
166
161
|
catch (error) {
|
|
167
162
|
throw new errors_1.IntegrationError(`Failed to get settings for instance ${instance.idInstance}: ${error.message}`, "INTEGRATION_ERROR");
|
|
168
163
|
}
|
|
169
|
-
const createdInstance = await this.storage.createInstance(instance
|
|
164
|
+
const createdInstance = await this.storage.createInstance(instance);
|
|
170
165
|
if (instance.settings) {
|
|
171
166
|
await client.setSettings(instance.settings);
|
|
172
167
|
}
|
|
@@ -185,10 +180,6 @@ class BaseAdapter {
|
|
|
185
180
|
*/
|
|
186
181
|
async removeInstance(idInstance) {
|
|
187
182
|
try {
|
|
188
|
-
const instance = await this.storage.getInstance(idInstance);
|
|
189
|
-
if (!instance) {
|
|
190
|
-
throw new errors_1.NotFoundError("No instance with such ID");
|
|
191
|
-
}
|
|
192
183
|
return this.storage.removeInstance(idInstance);
|
|
193
184
|
}
|
|
194
185
|
catch (error) {
|
|
@@ -232,14 +223,8 @@ class BaseAdapter {
|
|
|
232
223
|
*
|
|
233
224
|
* @param userCred - User credentials
|
|
234
225
|
* @param data - User data
|
|
235
|
-
* @throws {BadRequestError} If user already exists
|
|
236
|
-
* @throws {IntegrationError} If creation fails
|
|
237
226
|
*/
|
|
238
227
|
async createUser(userCred, data) {
|
|
239
|
-
const existingUser = await this.storage.findUser(userCred);
|
|
240
|
-
if (existingUser) {
|
|
241
|
-
throw new errors_1.BadRequestError("User already created");
|
|
242
|
-
}
|
|
243
228
|
try {
|
|
244
229
|
return this.storage.createUser(data);
|
|
245
230
|
}
|