+
+// whatsappImageMessage uploads stored pixels and uses the upload keys only in
+// the outgoing message. The text is the caption, not a separate message.
+func whatsappImageMessage(ctx context.Context, client WhatsAppClient, data []byte, text string) (*waE2E.Message, error) {
+ ctx, cancel := context.WithTimeout(ctx, whatsappImageUploadTimeout)
+ defer cancel()
+
+ upload, err := client.Upload(ctx, data, whatsmeow.MediaImage)
+ if err != nil {
+ return nil, fmt.Errorf("upload image: %w", whatsappImageSendError(err))
+ }
+
+ return &waE2E.Message{ImageMessage: &waE2E.ImageMessage{
+ Caption: new(text),
+ Mimetype: new(http.DetectContentType(data)),
+ URL: &upload.URL,
+ DirectPath: &upload.DirectPath,
+ MediaKey: upload.MediaKey,
+ FileEncSHA256: upload.FileEncSHA256,
+ FileSHA256: upload.FileSHA256,
+ FileLength: &upload.FileLength,
+ }}, nil
+}
+
+// whatsappImageSendError drops arbitrary upload and send errors, which can hold
+// media URLs and keys. Cancellation and deadline causes are safe to keep.
+func whatsappImageSendError(err error) error {
+ switch {
+ case errors.Is(err, context.Canceled):
+ return context.Canceled
+ case errors.Is(err, context.DeadlineExceeded):
+ return context.DeadlineExceeded
+ default:
+ return errors.New("media send failed")
+ }
+}