diff --git a/src/pkg/utils/general.go b/src/pkg/utils/general.go index 99faff9..23b22cc 100644 --- a/src/pkg/utils/general.go +++ b/src/pkg/utils/general.go @@ -1,7 +1,12 @@ package utils import ( + "bytes" "fmt" + "image" + _ "image/gif" // Register GIF format + _ "image/jpeg" // Register JPEG format + _ "image/png" // Register PNG format "io" "log" "net/http" @@ -100,22 +105,6 @@ func GetMetaDataFromURL(url string) (meta Metadata, err error) { meta.Image, _ = element.Attr("content") }) - document.Find("meta[property='og:image:width']").Each(func(index int, element *goquery.Selection) { - if content, exists := element.Attr("content"); exists { - width, _ := strconv.Atoi(content) - widthUint32 := uint32(width) - meta.Width = &widthUint32 - } - }) - - document.Find("meta[property='og:image:height']").Each(func(index int, element *goquery.Selection) { - if content, exists := element.Attr("content"); exists { - height, _ := strconv.Atoi(content) - heightUint32 := uint32(height) - meta.Height = &heightUint32 - } - }) - // If an og:image is found, download it and store its content in ImageThumb if meta.Image != "" { imageResponse, err := http.Get(meta.Image) @@ -123,11 +112,59 @@ func GetMetaDataFromURL(url string) (meta Metadata, err error) { log.Printf("Failed to download image: %v", err) } else { defer imageResponse.Body.Close() + + // Read image data imageData, err := io.ReadAll(imageResponse.Body) if err != nil { log.Printf("Failed to read image data: %v", err) } else { meta.ImageThumb = imageData + + // Get image dimensions from the actual image rather than OG tags + imageReader := bytes.NewReader(imageData) + img, _, err := image.Decode(imageReader) + if err == nil { + bounds := img.Bounds() + width := uint32(bounds.Max.X - bounds.Min.X) + height := uint32(bounds.Max.Y - bounds.Min.Y) + + // Check if image is square (1:1 ratio) + if width == height { + // For 1:1 ratio, leave width and height as nil + meta.Width = nil + meta.Height = nil + } else { + meta.Width = &width + meta.Height = &height + } + + log.Printf("Image dimensions: %dx%d", width, height) + } else { + log.Printf("Failed to decode image to get dimensions: %v", err) + + // Fallback to OG tags if image decoding fails + document.Find("meta[property='og:image:width']").Each(func(index int, element *goquery.Selection) { + if content, exists := element.Attr("content"); exists { + width, _ := strconv.Atoi(content) + widthUint32 := uint32(width) + meta.Width = &widthUint32 + } + }) + + document.Find("meta[property='og:image:height']").Each(func(index int, element *goquery.Selection) { + if content, exists := element.Attr("content"); exists { + height, _ := strconv.Atoi(content) + heightUint32 := uint32(height) + meta.Height = &heightUint32 + } + }) + + // Check if the OG tags indicate a 1:1 ratio + if meta.Width != nil && meta.Height != nil && *meta.Width == *meta.Height { + meta.Width = nil + meta.Height = nil + } + } } } } diff --git a/src/services/send.go b/src/services/send.go index 9a9afa2..c16cc1f 100644 --- a/src/services/send.go +++ b/src/services/send.go @@ -435,16 +435,38 @@ func (service serviceSend) SendLink(ctx context.Context, request domainSend.Link return response, err } + // Log image dimensions if available, otherwise note it's a square image or dimensions not available + if getMetaDataFromURL.Width != nil && getMetaDataFromURL.Height != nil { + fmt.Printf("Image dimensions: %dx%d\n", *getMetaDataFromURL.Width, *getMetaDataFromURL.Height) + } else { + fmt.Println("Image dimensions: Square image or dimensions not available") + } + + // Create the message msg := &waE2E.Message{ExtendedTextMessage: &waE2E.ExtendedTextMessage{ - Text: proto.String(fmt.Sprintf("%s\n%s", request.Caption, request.Link)), - Title: proto.String(getMetaDataFromURL.Title), - MatchedText: proto.String(request.Link), - Description: proto.String(getMetaDataFromURL.Description), - JPEGThumbnail: getMetaDataFromURL.ImageThumb, - ThumbnailHeight: getMetaDataFromURL.Height, - ThumbnailWidth: getMetaDataFromURL.Width, + Text: proto.String(fmt.Sprintf("%s\n%s", request.Caption, request.Link)), + Title: proto.String(getMetaDataFromURL.Title), + MatchedText: proto.String(request.Link), + Description: proto.String(getMetaDataFromURL.Description), + JPEGThumbnail: getMetaDataFromURL.ImageThumb, }} + // If we have a thumbnail image, upload it to WhatsApp's servers + if len(getMetaDataFromURL.ImageThumb) > 0 && getMetaDataFromURL.Height != nil && getMetaDataFromURL.Width != nil { + uploadedThumb, err := service.uploadMedia(ctx, whatsmeow.MediaImage, getMetaDataFromURL.ImageThumb, dataWaRecipient) + if err == nil { + // Update the message with the uploaded thumbnail information + msg.ExtendedTextMessage.ThumbnailDirectPath = proto.String(uploadedThumb.DirectPath) + msg.ExtendedTextMessage.ThumbnailSHA256 = uploadedThumb.FileSHA256 + msg.ExtendedTextMessage.ThumbnailEncSHA256 = uploadedThumb.FileEncSHA256 + msg.ExtendedTextMessage.MediaKey = uploadedThumb.MediaKey + msg.ExtendedTextMessage.ThumbnailHeight = getMetaDataFromURL.Height + msg.ExtendedTextMessage.ThumbnailWidth = getMetaDataFromURL.Width + } else { + logrus.Warnf("Failed to upload thumbnail: %v, continue without uploaded thumbnail", err) + } + } + content := "🔗 " + request.Link if request.Caption != "" { content = "🔗 " + request.Caption