Help me with a function

Good afternoon, I have the following function:

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) // Slice para almacenar los botones

	for _, quickReplyCarousel := range msg.QuickReplies() {
		// Verificamos si quickReply es una URL o texto
		if strings.HasPrefix(quickReplyCarousel, "http") {
			buttons = append(buttons, map[string]interface{}{
				"text":         "Open URL",
				"type":         "web_url",
				"postbackData": "myCustomPostbackData",
				"data":         quickReplyCarousel,
			})
		}
	}

	if len(buttons) > 0 {
		carouselItem["buttons"] = buttons // Agregamos los botones al elemento del carrusel si hay alguno
	}

	carouselContent = append(carouselContent, carouselItem)
}

return carouselContent

}

image

As seen in the image, it appears 2 times in the text “Open URL” and I only want it to appear once.

Could you help me or have any suggestions?

Hi @Ivan_Garcia,

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.

Hello Cristophberger, thanks for your help.

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.

I hope you have made me understand jejejeje

Regards.

So is my quick “analysis” of the code correct?

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.

Does this make sense?

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.

Thank you very much for your help, what I will do is eliminate everything repeated from the arrangement to see if it works for me.

I’ll tell evr how it went.

Greetings.

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()?

That’s right, you understood it perfectly, I’ll try your solution and I’ll share with you how it turned out, I really appreciate your help.

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.

thank you so much.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.