@green-api/greenapi-integration 0.1.0 → 0.2.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.
@@ -5,7 +5,31 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.GreenApiClient = void 0;
7
7
  const axios_1 = __importDefault(require("axios"));
8
+ /**
9
+ * Client for direct interaction with GREEN-API's WhatsApp gateway.
10
+ * Provides methods for sending messages, managing instances, and handling files.
11
+ *
12
+ * @category Client
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * const client = new GreenApiClient({
17
+ * idInstance: 12345,
18
+ * apiTokenInstance: "your-token"
19
+ * });
20
+ *
21
+ * await client.sendMessage({
22
+ * chatId: "1234567890@c.us",
23
+ * message: "Hello from GREEN-API!"
24
+ * });
25
+ * ```
26
+ */
8
27
  class GreenApiClient {
28
+ /**
29
+ * Creates a GREEN-API client instance.
30
+ *
31
+ * @param instance - Configuration containing idInstance and apiTokenInstance
32
+ */
9
33
  constructor(instance) {
10
34
  this.instance = instance;
11
35
  this.baseUrl = "https://api.green-api.com";
@@ -36,6 +60,21 @@ class GreenApiClient {
36
60
  ...headers,
37
61
  });
38
62
  }
63
+ /**
64
+ * Sends a text message to a WhatsApp chat.
65
+ *
66
+ * @param message - Message data containing chat ID and text
67
+ * @returns Promise resolving to send response with message ID
68
+ *
69
+ * @example
70
+ * ```typescript
71
+ * await client.sendMessage({
72
+ * chatId: "1234567890@c.us",
73
+ * message: "Hello!",
74
+ * quotedMessageId: "12345" // Optional: reply to a message
75
+ * });
76
+ * ```
77
+ */
39
78
  async sendMessage(message) {
40
79
  return this.makeRequest("post", "sendMessage", {
41
80
  chatId: message.chatId,
@@ -43,6 +82,24 @@ class GreenApiClient {
43
82
  quotedMessageId: message.quotedMessageId,
44
83
  });
45
84
  }
85
+ /**
86
+ * Sends a file from a URL to a WhatsApp chat.
87
+ *
88
+ * @param message - Message data containing chat ID and file URL
89
+ * @returns Promise resolving to send response
90
+ *
91
+ * @example
92
+ * ```typescript
93
+ * await client.sendFileByUrl({
94
+ * chatId: "1234567890@c.us",
95
+ * file: {
96
+ * url: "https://example.com/file.pdf",
97
+ * fileName: "document.pdf"
98
+ * },
99
+ * caption: "Check this file" // Optional
100
+ * });
101
+ * ```
102
+ */
46
103
  async sendFileByUrl(message) {
47
104
  return this.makeRequest("post", "sendFileByUrl", {
48
105
  chatId: message.chatId,
@@ -52,6 +109,24 @@ class GreenApiClient {
52
109
  quotedMessageId: message.quotedMessageId,
53
110
  });
54
111
  }
112
+ /**
113
+ * Sends a file from local data to a WhatsApp chat.
114
+ *
115
+ * @param message - Message data containing chat ID and file data
116
+ * @returns Promise resolving to send response with file URL
117
+ *
118
+ * @example
119
+ * ```typescript
120
+ * await client.sendFileByUpload({
121
+ * chatId: "1234567890@c.us",
122
+ * file: {
123
+ * data: fileBlob,
124
+ * fileName: "image.jpg"
125
+ * },
126
+ * caption: "Check this image"
127
+ * });
128
+ * ```
129
+ */
55
130
  async sendFileByUpload(message) {
56
131
  const formData = new FormData();
57
132
  formData.append("file", message.file.data);
@@ -63,6 +138,22 @@ class GreenApiClient {
63
138
  formData.append("quotedMessageId", message.quotedMessageId);
64
139
  return this.makeFileUploadRequest("sendFileByUpload", formData);
65
140
  }
141
+ /**
142
+ * Creates a poll in a WhatsApp chat.
143
+ *
144
+ * @param message - Poll data with question and options
145
+ * @returns Promise resolving to send response
146
+ *
147
+ * @example
148
+ * ```typescript
149
+ * await client.sendPoll({
150
+ * chatId: "1234567890@c.us",
151
+ * message: "What's your favorite color?",
152
+ * options: ["Red", "Blue", "Green"],
153
+ * multipleAnswers: false
154
+ * });
155
+ * ```
156
+ */
66
157
  async sendPoll(message) {
67
158
  return this.makeRequest("post", "sendPoll", {
68
159
  chatId: message.chatId,
@@ -72,6 +163,12 @@ class GreenApiClient {
72
163
  quotedMessageId: message.quotedMessageId,
73
164
  });
74
165
  }
166
+ /**
167
+ * Forwards messages from one chat to another.
168
+ *
169
+ * @param request - Forward request with source and target chat IDs
170
+ * @returns Promise resolving to forward response
171
+ */
75
172
  async forwardMessages(request) {
76
173
  return this.makeRequest("post", "forwardMessages", {
77
174
  chatId: request.chatId,
@@ -79,6 +176,23 @@ class GreenApiClient {
79
176
  messages: request.messages,
80
177
  });
81
178
  }
179
+ /**
180
+ * Sends a location to a WhatsApp chat.
181
+ *
182
+ * @param message - Location data with coordinates
183
+ * @returns Promise resolving to send response
184
+ *
185
+ * @example
186
+ * ```typescript
187
+ * await client.sendLocation({
188
+ * chatId: "1234567890@c.us",
189
+ * latitude: 51.5074,
190
+ * longitude: -0.1278,
191
+ * nameLocation: "London",
192
+ * address: "London, UK"
193
+ * });
194
+ * ```
195
+ */
82
196
  async sendLocation(message) {
83
197
  return this.makeRequest("post", "sendLocation", {
84
198
  chatId: message.chatId,
@@ -89,6 +203,24 @@ class GreenApiClient {
89
203
  quotedMessageId: message.quotedMessageId,
90
204
  });
91
205
  }
206
+ /**
207
+ * Sends a contact card to a WhatsApp chat.
208
+ *
209
+ * @param message - Contact data
210
+ * @returns Promise resolving to send response
211
+ *
212
+ * @example
213
+ * ```typescript
214
+ * await client.sendContact({
215
+ * chatId: "1234567890@c.us",
216
+ * contact: {
217
+ * phoneContact: 1234567890,
218
+ * firstName: "John",
219
+ * lastName: "Doe"
220
+ * }
221
+ * });
222
+ * ```
223
+ */
92
224
  async sendContact(message) {
93
225
  return this.makeRequest("post", "sendContact", {
94
226
  chatId: message.chatId,
@@ -96,32 +228,81 @@ class GreenApiClient {
96
228
  quotedMessageId: message.quotedMessageId,
97
229
  });
98
230
  }
231
+ /**
232
+ * Reboots the GREEN-API instance.
233
+ *
234
+ * @returns Promise resolving to reboot status
235
+ */
99
236
  async reboot() {
100
237
  return this.makeRequest("get", "reboot");
101
238
  }
239
+ /**
240
+ * Logs out from the GREEN-API instance.
241
+ *
242
+ * @returns Promise resolving to logout status
243
+ */
102
244
  async logout() {
103
245
  return this.makeRequest("get", "logout");
104
246
  }
247
+ /**
248
+ * Gets the current state of the GREEN-API instance.
249
+ *
250
+ * @returns Promise resolving to instance state
251
+ */
105
252
  async getStateInstance() {
106
253
  return this.makeRequest("get", "getStateInstance");
107
254
  }
255
+ /**
256
+ * Gets the QR code for GREEN-API instance authentication.
257
+ *
258
+ * @returns Promise resolving to QR code data
259
+ */
108
260
  async getQR() {
109
261
  return this.makeRequest("get", "qr");
110
262
  }
263
+ /**
264
+ * Gets current instance settings.
265
+ *
266
+ * @returns Promise resolving to settings object
267
+ */
111
268
  async getSettings() {
112
269
  return this.makeRequest("get", "getSettings");
113
270
  }
271
+ /**
272
+ * Updates instance settings.
273
+ *
274
+ * @param settings - New settings to apply
275
+ * @returns Promise resolving to settings update response
276
+ */
114
277
  async setSettings(settings) {
115
278
  return this.makeRequest("post", "setSettings", settings);
116
279
  }
280
+ /**
281
+ * Gets WhatsApp-specific settings.
282
+ *
283
+ * @returns Promise resolving to WhatsApp settings
284
+ */
117
285
  async getWaSettings() {
118
286
  return this.makeRequest("get", "getWaSettings");
119
287
  }
288
+ /**
289
+ * Sets the profile picture for the WhatsApp account.
290
+ *
291
+ * @param file - Image file to use as profile picture
292
+ * @returns Promise resolving to profile picture update response
293
+ */
120
294
  async setProfilePicture(file) {
121
295
  const formData = new FormData();
122
296
  formData.append("file", file);
123
297
  return this.makeFileUploadRequest("setProfilePicture", formData);
124
298
  }
299
+ /**
300
+ * Uploads a file to GREEN-API servers.
301
+ *
302
+ * @param file - File to upload
303
+ * @param customFileName - Optional custom name for the file
304
+ * @returns Promise resolving to upload response with file URL
305
+ */
125
306
  async uploadFile(file, customFileName) {
126
307
  const formData = new FormData();
127
308
  formData.append("file", file);
@@ -140,6 +321,13 @@ class GreenApiClient {
140
321
  }
141
322
  return this.makeFileUploadRequest("uploadFile", formData, headers);
142
323
  }
324
+ /**
325
+ * Gets authorization code for a phone number.
326
+ *
327
+ * @param phoneNumber - Phone number to get code for
328
+ * @returns Promise resolving to authorization code response
329
+ * @throws {Error} If phone number is not an integer
330
+ */
143
331
  async getAuthorizationCode(phoneNumber) {
144
332
  if (!Number.isInteger(phoneNumber)) {
145
333
  throw new Error("Phone number must contain only digits");
@@ -1,7 +1,52 @@
1
1
  import { BaseRequest } from "../types/types";
2
2
  import { StorageProvider } from "./storage-provider";
3
+ /**
4
+ * Base authentication guard for validating incoming GREEN-API webhooks.
5
+ * Ensures that webhooks are authenticated and come from valid instances.
6
+ *
7
+ * @category Authentication
8
+ * @typeParam T - Request type extending BaseRequest, contains headers and body
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * class WebhookGuard extends BaseGreenApiAuthGuard<ExpressRequest> {
13
+ * constructor(storage: StorageProvider) {
14
+ * super(storage);
15
+ * }
16
+ * }
17
+ *
18
+ * // Usage in Express
19
+ * app.post('/webhook', async (req, res) => {
20
+ * const guard = new WebhookGuard(storage);
21
+ * try {
22
+ * await guard.validateRequest(req);
23
+ * // Process webhook
24
+ * } catch (error) {
25
+ * if (error instanceof AuthenticationError) {
26
+ * res.status(401).json({ error: error.message });
27
+ * }
28
+ * }
29
+ * });
30
+ * ```
31
+ */
3
32
  export declare abstract class BaseGreenApiAuthGuard<T extends BaseRequest = BaseRequest> {
4
33
  protected storage: StorageProvider;
34
+ /**
35
+ * Creates an instance of BaseGreenApiAuthGuard.
36
+ *
37
+ * @param storage - Storage provider for accessing instance data
38
+ */
5
39
  constructor(storage: StorageProvider);
40
+ /**
41
+ * Validates an incoming webhook request.
42
+ * Checks for presence of authorization token and validates it against instance settings.
43
+ *
44
+ * @param request - The incoming request with headers and body
45
+ * @returns Promise resolving to true if validation succeeds
46
+ * @throws {AuthenticationError} If authorization header is missing
47
+ * @throws {AuthenticationError} If webhook format is invalid
48
+ * @throws {AuthenticationError} If instance is not found
49
+ * @throws {AuthenticationError} If token is invalid
50
+ */
6
51
  validateRequest(request: T): Promise<boolean>;
7
52
  }
@@ -2,10 +2,55 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.BaseGreenApiAuthGuard = void 0;
4
4
  const errors_1 = require("./errors");
5
+ /**
6
+ * Base authentication guard for validating incoming GREEN-API webhooks.
7
+ * Ensures that webhooks are authenticated and come from valid instances.
8
+ *
9
+ * @category Authentication
10
+ * @typeParam T - Request type extending BaseRequest, contains headers and body
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * class WebhookGuard extends BaseGreenApiAuthGuard<ExpressRequest> {
15
+ * constructor(storage: StorageProvider) {
16
+ * super(storage);
17
+ * }
18
+ * }
19
+ *
20
+ * // Usage in Express
21
+ * app.post('/webhook', async (req, res) => {
22
+ * const guard = new WebhookGuard(storage);
23
+ * try {
24
+ * await guard.validateRequest(req);
25
+ * // Process webhook
26
+ * } catch (error) {
27
+ * if (error instanceof AuthenticationError) {
28
+ * res.status(401).json({ error: error.message });
29
+ * }
30
+ * }
31
+ * });
32
+ * ```
33
+ */
5
34
  class BaseGreenApiAuthGuard {
35
+ /**
36
+ * Creates an instance of BaseGreenApiAuthGuard.
37
+ *
38
+ * @param storage - Storage provider for accessing instance data
39
+ */
6
40
  constructor(storage) {
7
41
  this.storage = storage;
8
42
  }
43
+ /**
44
+ * Validates an incoming webhook request.
45
+ * Checks for presence of authorization token and validates it against instance settings.
46
+ *
47
+ * @param request - The incoming request with headers and body
48
+ * @returns Promise resolving to true if validation succeeds
49
+ * @throws {AuthenticationError} If authorization header is missing
50
+ * @throws {AuthenticationError} If webhook format is invalid
51
+ * @throws {AuthenticationError} If instance is not found
52
+ * @throws {AuthenticationError} If token is invalid
53
+ */
9
54
  async validateRequest(request) {
10
55
  const token = request.headers["authorization"];
11
56
  if (!token) {
@@ -1,5 +1,49 @@
1
- import { IncomingGreenApiWebhook, Message } from "../types/types";
1
+ import { GreenApiWebhook, Message } from "../types/types";
2
+ /**
3
+ * Abstract class for transforming messages between your platform's format and GREEN-API's format.
4
+ * Implement this class to define how messages are converted between the two systems.
5
+ *
6
+ * @category Transformer
7
+ * @typeParam TPlatformWebhook - Your platform's webhook message type
8
+ * @typeParam TPlatformMessage - Your platform's outgoing message type
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * class YourTransformer extends MessageTransformer<YourWebhook, YourMessage> {
13
+ * toPlatformMessage(webhook: GreenApiWebhook): YourMessage {
14
+ * return {
15
+ * recipient: webhook.senderData.sender,
16
+ * content: webhook.messageData.textMessageData?.textMessage || "",
17
+ * };
18
+ * }
19
+ *
20
+ * toGreenApiMessage(message: YourWebhook): Message {
21
+ * return {
22
+ * type: "text",
23
+ * chatId: formatPhoneNumber(message.from),
24
+ * message: message.content,
25
+ * };
26
+ * }
27
+ * }
28
+ * ```
29
+ */
2
30
  export declare abstract class MessageTransformer<TPlatformWebhook, TPlatformMessage> {
3
- abstract toPlatformMessage(webhook: IncomingGreenApiWebhook): TPlatformMessage;
31
+ /**
32
+ * Transforms a GREEN-API webhook into your platform's message format.
33
+ * Implement this method to convert incoming WhatsApp messages to your platform's format.
34
+ *
35
+ * @param webhook - The incoming webhook from GREEN-API
36
+ * @returns Your platform's message format
37
+ * @throws {Error} If the webhook format is invalid or unsupported
38
+ */
39
+ abstract toPlatformMessage(webhook: GreenApiWebhook): TPlatformMessage;
40
+ /**
41
+ * Transforms your platform's message format into GREEN-API's message format.
42
+ * Implement this method to convert your platform's messages to WhatsApp format.
43
+ *
44
+ * @param message - The message in your platform's format
45
+ * @returns Message formatted for GREEN-API
46
+ * @throws {Error} If the message format is invalid or unsupported
47
+ */
4
48
  abstract toGreenApiMessage(message: TPlatformWebhook): Message;
5
49
  }
@@ -1,6 +1,34 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.MessageTransformer = void 0;
4
+ /**
5
+ * Abstract class for transforming messages between your platform's format and GREEN-API's format.
6
+ * Implement this class to define how messages are converted between the two systems.
7
+ *
8
+ * @category Transformer
9
+ * @typeParam TPlatformWebhook - Your platform's webhook message type
10
+ * @typeParam TPlatformMessage - Your platform's outgoing message type
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * class YourTransformer extends MessageTransformer<YourWebhook, YourMessage> {
15
+ * toPlatformMessage(webhook: GreenApiWebhook): YourMessage {
16
+ * return {
17
+ * recipient: webhook.senderData.sender,
18
+ * content: webhook.messageData.textMessageData?.textMessage || "",
19
+ * };
20
+ * }
21
+ *
22
+ * toGreenApiMessage(message: YourWebhook): Message {
23
+ * return {
24
+ * type: "text",
25
+ * chatId: formatPhoneNumber(message.from),
26
+ * message: message.content,
27
+ * };
28
+ * }
29
+ * }
30
+ * ```
31
+ */
4
32
  class MessageTransformer {
5
33
  }
6
34
  exports.MessageTransformer = MessageTransformer;
@@ -1,9 +1,69 @@
1
- import { BaseInstance, BaseUser, Instance, Settings } from "../types/types";
2
- export declare abstract class StorageProvider<TUser extends BaseUser = BaseUser, TInstance extends BaseInstance = Instance, TUserCreate extends Record<string, any> = any, TUserUpdate extends Record<string, any> = any> {
3
- abstract createInstance(instance: BaseInstance, userId: bigint | number, settings?: Settings): Promise<TInstance>;
1
+ import { BaseUser, Instance, Settings } from "../types/types";
2
+ /**
3
+ * Abstract class for managing instance and user data storage.
4
+ * Implement this class to define how your integration stores and retrieves data.
5
+ *
6
+ * @category Storage
7
+ * @typeParam TUser - User entity type, extends BaseUser
8
+ * @typeParam TInstance - Instance entity type, extends Instance
9
+ * @typeParam TUserCreate - Shape of data required to create a user
10
+ * @typeParam TUserUpdate - Shape of data allowed for user updates
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * class PostgresStorage extends StorageProvider<User, Instance> {
15
+ * async createInstance(instance: Instance, userId: bigint, settings?: Settings) {
16
+ * return prisma.instance.create({
17
+ * data: { ...instance, userId, settings }
18
+ * });
19
+ * }
20
+ * }
21
+ * ```
22
+ */
23
+ export declare abstract class StorageProvider<TUser extends BaseUser = BaseUser, TInstance extends Instance = Instance, TUserCreate extends Record<string, any> = any, TUserUpdate extends Record<string, any> = any> {
24
+ /**
25
+ * Creates a new instance in storage.
26
+ *
27
+ * @param instance - The instance data to store
28
+ * @param userId - ID of the user who owns this instance
29
+ * @param settings - Optional GREEN-API settings for the instance
30
+ * @returns Promise resolving to the created instance
31
+ */
32
+ abstract createInstance(instance: Instance, userId: bigint | number, settings?: Settings): Promise<TInstance>;
33
+ /**
34
+ * Retrieves an instance by its ID.
35
+ *
36
+ * @param idInstance - The instance ID to look up
37
+ * @returns Promise resolving to the instance or null if not found
38
+ */
4
39
  abstract getInstance(idInstance: number | bigint): Promise<TInstance | null>;
40
+ /**
41
+ * Removes an instance from storage.
42
+ *
43
+ * @param instanceId - ID of the instance to remove
44
+ * @returns Promise resolving to the removed instance
45
+ */
5
46
  abstract removeInstance(instanceId: number | bigint): Promise<TInstance>;
47
+ /**
48
+ * Creates a new user in storage.
49
+ *
50
+ * @param data - User data matching TUserCreate type
51
+ * @returns Promise resolving to the created user
52
+ */
6
53
  abstract createUser(data: TUserCreate): Promise<TUser>;
54
+ /**
55
+ * Finds a user by identifier (usually email or username).
56
+ *
57
+ * @param identifier - The identifier to look up
58
+ * @returns Promise resolving to the user or null if not found
59
+ */
7
60
  abstract findUser(identifier: string): Promise<TUser | null>;
61
+ /**
62
+ * Updates an existing user's data.
63
+ *
64
+ * @param identifier - The identifier of the user to update
65
+ * @param data - Partial update data matching TUserUpdate type
66
+ * @returns Promise resolving to the updated user
67
+ */
8
68
  abstract updateUser(identifier: string, data: Partial<TUserUpdate>): Promise<TUser>;
9
69
  }
@@ -1,6 +1,27 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.StorageProvider = void 0;
4
+ /**
5
+ * Abstract class for managing instance and user data storage.
6
+ * Implement this class to define how your integration stores and retrieves data.
7
+ *
8
+ * @category Storage
9
+ * @typeParam TUser - User entity type, extends BaseUser
10
+ * @typeParam TInstance - Instance entity type, extends Instance
11
+ * @typeParam TUserCreate - Shape of data required to create a user
12
+ * @typeParam TUserUpdate - Shape of data allowed for user updates
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * class PostgresStorage extends StorageProvider<User, Instance> {
17
+ * async createInstance(instance: Instance, userId: bigint, settings?: Settings) {
18
+ * return prisma.instance.create({
19
+ * data: { ...instance, userId, settings }
20
+ * });
21
+ * }
22
+ * }
23
+ * ```
24
+ */
4
25
  class StorageProvider {
5
26
  }
6
27
  exports.StorageProvider = StorageProvider;
package/dist/index.d.ts CHANGED
@@ -5,3 +5,4 @@ export { MessageTransformer } from "./core/message-transformer";
5
5
  export { BaseGreenApiAuthGuard } from "./core/guard";
6
6
  export { StorageProvider } from "./core/storage-provider";
7
7
  export * from "./utils/helpers";
8
+ export * from "./core/errors";
package/dist/index.js CHANGED
@@ -27,3 +27,4 @@ Object.defineProperty(exports, "BaseGreenApiAuthGuard", { enumerable: true, get:
27
27
  var storage_provider_1 = require("./core/storage-provider");
28
28
  Object.defineProperty(exports, "StorageProvider", { enumerable: true, get: function () { return storage_provider_1.StorageProvider; } });
29
29
  __exportStar(require("./utils/helpers"), exports);
30
+ __exportStar(require("./core/errors"), exports);