Skip to content

Commit c120b7e

Browse files
authored
Merge pull request #11 from Secreto31126/indexes
2 parents cbbfd1b + ff654d1 commit c120b7e

File tree

4 files changed

+50
-51
lines changed

4 files changed

+50
-51
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ A Whatsapp's Official API helper for Node.js (WIP)
66
1. Whatsapp's Official API is currently on beta acccess.
77
To participate, you can fill [this form](https://www.facebook.com/business/m/whatsapp/business-api).
88

9-
2. This project is a work in progress. Breaking changes are expected from version to version until we hit version 1.0.0.
9+
2. This project is a work in progress. Breaking changes are expected from mid-version to mid-version until it hits version 1.0.0.
10+
11+
3. To know what changes between updates, check out the [releases on Github](https://github.com/Secreto31126/whatsapp-api-js/releases).
1012

1113
## Set up
1214

index.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,7 @@ class WhatsAppAPI {
100100
* @property {Template} Types.Template.Template The API Template type object
101101
* @property {Language} Types.Template.Language The API Language type object
102102
* @property {ButtonComponent} Types.Template.ButtonComponent The API ButtonComponent type object
103-
* @property {UrlButton} Types.Template.UrlButton The API UrlButton type object
104-
* @property {PayloadButton} Types.Template.PayloadButton The API PayloadButton type object
103+
* @property {ButtonParameter} Types.Template.ButtonParameter The API ButtonParameter type object
105104
* @property {HeaderComponent} Types.Template.HeaderComponent The API HeaderComponent type object
106105
* @property {BodyComponent} Types.Template.BodyComponent The API BodyComponent type object
107106
* @property {Parameter} Types.Template.Parameter The API Parameter type object

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "whatsapp-api-js",
3-
"version": "0.1.7",
3+
"version": "0.2.0",
44
"description": "A Whatsapp Official API helper for Node.js",
55
"main": "index.js",
66
"scripts": {

types/template.js

Lines changed: 45 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,12 @@ class Template {
2323
if (!name) throw new Error("Template must have a name");
2424
if (!language) throw new Error("Template must have a language");
2525

26-
const indexes = components.filter(e => e instanceof ButtonComponent).map(e => e.index);
27-
if (indexes.length !== new Set(indexes).size) throw new Error("ButtonComponents must have unique ids");
26+
const temp = [];
27+
for (let component of components) {
28+
if (component instanceof ButtonComponent) temp.push(...component.build());
29+
else temp.push(component);
30+
}
31+
components = temp;
2832

2933
this.name = name;
3034
this.language = language instanceof Language ? language : new Language(language);
@@ -111,72 +115,67 @@ class DateTime {
111115
*
112116
* @property {String} type The type of the component
113117
* @property {String} sub_type The subtype of the component
114-
* @property {String} index The index of the component
115-
* @property {Array<(UrlButton|PayloadButton)>} parameters The parameters of the component
118+
* @property {Array<ButtonParameter>} parameters The ButtonParameters to be used in the build function
119+
* @property {Function} build The function to build the component as a compatible API object
116120
*/
117121
class ButtonComponent {
118122
/**
119-
* Builds a button component for a Template message
123+
* Builds a button component for a Template message.
124+
* The index of the buttons is defined by the order in which you add them to the Template parameters.
120125
*
121-
* @param {Number} index Position index of the button. You can have up to 3 buttons using index values of 0 to 2.
122126
* @param {String} sub_type Type of button to create. Can be either 'url' or 'quick_reply'.
123-
* @param {...(UrlButton|PayloadButton)} parameters Parameters of the button.
127+
* @param {...String} parameters Parameter for each button. The index of each parameter is defined by the order they are sent to the constructor.
128+
* @throws {Error} If sub_type is not either 'url' or 'quick_reply'
129+
* @throws {Error} If parameters is not provided
130+
* @throws {Error} If parameters has over 3 elements
124131
*/
125-
constructor(index, sub_type, ...parameters) {
126-
if (!index?.toString()) throw new Error("ButtonComponent must have an index");
127-
if (!index < 0 || index > 2) throw new Error("ButtonComponent index must be between 0 and 2");
128-
if (!['quick_reply', 'url'].includes(sub_type)) throw new Error("ButtonComponent sub_type must be either 'quick_reply' or 'url'");
129-
if (!parameters?.length) throw new Error("ButtonComponent must have at least one parameter");
132+
constructor(sub_type, ...parameters) {
133+
if (!["url", "quick_reply"].includes(sub_type)) throw new Error("ButtonComponent sub_type must be either 'url' or 'quick_reply'");
134+
if (!parameters?.length) throw new Error("ButtonComponent must have a parameter at least 1 parameter");
135+
if (parameters.length > 3) throw new Error("ButtonComponent can only have up to 3 parameters");
136+
137+
const buttonType = sub_type === "url" ? "text" : "payload";
138+
parameters = parameters.map(e => new ButtonParameter(e, buttonType));
130139

131-
for (const param of parameters) {
132-
if (sub_type === "quick_reply" && param instanceof UrlButton) throw new Error("ButtonComponent of type 'quick_replies' cannot have a UrlButton");
133-
if (sub_type === "url" && param instanceof PayloadButton) throw new Error("ButtonComponent of type 'url' cannot have a PayloadButton");
134-
}
135-
136140
this.type = "button";
137141
this.sub_type = sub_type;
138-
this.index = index.toString();
139142
this.parameters = parameters;
140143
}
141-
}
142144

143-
/**
144-
* Button Parameter API object
145-
*
146-
* @property {String} type The type of the button
147-
* @property {String} text The text of the button
148-
*/
149-
class UrlButton {
150145
/**
151-
* Builds a url button object for a ButtonComponent
146+
* Generates the buttons components for a Template message. For internal use only.
152147
*
153-
* @param {String} text Developer-provided suffix that is appended to the predefined prefix URL in the template.
154-
* @throws {Error} If url is not provided
148+
* @returns {Array<{ type: String, sub_type: String, index: String, parameters: Array<ButtonParameter> }>} An array of API compatible buttons components
155149
*/
156-
constructor(text) {
157-
if (!text) throw new Error("UrlButton must have a text");
158-
this.type = "text";
159-
this.text = text;
150+
build() {
151+
return this.parameters.map((p, i) => {
152+
return { type: this.type, sub_type: this.sub_type, index: i.toString(), parameters: [p] };
153+
});
160154
}
161155
}
162156

163157
/**
164158
* Button Parameter API object
165159
*
166160
* @property {String} type The type of the button
167-
* @property {String} payload The payload of the button
161+
* @property {String} [text] The text of the button
162+
* @property {String} [payload] The payload of the button
168163
*/
169-
class PayloadButton {
164+
class ButtonParameter {
170165
/**
171-
* Builds a payload button object for a ButtonComponent
166+
* Builds a button parameter for a ButtonComponent
172167
*
173-
* @param {String} payload Developer-defined payload that is returned when the button is clicked in addition to the display text on the button
174-
* @throws {Error} If payload is not provided
168+
* @param {String} param Developer-provided data that is used to fill in the template.
169+
* @param {String} type The type of the button. Can be either 'text' or 'payload'.
170+
* @throws {Error} If param is not provided
171+
* @throws {Error} If type is not either 'text' or 'payload'
175172
*/
176-
constructor(payload) {
177-
if (!payload) throw new Error("PayloadButton must have a payload");
178-
this.type = "payload";
179-
this.payload = payload;
173+
constructor(param, type) {
174+
if (!param) throw new Error("UrlButton must have a param");
175+
if (!["text", "payload"].includes(type)) throw new Error("UrlButton must be either 'text' or 'payload'");
176+
177+
this.type = type;
178+
this[type] = param;
180179
}
181180
}
182181

@@ -190,7 +189,7 @@ class HeaderComponent {
190189
/**
191190
* Builds a header component for a Template message
192191
*
193-
* @param {...(Text|Currency|DateTime|Image|Document|Video)} parameters Parameters of the body component
192+
* @param {...(Text|Currency|DateTime|Image|Document|Video|Parameter)} parameters Parameters of the body component
194193
*/
195194
constructor(...parameters) {
196195
this.type = "header";
@@ -208,11 +207,11 @@ class BodyComponent {
208207
/**
209208
* Builds a body component for a Template message
210209
*
211-
* @param {...(Text|Currency|DateTime|Image|Document|Video)} parameters Parameters of the body component
210+
* @param {...(Text|Currency|DateTime|Image|Document|Video|Parameter)} parameters Parameters of the body component
212211
*/
213212
constructor(...parameters) {
214213
this.type = "body";
215-
if (parameters) this.parameters = parameters.map(e => new Parameter(e));
214+
if (parameters) this.parameters = parameters.map(e => e instanceof Parameter ? e : new Parameter(e));
216215
}
217216
}
218217

@@ -249,8 +248,7 @@ module.exports = {
249248
Template,
250249
Language,
251250
ButtonComponent,
252-
UrlButton,
253-
PayloadButton,
251+
ButtonParameter,
254252
HeaderComponent,
255253
BodyComponent,
256254
Parameter,

0 commit comments

Comments
 (0)