@@ -23,8 +23,12 @@ class Template {
23
23
if ( ! name ) throw new Error ( "Template must have a name" ) ;
24
24
if ( ! language ) throw new Error ( "Template must have a language" ) ;
25
25
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 ;
28
32
29
33
this . name = name ;
30
34
this . language = language instanceof Language ? language : new Language ( language ) ;
@@ -111,72 +115,67 @@ class DateTime {
111
115
*
112
116
* @property {String } type The type of the component
113
117
* @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
116
120
*/
117
121
class ButtonComponent {
118
122
/**
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.
120
125
*
121
- * @param {Number } index Position index of the button. You can have up to 3 buttons using index values of 0 to 2.
122
126
* @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
124
131
*/
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 ) ) ;
130
139
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
-
136
140
this . type = "button" ;
137
141
this . sub_type = sub_type ;
138
- this . index = index . toString ( ) ;
139
142
this . parameters = parameters ;
140
143
}
141
- }
142
144
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 {
150
145
/**
151
- * Builds a url button object for a ButtonComponent
146
+ * Generates the buttons components for a Template message. For internal use only.
152
147
*
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
155
149
*/
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
+ } ) ;
160
154
}
161
155
}
162
156
163
157
/**
164
158
* Button Parameter API object
165
159
*
166
160
* @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
168
163
*/
169
- class PayloadButton {
164
+ class ButtonParameter {
170
165
/**
171
- * Builds a payload button object for a ButtonComponent
166
+ * Builds a button parameter for a ButtonComponent
172
167
*
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'
175
172
*/
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 ;
180
179
}
181
180
}
182
181
@@ -190,7 +189,7 @@ class HeaderComponent {
190
189
/**
191
190
* Builds a header component for a Template message
192
191
*
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
194
193
*/
195
194
constructor ( ...parameters ) {
196
195
this . type = "header" ;
@@ -208,11 +207,11 @@ class BodyComponent {
208
207
/**
209
208
* Builds a body component for a Template message
210
209
*
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
212
211
*/
213
212
constructor ( ...parameters ) {
214
213
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 ) ) ;
216
215
}
217
216
}
218
217
@@ -249,8 +248,7 @@ module.exports = {
249
248
Template,
250
249
Language,
251
250
ButtonComponent,
252
- UrlButton,
253
- PayloadButton,
251
+ ButtonParameter,
254
252
HeaderComponent,
255
253
BodyComponent,
256
254
Parameter,
0 commit comments