@green-api/greenapi-integration 0.2.0 → 0.3.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/dist/core/base-adapter.d.ts +11 -4
- package/dist/core/base-adapter.js +26 -9
- package/dist/core/green-api.client.js +1 -1
- package/dist/core/storage-provider.d.ts +2 -3
- package/dist/types/types.d.ts +14 -2
- package/dist/utils/helpers.d.ts +32 -0
- package/dist/utils/helpers.js +64 -0
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { GreenApiClient } from "./green-api.client";
|
|
2
2
|
import { MessageTransformer } from "./message-transformer";
|
|
3
|
-
import { BaseUser, ForwardMessagesResponse, GreenApiWebhook, Instance, SendResponse,
|
|
3
|
+
import { BaseUser, ForwardMessagesResponse, GreenApiWebhook, Instance, SendResponse, StateInstanceWebhook, WebhookType } from "../types/types";
|
|
4
4
|
import { StorageProvider } from "./storage-provider";
|
|
5
5
|
/**
|
|
6
6
|
* Base adapter for platform integrations with GREEN-API.
|
|
@@ -74,6 +74,14 @@ export declare abstract class BaseAdapter<TPlatformWebhook, TPlatformMessage, TU
|
|
|
74
74
|
* ```
|
|
75
75
|
*/
|
|
76
76
|
abstract createPlatformClient(params: any): Promise<any>;
|
|
77
|
+
/**
|
|
78
|
+
* Handles instance state change webhooks from GREEN-API.
|
|
79
|
+
* Adapters MUST override this method if they need to handle instance state changes
|
|
80
|
+
*
|
|
81
|
+
* @param webhook - The state change webhook from GREEN-API
|
|
82
|
+
* @returns Promise resolving when the webhook is handled
|
|
83
|
+
*/
|
|
84
|
+
handleStateInstanceWebhook(webhook: StateInstanceWebhook): Promise<void>;
|
|
77
85
|
/**
|
|
78
86
|
* Creates a GREEN-API client instance.
|
|
79
87
|
*
|
|
@@ -107,18 +115,17 @@ export declare abstract class BaseAdapter<TPlatformWebhook, TPlatformMessage, TU
|
|
|
107
115
|
* @throws {NotFoundError} If instance is not found
|
|
108
116
|
* @throws {IntegrationError} If webhook handling fails
|
|
109
117
|
*/
|
|
110
|
-
handleGreenApiWebhook(webhook: GreenApiWebhook, allowedTypes:
|
|
118
|
+
handleGreenApiWebhook(webhook: GreenApiWebhook, allowedTypes: WebhookType[]): Promise<void>;
|
|
111
119
|
/**
|
|
112
120
|
* Creates a new instance with specified settings.
|
|
113
121
|
*
|
|
114
122
|
* @param instance - The instance configuration
|
|
115
|
-
* @param settings - GREEN-API settings for the instance
|
|
116
123
|
* @param userCred - User credentials
|
|
117
124
|
* @returns Promise resolving to the created instance
|
|
118
125
|
* @throws {NotFoundError} If user is not found
|
|
119
126
|
* @throws {IntegrationError} If instance creation fails
|
|
120
127
|
*/
|
|
121
|
-
createInstance(instance: Instance,
|
|
128
|
+
createInstance(instance: Instance, userCred: any): Promise<TInstance>;
|
|
122
129
|
/**
|
|
123
130
|
* Removes an instance by ID.
|
|
124
131
|
*
|
|
@@ -38,6 +38,17 @@ class BaseAdapter {
|
|
|
38
38
|
this.transformer = transformer;
|
|
39
39
|
this.storage = storage;
|
|
40
40
|
}
|
|
41
|
+
/**
|
|
42
|
+
* Handles instance state change webhooks from GREEN-API.
|
|
43
|
+
* Adapters MUST override this method if they need to handle instance state changes
|
|
44
|
+
*
|
|
45
|
+
* @param webhook - The state change webhook from GREEN-API
|
|
46
|
+
* @returns Promise resolving when the webhook is handled
|
|
47
|
+
*/
|
|
48
|
+
async handleStateInstanceWebhook(webhook) {
|
|
49
|
+
// Default empty implementation
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
41
52
|
/**
|
|
42
53
|
* Creates a GREEN-API client instance.
|
|
43
54
|
*
|
|
@@ -117,12 +128,17 @@ class BaseAdapter {
|
|
|
117
128
|
return;
|
|
118
129
|
}
|
|
119
130
|
try {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
131
|
+
if (webhook.typeWebhook === "stateInstanceChanged") {
|
|
132
|
+
await this.handleStateInstanceWebhook(webhook);
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
const transformedMessage = await this.transformer.toPlatformMessage(webhook);
|
|
136
|
+
const instance = await this.storage.getInstance(webhook.instanceData.idInstance);
|
|
137
|
+
if (!instance) {
|
|
138
|
+
throw new errors_1.NotFoundError("Instance not found");
|
|
139
|
+
}
|
|
140
|
+
await this.sendToPlatform(transformedMessage, instance);
|
|
124
141
|
}
|
|
125
|
-
await this.sendToPlatform(transformedMessage, instance);
|
|
126
142
|
}
|
|
127
143
|
catch (error) {
|
|
128
144
|
this.handleError("Failed to handle GREEN-API webhook", error);
|
|
@@ -132,13 +148,12 @@ class BaseAdapter {
|
|
|
132
148
|
* Creates a new instance with specified settings.
|
|
133
149
|
*
|
|
134
150
|
* @param instance - The instance configuration
|
|
135
|
-
* @param settings - GREEN-API settings for the instance
|
|
136
151
|
* @param userCred - User credentials
|
|
137
152
|
* @returns Promise resolving to the created instance
|
|
138
153
|
* @throws {NotFoundError} If user is not found
|
|
139
154
|
* @throws {IntegrationError} If instance creation fails
|
|
140
155
|
*/
|
|
141
|
-
async createInstance(instance,
|
|
156
|
+
async createInstance(instance, userCred) {
|
|
142
157
|
try {
|
|
143
158
|
const user = await this.storage.findUser(userCred);
|
|
144
159
|
if (!user) {
|
|
@@ -151,8 +166,10 @@ class BaseAdapter {
|
|
|
151
166
|
catch (error) {
|
|
152
167
|
throw new errors_1.IntegrationError(`Failed to get settings for instance ${instance.idInstance}: ${error.message}`, "INTEGRATION_ERROR");
|
|
153
168
|
}
|
|
154
|
-
const createdInstance = await this.storage.createInstance(instance, user.id
|
|
155
|
-
|
|
169
|
+
const createdInstance = await this.storage.createInstance(instance, user.id);
|
|
170
|
+
if (instance.settings) {
|
|
171
|
+
await client.setSettings(instance.settings);
|
|
172
|
+
}
|
|
156
173
|
return createdInstance;
|
|
157
174
|
}
|
|
158
175
|
catch (error) {
|
|
@@ -51,7 +51,7 @@ class GreenApiClient {
|
|
|
51
51
|
return response.data;
|
|
52
52
|
}
|
|
53
53
|
catch (error) {
|
|
54
|
-
throw new Error(`Failed to ${endpoint.replace(/([A-Z])/g, " $1").toLowerCase()}: ${error.message}`);
|
|
54
|
+
throw new Error(`Failed to ${endpoint.replace(/([A-Z])/g, " $1").toLowerCase()}: ${error.message}. ${JSON.stringify(error.response?.data)}`);
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
async makeFileUploadRequest(endpoint, formData, headers) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BaseUser, Instance
|
|
1
|
+
import { BaseUser, Instance } from "../types/types";
|
|
2
2
|
/**
|
|
3
3
|
* Abstract class for managing instance and user data storage.
|
|
4
4
|
* Implement this class to define how your integration stores and retrieves data.
|
|
@@ -26,10 +26,9 @@ export declare abstract class StorageProvider<TUser extends BaseUser = BaseUser,
|
|
|
26
26
|
*
|
|
27
27
|
* @param instance - The instance data to store
|
|
28
28
|
* @param userId - ID of the user who owns this instance
|
|
29
|
-
* @param settings - Optional GREEN-API settings for the instance
|
|
30
29
|
* @returns Promise resolving to the created instance
|
|
31
30
|
*/
|
|
32
|
-
abstract createInstance(instance: Instance, userId: bigint | number
|
|
31
|
+
abstract createInstance(instance: Instance, userId: bigint | number): Promise<TInstance>;
|
|
33
32
|
/**
|
|
34
33
|
* Retrieves an instance by its ID.
|
|
35
34
|
*
|
package/dist/types/types.d.ts
CHANGED
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
interface BaseInstance {
|
|
6
6
|
idInstance: number | bigint;
|
|
7
7
|
apiTokenInstance: string;
|
|
8
|
-
|
|
8
|
+
stateInstance?: InstanceState;
|
|
9
|
+
settings?: Settings | Record<string, any>;
|
|
9
10
|
}
|
|
10
11
|
/**
|
|
11
12
|
* Extended instance interface that allows for additional platform-specific properties.
|
|
@@ -172,6 +173,7 @@ export interface PollUpdateMessageData {
|
|
|
172
173
|
multipleAnswers: boolean;
|
|
173
174
|
}
|
|
174
175
|
export type OutgoingMessageStatus = "sent" | "delivered" | "read" | "failed" | "noAccount" | "notInGroup" | "yellowCard";
|
|
176
|
+
export type WebhookType = "stateInstanceChanged" | "outgoingMessageStatus" | "outgoingAPIMessageReceived" | "outgoingMessageReceived" | "incomingMessageReceived";
|
|
175
177
|
/**
|
|
176
178
|
* Webhook payload received when a message status changes.
|
|
177
179
|
* Used to track delivery and read receipts.
|
|
@@ -190,6 +192,16 @@ export interface OutgoingMessageStatusWebhook {
|
|
|
190
192
|
description?: string;
|
|
191
193
|
sendByApi: boolean;
|
|
192
194
|
}
|
|
195
|
+
export interface StateInstanceWebhook {
|
|
196
|
+
typeWebhook: "stateInstanceChanged";
|
|
197
|
+
instanceData: {
|
|
198
|
+
idInstance: number;
|
|
199
|
+
wid: string;
|
|
200
|
+
typeInstance: string;
|
|
201
|
+
};
|
|
202
|
+
timestamp: number;
|
|
203
|
+
stateInstance: InstanceState;
|
|
204
|
+
}
|
|
193
205
|
export type WebhookMessageData = {
|
|
194
206
|
typeMessage: "textMessage";
|
|
195
207
|
textMessageData: TextMessageData;
|
|
@@ -235,7 +247,7 @@ export interface MessageWebhook {
|
|
|
235
247
|
/**
|
|
236
248
|
* Primary webhook types received from GREEN-API.
|
|
237
249
|
*/
|
|
238
|
-
export type GreenApiWebhook = MessageWebhook | OutgoingMessageStatusWebhook;
|
|
250
|
+
export type GreenApiWebhook = MessageWebhook | OutgoingMessageStatusWebhook | StateInstanceWebhook;
|
|
239
251
|
/**
|
|
240
252
|
* Configuration settings for a GREEN-API instance.
|
|
241
253
|
* Controls webhook behavior, message handling, and other instance features.
|
package/dist/utils/helpers.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Settings } from "../types/types";
|
|
1
2
|
/**
|
|
2
3
|
* Utility functions for working with phone numbers, tokens, and vCards.
|
|
3
4
|
*
|
|
@@ -39,3 +40,34 @@ export declare function generateRandomToken(length?: number): string;
|
|
|
39
40
|
* extractPhoneNumberFromVCard(vcard) // Returns '+1234567890'
|
|
40
41
|
*/
|
|
41
42
|
export declare function extractPhoneNumberFromVCard(vcard: string): string | null;
|
|
43
|
+
/**
|
|
44
|
+
* Validates if a value is appropriate for a specific Settings interface key.
|
|
45
|
+
* Checks type compatibility for numbers, strings, and yes/no enums.
|
|
46
|
+
*
|
|
47
|
+
* @param key - The settings key to validate
|
|
48
|
+
* @param value - The value to check against the key's expected type
|
|
49
|
+
* @returns Boolean indicating if the value is valid for the given key
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* isValidSettingValue('delaySendMessagesMilliseconds', 1000) // Returns true
|
|
53
|
+
* isValidSettingValue('outgoingWebhook', 'maybe') // Returns false
|
|
54
|
+
* isValidSettingValue('webhookUrl', 'https://example.com') // Returns true
|
|
55
|
+
*/
|
|
56
|
+
export declare function isValidSettingValue(key: keyof Settings, value: any): boolean;
|
|
57
|
+
/**
|
|
58
|
+
* Validates and cleans a settings object against the Settings interface.
|
|
59
|
+
* Removes any properties that don't match the interface or have invalid values.
|
|
60
|
+
*
|
|
61
|
+
* @param settings - The settings object to validate and clean
|
|
62
|
+
* @returns A new Settings object containing only valid properties and values
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* const input = {
|
|
66
|
+
* webhookUrl: 'https://example.com',
|
|
67
|
+
* outgoingWebhook: 'yes',
|
|
68
|
+
* invalidKey: 'value',
|
|
69
|
+
* delaySendMessagesMilliseconds: 'invalid'
|
|
70
|
+
* };
|
|
71
|
+
* validateAndCleanSettings(input) // Returns { webhookUrl: 'https://example.com', outgoingWebhook: 'yes' }
|
|
72
|
+
*/
|
|
73
|
+
export declare function validateAndCleanSettings(settings: any): Settings;
|
package/dist/utils/helpers.js
CHANGED
|
@@ -36,6 +36,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
36
36
|
exports.formatPhoneNumber = formatPhoneNumber;
|
|
37
37
|
exports.generateRandomToken = generateRandomToken;
|
|
38
38
|
exports.extractPhoneNumberFromVCard = extractPhoneNumberFromVCard;
|
|
39
|
+
exports.isValidSettingValue = isValidSettingValue;
|
|
40
|
+
exports.validateAndCleanSettings = validateAndCleanSettings;
|
|
39
41
|
const crypto = __importStar(require("crypto"));
|
|
40
42
|
/**
|
|
41
43
|
* Utility functions for working with phone numbers, tokens, and vCards.
|
|
@@ -86,3 +88,65 @@ function extractPhoneNumberFromVCard(vcard) {
|
|
|
86
88
|
const phoneMatch = vcard.match(/TEL(?:;[^:]+)?:([+\d\s-]+)/);
|
|
87
89
|
return phoneMatch ? phoneMatch[1] : null;
|
|
88
90
|
}
|
|
91
|
+
/**
|
|
92
|
+
* Validates if a value is appropriate for a specific Settings interface key.
|
|
93
|
+
* Checks type compatibility for numbers, strings, and yes/no enums.
|
|
94
|
+
*
|
|
95
|
+
* @param key - The settings key to validate
|
|
96
|
+
* @param value - The value to check against the key's expected type
|
|
97
|
+
* @returns Boolean indicating if the value is valid for the given key
|
|
98
|
+
*
|
|
99
|
+
* @example
|
|
100
|
+
* isValidSettingValue('delaySendMessagesMilliseconds', 1000) // Returns true
|
|
101
|
+
* isValidSettingValue('outgoingWebhook', 'maybe') // Returns false
|
|
102
|
+
* isValidSettingValue('webhookUrl', 'https://example.com') // Returns true
|
|
103
|
+
*/
|
|
104
|
+
function isValidSettingValue(key, value) {
|
|
105
|
+
switch (key) {
|
|
106
|
+
case "delaySendMessagesMilliseconds":
|
|
107
|
+
return typeof value === "number";
|
|
108
|
+
case "wid":
|
|
109
|
+
case "webhookUrl":
|
|
110
|
+
case "webhookUrlToken":
|
|
111
|
+
return typeof value === "string";
|
|
112
|
+
case "markIncomingMessagesReaded":
|
|
113
|
+
case "markIncomingMessagesReadedOnReply":
|
|
114
|
+
case "outgoingWebhook":
|
|
115
|
+
case "outgoingMessageWebhook":
|
|
116
|
+
case "outgoingAPIMessageWebhook":
|
|
117
|
+
case "stateWebhook":
|
|
118
|
+
case "incomingWebhook":
|
|
119
|
+
case "keepOnlineStatus":
|
|
120
|
+
case "pollMessageWebhook":
|
|
121
|
+
case "incomingCallWebhook":
|
|
122
|
+
return value === "yes" || value === "no";
|
|
123
|
+
default:
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Validates and cleans a settings object against the Settings interface.
|
|
129
|
+
* Removes any properties that don't match the interface or have invalid values.
|
|
130
|
+
*
|
|
131
|
+
* @param settings - The settings object to validate and clean
|
|
132
|
+
* @returns A new Settings object containing only valid properties and values
|
|
133
|
+
*
|
|
134
|
+
* @example
|
|
135
|
+
* const input = {
|
|
136
|
+
* webhookUrl: 'https://example.com',
|
|
137
|
+
* outgoingWebhook: 'yes',
|
|
138
|
+
* invalidKey: 'value',
|
|
139
|
+
* delaySendMessagesMilliseconds: 'invalid'
|
|
140
|
+
* };
|
|
141
|
+
* validateAndCleanSettings(input) // Returns { webhookUrl: 'https://example.com', outgoingWebhook: 'yes' }
|
|
142
|
+
*/
|
|
143
|
+
function validateAndCleanSettings(settings) {
|
|
144
|
+
const validSettings = {};
|
|
145
|
+
const settingsKeys = Object.keys(settings);
|
|
146
|
+
for (const key of settingsKeys) {
|
|
147
|
+
if (key in validSettings && isValidSettingValue(key, settings[key])) {
|
|
148
|
+
validSettings[key] = settings[key];
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return validSettings;
|
|
152
|
+
}
|