I am not sure if I understand what the code does. It would seem that buttons accumulates all the buttons from every quickReplyCarousel. So for each element in msg.QuickReplies(), one button gets added to buttons.
After the loop, the complete buttons map with all buttons in it is assigned to the map carouselItem with the key "buttons".
If msg.QuickReplies() contains two elements with prefix “http”, buttons will contain two buttons named “Open URL”.
Maybe it’s more of a data problem than a code problem.
This code is used for RCS messages and particularly I am implementing it in an image carousel with one link per image, as I show in the screenshot, it is printing 2 links.
If so, the solution might be to check what msg.QuickReplies() actually contains. If it contains two elements with prefix http, then obviously, the data delivered to your function already contains this duplicate.
To elaborate further, after finding the first quick reply with prefix http, the for loop could break to avoid collecting further strings with the same prefix.
This would not fix the duplicate data, but at least prevent the duplicate from appearing in the UI.
If msg.QuickReplies() contains more than one instance with “http” prefix, then there will be more than one button in return. Imho it needs the update of the filter, which creates buttons. Or add specific element of the buttons:
if len(buttons) > 0 {
carouselItem["buttons"] = buttons[0]
}
Hi @lemarkar Thank you for your comments, it helped me a lot, the issue of duplicity has now been resolved.
A new problem arose, when printing the buttons, the same link appears for all the buttons when different links are configured, hehehe is left with only the first link and repeats it in the “n” buttons.
I share my function with you, I thank you in advance for your help.
func generateCarouselContent(attachments []string, msg courier.Msg) []map[string]interface{} {
carouselContent := make([]map[string]interface{}, 0)
for _, attachment := range attachments {
_, mediaURL := handlers.SplitAttachment(attachment)
carouselItem := map[string]interface{}{
"text": msg.Text(),
"image": mediaURL,
}
buttons := make([]map[string]interface{}, 0) // Almacenar los botones únicos
// Verificar si se ha encontrado al menos una quickReply que sea una URL
foundURLQuickReply := false
quickReplyIndex := 0
for foundURLQuickReply == false && quickReplyIndex < len(msg.QuickReplies()) {
quickReplyCarousel := msg.QuickReplies()[quickReplyIndex]
// Verificar si quickReply es una URL o texto
if strings.HasPrefix(quickReplyCarousel, "http") {
// Agregar botón solo si es una URL y aún no se ha encontrado ninguna
foundURLQuickReply = true
buttons = append(buttons, map[string]interface{}{
"text": "Open",
"type": "web_url",
"postbackData": "myCustomPostbackData",
"data": quickReplyCarousel,
})
}
quickReplyIndex++
}
if len(buttons) > 0 {
carouselItem["buttons"] = buttons
}
carouselContent = append(carouselContent, carouselItem)
}
return carouselContent
}
If I got your code right, then the problem is in quickReplyIndex. You define it on every attachment iteration and it becomes 0. I assume, you should try it outside the outer loop at the start of the function:
quickReplyIndex := 0
for _, attachment := range attachments {
// Your code here...
}
But this creates a confusion and possible panic situation. What if attachments are still there, but your quickReplyIndex is out of range. Do I understand it right, that amount of attachments equals the amount of strings with “http” prefix in msg.QuickReplies()?
I have implemented the change and it works correctly!!! Thank you very much for your help, in fact it was that, quickReplyIndex := 0 must have been outside the loop, since it always initialized it to 0 in each loop.