X-Git-Url: https://git.giacomolli.uk/onechat/blobdiff_plain/0da50dc187c8b4aa23ac1ddd0418c0da779389d9..195c3fbb075383ac47bba310eb701b02774e8d10:/whatsapp_image.go diff --git a/whatsapp_image.go b/whatsapp_image.go index 4277b0a..5ce13a8 100644 --- a/whatsapp_image.go +++ b/whatsapp_image.go @@ -4,14 +4,15 @@ import ( "context" "errors" "fmt" + "net/http" "time" "go.mau.fi/whatsmeow" "go.mau.fi/whatsmeow/proto/waE2E" ) -// whatsappImageTime is the longest time of an image download. -const whatsappImageTime = 2 * time.Minute +// whatsappImageUploadTimeout limits one image upload to WhatsApp. +const whatsappImageUploadTimeout = 2 * time.Minute // whatsappImage downloads only supported images and stores them before the // event can be acknowledged. Both the declared size and the downloaded bytes @@ -63,3 +64,39 @@ func whatsappImageDownloadError(err error) error { return errors.New("media download failed") } + +// 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") + } +}