@green-api/greenapi-integration 0.1.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.
@@ -3,17 +3,72 @@ 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
+ /**
7
+ * Base adapter for platform integrations with GREEN-API.
8
+ * This class handles the core integration logic between your platform and GREEN-API's WhatsApp gateway.
9
+ *
10
+ * @category Core
11
+ * @typeParam TPlatformWebhook - The webhook type specific to your platform
12
+ * @typeParam TPlatformMessage - The message type specific to your platform
13
+ * @typeParam TUser - User type extending BaseUser (default: BaseUser)
14
+ * @typeParam TInstance - Instance type extending Instance (default: Instance)
15
+ *
16
+ * @example
17
+ * ```typescript
18
+ * class YourAdapter extends BaseAdapter<YourWebhook, YourMessage> {
19
+ * async createPlatformClient(config: YourConfig) {
20
+ * return new YourPlatformClient(config);
21
+ * }
22
+ *
23
+ * async sendToPlatform(message: YourMessage, instance: Instance) {
24
+ * const client = await this.createPlatformClient(instance.config);
25
+ * await client.sendMessage(message);
26
+ * }
27
+ * }
28
+ * ```
29
+ */
6
30
  class BaseAdapter {
31
+ /**
32
+ * Creates an instance of BaseAdapter.
33
+ *
34
+ * @param transformer - Message transformer for converting between platform and GREEN-API formats
35
+ * @param storage - Storage provider for user and instance data
36
+ */
7
37
  constructor(transformer, storage) {
8
38
  this.transformer = transformer;
9
39
  this.storage = storage;
10
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
+ }
52
+ /**
53
+ * Creates a GREEN-API client instance.
54
+ *
55
+ * @param instance - The instance configuration containing ID and token
56
+ * @returns GREEN-API client
57
+ */
11
58
  createGreenApiClient(instance) {
12
59
  return new green_api_client_1.GreenApiClient({
13
60
  idInstance: instance.idInstance,
14
61
  apiTokenInstance: instance.apiTokenInstance,
15
62
  });
16
63
  }
64
+ /**
65
+ * Handles and wraps errors in IntegrationError.
66
+ *
67
+ * @param context - Error context description
68
+ * @param error - Original error
69
+ * @throws {IntegrationError} Always throws wrapped error
70
+ * @internal This method is used internally by the adapter
71
+ */
17
72
  handleError(context, error) {
18
73
  if (error instanceof errors_1.IntegrationError) {
19
74
  throw error;
@@ -21,6 +76,14 @@ class BaseAdapter {
21
76
  const errorMessage = error instanceof Error ? error.message : String(error);
22
77
  throw new errors_1.IntegrationError(`${context}: ${errorMessage}`, "UNEXPECTED_ERROR", 500, { originalError: error });
23
78
  }
79
+ /**
80
+ * Handles incoming webhooks from your platform and sends them to GREEN-API.
81
+ *
82
+ * @param message - The webhook message from your platform
83
+ * @param idInstance - The GREEN-API instance ID
84
+ * @returns Promise resolving to the send response
85
+ * @throws {IntegrationError} If instance is not found or message handling fails
86
+ */
24
87
  async handlePlatformWebhook(message, idInstance) {
25
88
  try {
26
89
  const instance = await this.storage.getInstance(idInstance);
@@ -52,24 +115,45 @@ class BaseAdapter {
52
115
  this.handleError("Failed to handle incoming message", error);
53
116
  }
54
117
  }
118
+ /**
119
+ * Handles incoming GREEN-API webhooks and forwards them to your platform.
120
+ *
121
+ * @param webhook - The webhook from GREEN-API
122
+ * @param allowedTypes - Array of webhook types to process, otherwise skipped
123
+ * @throws {NotFoundError} If instance is not found
124
+ * @throws {IntegrationError} If webhook handling fails
125
+ */
55
126
  async handleGreenApiWebhook(webhook, allowedTypes) {
56
127
  if (!allowedTypes.includes(webhook.typeWebhook)) {
57
128
  return;
58
129
  }
59
130
  try {
60
- const transformedMessage = await this.transformer.toPlatformMessage(webhook);
61
- const instance = await this.storage.getInstance(webhook.instanceData.idInstance);
62
- if (!instance) {
63
- throw new errors_1.NotFoundError("Instance not found");
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);
64
141
  }
65
- await this.sendToPlatform(transformedMessage, instance);
66
142
  }
67
143
  catch (error) {
68
144
  this.handleError("Failed to handle GREEN-API webhook", error);
69
145
  }
70
146
  }
71
- async createInstance(instance, settings, userCred) {
72
- console.log(instance, settings, userCred);
147
+ /**
148
+ * Creates a new instance with specified settings.
149
+ *
150
+ * @param instance - The instance configuration
151
+ * @param userCred - User credentials
152
+ * @returns Promise resolving to the created instance
153
+ * @throws {NotFoundError} If user is not found
154
+ * @throws {IntegrationError} If instance creation fails
155
+ */
156
+ async createInstance(instance, userCred) {
73
157
  try {
74
158
  const user = await this.storage.findUser(userCred);
75
159
  if (!user) {
@@ -82,14 +166,23 @@ class BaseAdapter {
82
166
  catch (error) {
83
167
  throw new errors_1.IntegrationError(`Failed to get settings for instance ${instance.idInstance}: ${error.message}`, "INTEGRATION_ERROR");
84
168
  }
85
- const createdInstance = await this.storage.createInstance(instance, user.id, settings);
86
- await client.setSettings(settings);
169
+ const createdInstance = await this.storage.createInstance(instance, user.id);
170
+ if (instance.settings) {
171
+ await client.setSettings(instance.settings);
172
+ }
87
173
  return createdInstance;
88
174
  }
89
175
  catch (error) {
90
176
  this.handleError("Failed to add instance", error);
91
177
  }
92
178
  }
179
+ /**
180
+ * Removes an instance by ID.
181
+ *
182
+ * @param idInstance - The instance ID to remove
183
+ * @returns Promise resolving to the removed instance
184
+ * @throws {NotFoundError} If instance is not found
185
+ */
93
186
  async removeInstance(idInstance) {
94
187
  try {
95
188
  const instance = await this.storage.getInstance(idInstance);
@@ -102,6 +195,13 @@ class BaseAdapter {
102
195
  this.handleError("Failed to remove instance", error);
103
196
  }
104
197
  }
198
+ /**
199
+ * Retrieves an instance by ID.
200
+ *
201
+ * @param idInstance - The instance ID to retrieve
202
+ * @returns Promise resolving to the instance or null if not found
203
+ * @throws {IntegrationError} If retrieval fails
204
+ */
105
205
  async getInstance(idInstance) {
106
206
  try {
107
207
  return this.storage.getInstance(idInstance);
@@ -110,15 +210,31 @@ class BaseAdapter {
110
210
  this.handleError("Failed to remove instance", error);
111
211
  }
112
212
  }
213
+ /**
214
+ * Updates user information.
215
+ *
216
+ * @param userCred - User credentials
217
+ * @param userUpdateData - New user data
218
+ * @returns Promise resolving to success status
219
+ * @throws {IntegrationError} If update fails
220
+ */
113
221
  async updateUser(userCred, userUpdateData) {
114
222
  try {
115
- await this.storage.updateUser(userCred, userUpdateData);
116
- return { status: "ok", message: "Token updated successfully" };
223
+ return this.storage.updateUser(userCred, userUpdateData);
117
224
  }
118
225
  catch (error) {
119
226
  this.handleError(`Failed to update user ${userCred}`, error);
120
227
  }
121
228
  }
229
+ /**
230
+ * Creates a new user in the storage.
231
+ * This method is implemented in the base adapter but can be overridden if needed.
232
+ *
233
+ * @param userCred - User credentials
234
+ * @param data - User data
235
+ * @throws {BadRequestError} If user already exists
236
+ * @throws {IntegrationError} If creation fails
237
+ */
122
238
  async createUser(userCred, data) {
123
239
  const existingUser = await this.storage.findUser(userCred);
124
240
  if (existingUser) {
@@ -1,15 +1,90 @@
1
+ /**
2
+ * Base error class for all integration-related errors.
3
+ *
4
+ * @category Errors
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * throw new IntegrationError(
9
+ * "Failed to process webhook",
10
+ * "PROCESSING_ERROR",
11
+ * 500,
12
+ * { webhookId: "123" }
13
+ * );
14
+ * ```
15
+ */
1
16
  export declare class IntegrationError extends Error {
2
17
  readonly code: string;
3
18
  readonly statusCode: number;
4
19
  readonly details?: unknown | undefined;
20
+ /**
21
+ * Creates an integration error.
22
+ *
23
+ * @param message - Human-readable error message
24
+ * @param code - Error code for programmatic handling
25
+ * @param statusCode - HTTP status code (default: 500)
26
+ * @param details - Additional error details or context
27
+ */
5
28
  constructor(message: string, code: string, statusCode?: number, details?: unknown | undefined);
6
29
  }
30
+ /**
31
+ * Error thrown when request validation fails or request data is invalid.
32
+ *
33
+ * @category Errors
34
+ *
35
+ * @example
36
+ * ```typescript
37
+ * if (!instanceId) {
38
+ * throw new BadRequestError("Instance ID is required");
39
+ * }
40
+ * ```
41
+ */
7
42
  export declare class BadRequestError extends IntegrationError {
43
+ /**
44
+ * Creates a bad request error.
45
+ *
46
+ * @param message - Human-readable error message
47
+ * @param details - Additional error details or context
48
+ */
8
49
  constructor(message: string, details?: unknown);
9
50
  }
51
+ /**
52
+ * Error thrown when authentication fails or credentials are invalid.
53
+ *
54
+ * @category Errors
55
+ *
56
+ * @example
57
+ * ```typescript
58
+ * if (!token) {
59
+ * throw new AuthenticationError("Authentication token is missing");
60
+ * }
61
+ * ```
62
+ */
10
63
  export declare class AuthenticationError extends IntegrationError {
64
+ /**
65
+ * Creates an authentication error.
66
+ *
67
+ * @param message - Human-readable error message
68
+ */
11
69
  constructor(message: string);
12
70
  }
71
+ /**
72
+ * Error thrown when a requested resource is not found.
73
+ *
74
+ * @category Errors
75
+ *
76
+ * @example
77
+ * ```typescript
78
+ * if (!instance) {
79
+ * throw new NotFoundError("No instance with such ID");
80
+ * }
81
+ * ```
82
+ */
13
83
  export declare class NotFoundError extends IntegrationError {
84
+ /**
85
+ * Creates a not found error.
86
+ *
87
+ * @param message - Human-readable error message
88
+ */
14
89
  constructor(message: string);
15
90
  }
@@ -1,7 +1,30 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.NotFoundError = exports.AuthenticationError = exports.BadRequestError = exports.IntegrationError = void 0;
4
+ /**
5
+ * Base error class for all integration-related errors.
6
+ *
7
+ * @category Errors
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * throw new IntegrationError(
12
+ * "Failed to process webhook",
13
+ * "PROCESSING_ERROR",
14
+ * 500,
15
+ * { webhookId: "123" }
16
+ * );
17
+ * ```
18
+ */
4
19
  class IntegrationError extends Error {
20
+ /**
21
+ * Creates an integration error.
22
+ *
23
+ * @param message - Human-readable error message
24
+ * @param code - Error code for programmatic handling
25
+ * @param statusCode - HTTP status code (default: 500)
26
+ * @param details - Additional error details or context
27
+ */
5
28
  constructor(message, code, statusCode = 500, details) {
6
29
  super(message);
7
30
  this.code = code;
@@ -11,19 +34,71 @@ class IntegrationError extends Error {
11
34
  }
12
35
  }
13
36
  exports.IntegrationError = IntegrationError;
37
+ /**
38
+ * Error thrown when request validation fails or request data is invalid.
39
+ *
40
+ * @category Errors
41
+ *
42
+ * @example
43
+ * ```typescript
44
+ * if (!instanceId) {
45
+ * throw new BadRequestError("Instance ID is required");
46
+ * }
47
+ * ```
48
+ */
14
49
  class BadRequestError extends IntegrationError {
50
+ /**
51
+ * Creates a bad request error.
52
+ *
53
+ * @param message - Human-readable error message
54
+ * @param details - Additional error details or context
55
+ */
15
56
  constructor(message, details) {
16
57
  super(message, "VALIDATION_ERROR", 400, details);
17
58
  }
18
59
  }
19
60
  exports.BadRequestError = BadRequestError;
61
+ /**
62
+ * Error thrown when authentication fails or credentials are invalid.
63
+ *
64
+ * @category Errors
65
+ *
66
+ * @example
67
+ * ```typescript
68
+ * if (!token) {
69
+ * throw new AuthenticationError("Authentication token is missing");
70
+ * }
71
+ * ```
72
+ */
20
73
  class AuthenticationError extends IntegrationError {
74
+ /**
75
+ * Creates an authentication error.
76
+ *
77
+ * @param message - Human-readable error message
78
+ */
21
79
  constructor(message) {
22
80
  super(message, "AUTHENTICATION_ERROR", 401);
23
81
  }
24
82
  }
25
83
  exports.AuthenticationError = AuthenticationError;
84
+ /**
85
+ * Error thrown when a requested resource is not found.
86
+ *
87
+ * @category Errors
88
+ *
89
+ * @example
90
+ * ```typescript
91
+ * if (!instance) {
92
+ * throw new NotFoundError("No instance with such ID");
93
+ * }
94
+ * ```
95
+ */
26
96
  class NotFoundError extends IntegrationError {
97
+ /**
98
+ * Creates a not found error.
99
+ *
100
+ * @param message - Human-readable error message
101
+ */
27
102
  constructor(message) {
28
103
  super(message, "NOT_FOUND_ERROR", 404);
29
104
  }
@@ -1,28 +1,216 @@
1
1
  import { Instance, Settings, SendMessage, SendFileByUrl, SendFileByUpload, SendPoll, StateInstance, Reboot, Logout, QR, SendResponse, SendFileByUploadResponse, SetSettingsResponse, GetAuthorizationCode, SetProfilePicture, WaSettings, UploadFile, SendLocation, SendContact, ForwardMessages, ForwardMessagesResponse } from "../types/types";
2
+ /**
3
+ * Client for direct interaction with GREEN-API's WhatsApp gateway.
4
+ * Provides methods for sending messages, managing instances, and handling files.
5
+ *
6
+ * @category Client
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * const client = new GreenApiClient({
11
+ * idInstance: 12345,
12
+ * apiTokenInstance: "your-token"
13
+ * });
14
+ *
15
+ * await client.sendMessage({
16
+ * chatId: "1234567890@c.us",
17
+ * message: "Hello from GREEN-API!"
18
+ * });
19
+ * ```
20
+ */
2
21
  export declare class GreenApiClient {
3
22
  private instance;
4
23
  private client;
5
24
  private readonly baseUrl;
25
+ /**
26
+ * Creates a GREEN-API client instance.
27
+ *
28
+ * @param instance - Configuration containing idInstance and apiTokenInstance
29
+ */
6
30
  constructor(instance: Instance);
7
31
  private buildUrl;
8
32
  private buildEndpoint;
9
33
  private makeRequest;
10
34
  private makeFileUploadRequest;
35
+ /**
36
+ * Sends a text message to a WhatsApp chat.
37
+ *
38
+ * @param message - Message data containing chat ID and text
39
+ * @returns Promise resolving to send response with message ID
40
+ *
41
+ * @example
42
+ * ```typescript
43
+ * await client.sendMessage({
44
+ * chatId: "1234567890@c.us",
45
+ * message: "Hello!",
46
+ * quotedMessageId: "12345" // Optional: reply to a message
47
+ * });
48
+ * ```
49
+ */
11
50
  sendMessage(message: SendMessage): Promise<SendResponse>;
51
+ /**
52
+ * Sends a file from a URL to a WhatsApp chat.
53
+ *
54
+ * @param message - Message data containing chat ID and file URL
55
+ * @returns Promise resolving to send response
56
+ *
57
+ * @example
58
+ * ```typescript
59
+ * await client.sendFileByUrl({
60
+ * chatId: "1234567890@c.us",
61
+ * file: {
62
+ * url: "https://example.com/file.pdf",
63
+ * fileName: "document.pdf"
64
+ * },
65
+ * caption: "Check this file" // Optional
66
+ * });
67
+ * ```
68
+ */
12
69
  sendFileByUrl(message: SendFileByUrl): Promise<SendResponse>;
70
+ /**
71
+ * Sends a file from local data to a WhatsApp chat.
72
+ *
73
+ * @param message - Message data containing chat ID and file data
74
+ * @returns Promise resolving to send response with file URL
75
+ *
76
+ * @example
77
+ * ```typescript
78
+ * await client.sendFileByUpload({
79
+ * chatId: "1234567890@c.us",
80
+ * file: {
81
+ * data: fileBlob,
82
+ * fileName: "image.jpg"
83
+ * },
84
+ * caption: "Check this image"
85
+ * });
86
+ * ```
87
+ */
13
88
  sendFileByUpload(message: SendFileByUpload): Promise<SendFileByUploadResponse>;
89
+ /**
90
+ * Creates a poll in a WhatsApp chat.
91
+ *
92
+ * @param message - Poll data with question and options
93
+ * @returns Promise resolving to send response
94
+ *
95
+ * @example
96
+ * ```typescript
97
+ * await client.sendPoll({
98
+ * chatId: "1234567890@c.us",
99
+ * message: "What's your favorite color?",
100
+ * options: ["Red", "Blue", "Green"],
101
+ * multipleAnswers: false
102
+ * });
103
+ * ```
104
+ */
14
105
  sendPoll(message: SendPoll): Promise<SendResponse>;
106
+ /**
107
+ * Forwards messages from one chat to another.
108
+ *
109
+ * @param request - Forward request with source and target chat IDs
110
+ * @returns Promise resolving to forward response
111
+ */
15
112
  forwardMessages(request: ForwardMessages): Promise<ForwardMessagesResponse>;
113
+ /**
114
+ * Sends a location to a WhatsApp chat.
115
+ *
116
+ * @param message - Location data with coordinates
117
+ * @returns Promise resolving to send response
118
+ *
119
+ * @example
120
+ * ```typescript
121
+ * await client.sendLocation({
122
+ * chatId: "1234567890@c.us",
123
+ * latitude: 51.5074,
124
+ * longitude: -0.1278,
125
+ * nameLocation: "London",
126
+ * address: "London, UK"
127
+ * });
128
+ * ```
129
+ */
16
130
  sendLocation(message: SendLocation): Promise<SendResponse>;
131
+ /**
132
+ * Sends a contact card to a WhatsApp chat.
133
+ *
134
+ * @param message - Contact data
135
+ * @returns Promise resolving to send response
136
+ *
137
+ * @example
138
+ * ```typescript
139
+ * await client.sendContact({
140
+ * chatId: "1234567890@c.us",
141
+ * contact: {
142
+ * phoneContact: 1234567890,
143
+ * firstName: "John",
144
+ * lastName: "Doe"
145
+ * }
146
+ * });
147
+ * ```
148
+ */
17
149
  sendContact(message: SendContact): Promise<SendResponse>;
150
+ /**
151
+ * Reboots the GREEN-API instance.
152
+ *
153
+ * @returns Promise resolving to reboot status
154
+ */
18
155
  reboot(): Promise<Reboot>;
156
+ /**
157
+ * Logs out from the GREEN-API instance.
158
+ *
159
+ * @returns Promise resolving to logout status
160
+ */
19
161
  logout(): Promise<Logout>;
162
+ /**
163
+ * Gets the current state of the GREEN-API instance.
164
+ *
165
+ * @returns Promise resolving to instance state
166
+ */
20
167
  getStateInstance(): Promise<StateInstance>;
168
+ /**
169
+ * Gets the QR code for GREEN-API instance authentication.
170
+ *
171
+ * @returns Promise resolving to QR code data
172
+ */
21
173
  getQR(): Promise<QR>;
174
+ /**
175
+ * Gets current instance settings.
176
+ *
177
+ * @returns Promise resolving to settings object
178
+ */
22
179
  getSettings(): Promise<Settings>;
180
+ /**
181
+ * Updates instance settings.
182
+ *
183
+ * @param settings - New settings to apply
184
+ * @returns Promise resolving to settings update response
185
+ */
23
186
  setSettings(settings: Settings): Promise<SetSettingsResponse>;
187
+ /**
188
+ * Gets WhatsApp-specific settings.
189
+ *
190
+ * @returns Promise resolving to WhatsApp settings
191
+ */
24
192
  getWaSettings(): Promise<WaSettings>;
193
+ /**
194
+ * Sets the profile picture for the WhatsApp account.
195
+ *
196
+ * @param file - Image file to use as profile picture
197
+ * @returns Promise resolving to profile picture update response
198
+ */
25
199
  setProfilePicture(file: Blob | File): Promise<SetProfilePicture>;
200
+ /**
201
+ * Uploads a file to GREEN-API servers.
202
+ *
203
+ * @param file - File to upload
204
+ * @param customFileName - Optional custom name for the file
205
+ * @returns Promise resolving to upload response with file URL
206
+ */
26
207
  uploadFile(file: Blob | File, customFileName?: string): Promise<UploadFile>;
208
+ /**
209
+ * Gets authorization code for a phone number.
210
+ *
211
+ * @param phoneNumber - Phone number to get code for
212
+ * @returns Promise resolving to authorization code response
213
+ * @throws {Error} If phone number is not an integer
214
+ */
27
215
  getAuthorizationCode(phoneNumber: number): Promise<GetAuthorizationCode>;
28
216
  }