@@ -3,9 +3,9 @@ package manager
33import (
44 "encoding/json"
55 "net/http"
6+ "strconv"
67 "strings"
78
8- "github.com/wapikit/wapi.go/internal"
99 "github.com/wapikit/wapi.go/internal/request_client"
1010)
1111
@@ -69,8 +69,8 @@ func NewTemplateManager(config *TemplateManagerConfig) *TemplateManager {
6969
7070// WhatsAppBusinessTemplatesFetchResponseEdge represents the response structure for fetching templates.
7171type WhatsAppBusinessTemplatesFetchResponseEdge struct {
72- Data []WhatsAppBusinessMessageTemplateNode `json:"data,omitempty"`
73- Paging internal. WhatsAppBusinessApiPaginationMeta `json:"paging,omitempty"`
72+ Data []WhatsAppBusinessMessageTemplateNode `json:"data,omitempty"`
73+ Paging PaginationDetails `json:"paging,omitempty"`
7474}
7575
7676// TemplateMessageComponentCard represents a card component in a message template.
@@ -163,61 +163,7 @@ type WhatsAppBusinessHSMWhatsAppHSMComponent struct {
163163type TemplateMessageQualityScore struct {
164164 Date int `json:"date,omitempty"`
165165 Reasons []string `json:"reasons,omitempty"`
166- Score int `json:"score,omitempty"`
167- }
168-
169- // FetchAll fetches all WhatsApp Business message templates.
170- func (manager * TemplateManager ) FetchAll () (* WhatsAppBusinessTemplatesFetchResponseEdge , error ) {
171- apiRequest := manager .requester .NewApiRequest (strings .Join ([]string {manager .businessAccountId , "/" , "message_templates" }, "" ), http .MethodGet )
172-
173- fields := []string {
174- "id" , "category" , "components" , "correct_category" , "cta_url_link_tracking_opted_out" ,
175- "language" , "library_template_name" , "message_send_ttl_seconds" , "name" , "previous_category" ,
176- "quality_score" , "rejected_reason" , "status" , "sub_category" ,
177- }
178-
179- for _ , field := range fields {
180- apiRequest .AddField (request_client.ApiRequestQueryParamField {
181- Name : field ,
182- Filters : map [string ]string {},
183- })
184- }
185-
186- // for now add a default 1000 limit on templates fetch
187- // ! TODO: add proper pagination
188- apiRequest .AddQueryParam ("limit" , "1000" )
189-
190- response , err := apiRequest .Execute ()
191- if err != nil {
192- return nil , err
193- }
194-
195- var responseToReturn WhatsAppBusinessTemplatesFetchResponseEdge
196- json .Unmarshal ([]byte (response ), & responseToReturn )
197- return & responseToReturn , nil
198- }
199-
200- // Fetch fetches a single WhatsApp Business message template by its ID.
201- func (manager * TemplateManager ) Fetch (Id string ) (* WhatsAppBusinessMessageTemplateNode , error ) {
202- apiRequest := manager .requester .NewApiRequest (strings .Join ([]string {Id }, "" ), http .MethodGet )
203- fields := []string {
204- "id" , "category" , "components" , "correct_category" , "cta_url_link_tracking_opted_out" ,
205- "language" , "library_template_name" , "message_send_ttl_seconds" , "name" , "previous_category" ,
206- "quality_score" , "rejected_reason" , "status" , "sub_category" ,
207- }
208- for _ , field := range fields {
209- apiRequest .AddField (request_client.ApiRequestQueryParamField {
210- Name : field ,
211- Filters : map [string ]string {},
212- })
213- }
214- response , err := apiRequest .Execute ()
215- if err != nil {
216- return nil , err
217- }
218- var responseToReturn WhatsAppBusinessMessageTemplateNode
219- json .Unmarshal ([]byte (response ), & responseToReturn )
220- return & responseToReturn , nil
166+ Score string `json:"score,omitempty"`
221167}
222168
223169// WhatsappMessageTemplateButtonCreateRequestBody represents the request body for creating a button.
@@ -337,8 +283,8 @@ type TemplateMessagePreviewNode struct {
337283
338284// TemplateMessagePreviewEdge represents the preview response.
339285type TemplateMessagePreviewEdge struct {
340- Data []TemplateMessagePreviewNode `json:"data,omitempty"`
341- Paging internal. WhatsAppBusinessApiPaginationMeta `json:"paging,omitempty"`
286+ Data []TemplateMessagePreviewNode `json:"data,omitempty"`
287+ Paging PaginationDetails `json:"paging,omitempty"`
342288}
343289
344290// TemplateMigrationResponse represents the migration response.
@@ -360,3 +306,149 @@ func (manager *TemplateManager) MigrateFromOtherBusinessAccount(sourcePageNumber
360306 json .Unmarshal ([]byte (response ), & responseToReturn )
361307 return & responseToReturn , nil
362308}
309+
310+ // FetchAllWithPagination fetches WhatsApp Business message templates with pagination support
311+ func (manager * TemplateManager ) FetchAllWithPagination (paginationInput ... * PaginationInput ) (* PaginatedResponse [WhatsAppBusinessMessageTemplateNode ], error ) {
312+ apiRequest := manager .requester .NewApiRequest (
313+ strings .Join ([]string {manager .businessAccountId , "/" , "message_templates" }, "" ),
314+ http .MethodGet ,
315+ )
316+
317+ fields := []string {
318+ "id" , "category" , "components" , "correct_category" , "cta_url_link_tracking_opted_out" ,
319+ "language" , "library_template_name" , "message_send_ttl_seconds" , "name" , "previous_category" ,
320+ "quality_score" , "rejected_reason" , "status" , "sub_category" ,
321+ }
322+
323+ for _ , field := range fields {
324+ apiRequest .AddField (request_client.ApiRequestQueryParamField {
325+ Name : field ,
326+ Filters : map [string ]string {},
327+ })
328+ }
329+
330+ // Apply pagination parameters
331+ if len (paginationInput ) > 0 && paginationInput [0 ] != nil {
332+ input := paginationInput [0 ]
333+ if input .Limit > 0 {
334+ apiRequest .AddQueryParam ("limit" , strconv .Itoa (input .Limit ))
335+ }
336+ if input .After != "" {
337+ apiRequest .AddQueryParam ("after" , input .After )
338+ }
339+ if input .Before != "" {
340+ apiRequest .AddQueryParam ("before" , input .Before )
341+ }
342+ } else {
343+ // Default limit
344+ apiRequest .AddQueryParam ("limit" , "100" )
345+ }
346+
347+ response , err := apiRequest .Execute ()
348+ if err != nil {
349+ return nil , err
350+ }
351+
352+ var result PaginatedResponse [WhatsAppBusinessMessageTemplateNode ]
353+ if err := json .Unmarshal ([]byte (response ), & result ); err != nil {
354+ return nil , err
355+ }
356+
357+ return & result , nil
358+ }
359+
360+ // Deprecated: Use FetchAllWithPagination for better control
361+ func (manager * TemplateManager ) FetchAll () (* WhatsAppBusinessTemplatesFetchResponseEdge , error ) {
362+ apiRequest := manager .requester .NewApiRequest (
363+ strings .Join ([]string {manager .businessAccountId , "/" , "message_templates" }, "" ),
364+ http .MethodGet ,
365+ )
366+
367+ fields := []string {
368+ "id" , "category" , "components" , "correct_category" , "cta_url_link_tracking_opted_out" ,
369+ "language" , "library_template_name" , "message_send_ttl_seconds" , "name" , "previous_category" ,
370+ "quality_score" , "rejected_reason" , "status" , "sub_category" ,
371+ }
372+
373+ for _ , field := range fields {
374+ apiRequest .AddField (request_client.ApiRequestQueryParamField {
375+ Name : field ,
376+ Filters : map [string ]string {},
377+ })
378+ }
379+
380+ // High limit for backwards compatibility
381+ apiRequest .AddQueryParam ("limit" , "1000" )
382+
383+ response , err := apiRequest .Execute ()
384+ if err != nil {
385+ return nil , err
386+ }
387+
388+ var responseToReturn WhatsAppBusinessTemplatesFetchResponseEdge
389+ if err := json .Unmarshal ([]byte (response ), & responseToReturn ); err != nil {
390+ return nil , err
391+ }
392+
393+ return & responseToReturn , nil
394+ }
395+
396+ // GetAllTemplates fetches all templates across all pages
397+ // This is a helper method that handles pagination automatically
398+ func (manager * TemplateManager ) GetAllTemplates (limit ... int ) ([]WhatsAppBusinessMessageTemplateNode , error ) {
399+ pageLimit := 100
400+ if len (limit ) > 0 && limit [0 ] > 0 {
401+ pageLimit = limit [0 ]
402+ }
403+
404+ var allTemplates []WhatsAppBusinessMessageTemplateNode
405+ var nextCursor string
406+
407+ for {
408+ input := & PaginationInput {
409+ Limit : pageLimit ,
410+ After : nextCursor ,
411+ }
412+
413+ result , err := manager .FetchAllWithPagination (input )
414+ if err != nil {
415+ return nil , err
416+ }
417+
418+ allTemplates = append (allTemplates , result .Data ... )
419+
420+ // Check if there's a next page
421+ if ! result .Paging .HasNextPage () {
422+ break
423+ }
424+
425+ nextCursor = result .Paging .GetNextCursor ()
426+ }
427+
428+ return allTemplates , nil
429+ }
430+
431+ // Fetch fetches a single WhatsApp Business message template by its ID (no changes needed)
432+ func (manager * TemplateManager ) Fetch (Id string ) (* WhatsAppBusinessMessageTemplateNode , error ) {
433+ apiRequest := manager .requester .NewApiRequest (strings .Join ([]string {Id }, "" ), http .MethodGet )
434+ fields := []string {
435+ "id" , "category" , "components" , "correct_category" , "cta_url_link_tracking_opted_out" ,
436+ "language" , "library_template_name" , "message_send_ttl_seconds" , "name" , "previous_category" ,
437+ "quality_score" , "rejected_reason" , "status" , "sub_category" ,
438+ }
439+ for _ , field := range fields {
440+ apiRequest .AddField (request_client.ApiRequestQueryParamField {
441+ Name : field ,
442+ Filters : map [string ]string {},
443+ })
444+ }
445+ response , err := apiRequest .Execute ()
446+ if err != nil {
447+ return nil , err
448+ }
449+ var responseToReturn WhatsAppBusinessMessageTemplateNode
450+ if err := json .Unmarshal ([]byte (response ), & responseToReturn ); err != nil {
451+ return nil , err
452+ }
453+ return & responseToReturn , nil
454+ }
0 commit comments