From f30a496ba83d10a58d1e77aa30b487b55a6b858c Mon Sep 17 00:00:00 2001 From: Aldino Kemal Date: Tue, 17 May 2022 11:51:25 +0700 Subject: [PATCH] feat: add send rest --- readme.md | 2 +- src/config/settings.go | 6 ++-- src/controllers/send_controller.go | 33 ++++++++++++++++- src/go.mod | 1 + src/go.sum | 2 ++ src/services/send_service.go | 1 + src/services/send_service_impl.go | 58 +++++++++++++++++++++++++++--- src/structs/send_struct.go | 11 ++++++ src/validations/send_validation.go | 29 +++++++++++++-- 9 files changed, 132 insertions(+), 11 deletions(-) diff --git a/readme.md b/readme.md index 265b160..4deb3f3 100644 --- a/readme.md +++ b/readme.md @@ -55,7 +55,7 @@ 7. open `http://localhost:3000` in browser ### Production Mode (docker) -- `docker run --publish 3000:3000 --restart=always aldinokemal2104/go-whatsapp-web-multidevice` +- `docker run --publish=3000:3000 --restart=always --detach aldinokemal2104/go-whatsapp-web-multidevice --autoreply="Dont't reply this message please"` ### Production Mode (binary) - download binary from [release](https://github.com/aldinokemal/go-whatsapp-web-multidevice/releases) diff --git a/src/config/settings.go b/src/config/settings.go index 34dacbe..4a5a95f 100644 --- a/src/config/settings.go +++ b/src/config/settings.go @@ -11,6 +11,8 @@ var ( DBName string = "hydrogenWaCli.db" - WhatsappLogLevel string = "ERROR" - WhatsappAutoReplyMessage string + WhatsappLogLevel string = "ERROR" + WhatsappAutoReplyMessage string + WhatsappSettingMaxFileSize int64 = 10240000 // 10MB + WhatsappSettingMaxVideoSize int64 = 30000000 // 30MB ) diff --git a/src/controllers/send_controller.go b/src/controllers/send_controller.go index 6e1aab6..3820c59 100644 --- a/src/controllers/send_controller.go +++ b/src/controllers/send_controller.go @@ -20,6 +20,7 @@ func (controller *SendController) Route(app *fiber.App) { app.Post("/send/message", controller.SendText) app.Post("/send/image", controller.SendImage) app.Post("/send/file", controller.SendFile) + app.Post("/send/video", controller.SendVideo) } func (controller *SendController) SendText(c *fiber.Ctx) error { @@ -93,7 +94,7 @@ func (controller *SendController) SendFile(c *fiber.Ctx) error { } else { request.Phone = request.Phone + "@s.whatsapp.net" } - + response, err := controller.Service.SendFile(c, request) utils.PanicIfNeeded(err) @@ -103,3 +104,33 @@ func (controller *SendController) SendFile(c *fiber.Ctx) error { Results: response, }) } + +func (controller *SendController) SendVideo(c *fiber.Ctx) error { + var request structs.SendVideoRequest + err := c.BodyParser(&request) + utils.PanicIfNeeded(err) + + video, err := c.FormFile("video") + utils.PanicIfNeeded(err) + + request.Video = video + + //add validation send image + validations.ValidateSendVideo(request) + + if request.Type == structs.TypeGroup { + request.Phone = request.Phone + "@g.us" + } else { + request.Phone = request.Phone + "@s.whatsapp.net" + } + + response, err := controller.Service.SendVideo(c, request) + utils.PanicIfNeeded(err) + + return c.JSON(utils.ResponseData{ + Code: 200, + Message: response.Status, + Results: response, + }) +} + diff --git a/src/go.mod b/src/go.mod index 97a1275..1719565 100644 --- a/src/go.mod +++ b/src/go.mod @@ -3,6 +3,7 @@ module github.com/aldinokemal/go-whatsapp-web-multidevice go 1.17 require ( + github.com/dustin/go-humanize v1.0.0 github.com/go-ozzo/ozzo-validation/v4 v4.3.0 github.com/gofiber/fiber/v2 v2.26.0 github.com/gofiber/template v1.6.22 diff --git a/src/go.sum b/src/go.sum index c4b018b..bd56f99 100644 --- a/src/go.sum +++ b/src/go.sum @@ -106,6 +106,8 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= diff --git a/src/services/send_service.go b/src/services/send_service.go index e3c4b5d..0ad41dc 100644 --- a/src/services/send_service.go +++ b/src/services/send_service.go @@ -9,4 +9,5 @@ type SendService interface { SendText(c *fiber.Ctx, request structs.SendMessageRequest) (response structs.SendMessageResponse, err error) SendImage(c *fiber.Ctx, request structs.SendImageRequest) (response structs.SendImageResponse, err error) SendFile(c *fiber.Ctx, request structs.SendFileRequest) (response structs.SendFileResponse, err error) + SendVideo(c *fiber.Ctx, request structs.SendVideoRequest) (response structs.SendVideoResponse, err error) } diff --git a/src/services/send_service_impl.go b/src/services/send_service_impl.go index e9a9a01..fdd9902 100644 --- a/src/services/send_service_impl.go +++ b/src/services/send_service_impl.go @@ -46,12 +46,13 @@ func (service SendServiceImpl) SendText(_ *fiber.Ctx, request structs.SendMessag func (service SendServiceImpl) SendImage(c *fiber.Ctx, request structs.SendImageRequest) (response structs.SendImageResponse, err error) { utils.MustLogin(service.WaCli) - // Resize image + // Save image to server oriImagePath := fmt.Sprintf("%s/%s", config.PathSendItems, request.Image.Filename) err = c.SaveFile(request.Image, oriImagePath) if err != nil { return response, err } + // Resize image openImageBuffer, err := bimg.Read(oriImagePath) newImage, err := bimg.NewImage(openImageBuffer).Process(bimg.Options{Quality: 90, Width: 600, Height: 600, Embed: true}) if err != nil { @@ -63,7 +64,7 @@ func (service SendServiceImpl) SendImage(c *fiber.Ctx, request structs.SendImage if err != nil { return response, err } - + // Send to WA server dataWaCaption := request.Caption dataWaRecipient, ok := utils.ParseJID(request.Phone) @@ -110,7 +111,6 @@ func (service SendServiceImpl) SendImage(c *fiber.Ctx, request structs.SendImage func (service SendServiceImpl) SendFile(c *fiber.Ctx, request structs.SendFileRequest) (response structs.SendFileResponse, err error) { utils.MustLogin(service.WaCli) - // Resize image oriFilePath := fmt.Sprintf("%s/%s", config.PathSendItems, request.File.Filename) err = c.SaveFile(request.File, oriFilePath) if err != nil { @@ -153,7 +153,57 @@ func (service SendServiceImpl) SendFile(c *fiber.Ctx, request structs.SendFileRe if err != nil { return response, err } else { - response.Status = fmt.Sprintf("Message sent to %s (server timestamp: %s)", request.Phone, ts) + response.Status = fmt.Sprintf("Document sent to %s (server timestamp: %s)", request.Phone, ts) + return response, nil + } +} + +func (service SendServiceImpl) SendVideo(c *fiber.Ctx, request structs.SendVideoRequest) (response structs.SendVideoResponse, err error) { + utils.MustLogin(service.WaCli) + + // Save image to server + oriVideoPath := fmt.Sprintf("%s/%s", config.PathSendItems, request.Video.Filename) + err = c.SaveFile(request.Video, oriVideoPath) + if err != nil { + return response, err + } + + // Send to WA server + dataWaRecipient, ok := utils.ParseJID(request.Phone) + if !ok { + return response, errors.New("invalid JID " + request.Phone) + } + dataWaFile, err := os.ReadFile(oriVideoPath) + if err != nil { + return response, err + } + uploadedFile, err := service.WaCli.Upload(context.Background(), dataWaFile, whatsmeow.MediaDocument) + if err != nil { + fmt.Printf("Failed to upload file: %v", err) + return response, err + } + + msg := &waProto.Message{VideoMessage: &waProto.VideoMessage{ + Url: proto.String(uploadedFile.URL), + Mimetype: proto.String(http.DetectContentType(dataWaFile)), + Caption: proto.String(request.Caption), + FileLength: proto.Uint64(uploadedFile.FileLength), + FileSha256: uploadedFile.FileSHA256, + FileEncSha256: uploadedFile.FileEncSHA256, + MediaKey: uploadedFile.MediaKey, + DirectPath: proto.String(uploadedFile.DirectPath), + }} + ts, err := service.WaCli.SendMessage(dataWaRecipient, "", msg) + go func() { + errDelete := utils.RemoveFile(0, oriVideoPath) + if errDelete != nil { + fmt.Println(errDelete) + } + }() + if err != nil { + return response, err + } else { + response.Status = fmt.Sprintf("Video sent to %s (server timestamp: %s)", request.Phone, ts) return response, nil } } diff --git a/src/structs/send_struct.go b/src/structs/send_struct.go index 631a95e..b57b11b 100644 --- a/src/structs/send_struct.go +++ b/src/structs/send_struct.go @@ -40,3 +40,14 @@ type SendFileRequest struct { type SendFileResponse struct { Status string `json:"status"` } + +type SendVideoRequest struct { + Phone string `json:"phone" form:"phone"` + Caption string `json:"caption" form:"caption"` + Video *multipart.FileHeader `json:"video" form:"video"` + Type SendType `json:"type" form:"message"` +} + +type SendVideoResponse struct { + Status string `json:"status"` +} diff --git a/src/validations/send_validation.go b/src/validations/send_validation.go index 11c73a1..b0d09df 100644 --- a/src/validations/send_validation.go +++ b/src/validations/send_validation.go @@ -1,8 +1,11 @@ package validations import ( + "fmt" + "github.com/aldinokemal/go-whatsapp-web-multidevice/config" "github.com/aldinokemal/go-whatsapp-web-multidevice/structs" "github.com/aldinokemal/go-whatsapp-web-multidevice/utils" + "github.com/dustin/go-humanize" validation "github.com/go-ozzo/ozzo-validation/v4" "github.com/go-ozzo/ozzo-validation/v4/is" ) @@ -44,7 +47,6 @@ func ValidateSendImage(request structs.SendImageRequest) { Message: "your image is not allowed. please use jpg/jpeg/png", }) } - } func ValidateSendFile(request structs.SendFileRequest) { @@ -59,9 +61,30 @@ func ValidateSendFile(request structs.SendFileRequest) { }) } - if request.File.Size > 10240000 { // 10MB + if request.File.Size > config.WhatsappSettingMaxFileSize { // 10MB + maxSizeString := humanize.Bytes(uint64(config.WhatsappSettingMaxFileSize)) + panic(utils.ValidationError{ + Message: fmt.Sprintf("max file upload is %s, please upload in cloud and send via text if your file is higher than %s", maxSizeString, maxSizeString), + }) + } +} + +func ValidateSendVideo(request structs.SendVideoRequest) { + err := validation.ValidateStruct(&request, + validation.Field(&request.Phone, validation.Required, is.Digit, validation.Length(10, 25)), + validation.Field(&request.Video, validation.Required), + ) + + if err != nil { + panic(utils.ValidationError{ + Message: err.Error(), + }) + } + + if request.Video.Size > config.WhatsappSettingMaxVideoSize { // 30MB + maxSizeString := humanize.Bytes(uint64(config.WhatsappSettingMaxVideoSize)) panic(utils.ValidationError{ - Message: "max file upload is 10MB, please upload in cloud and send via text if your file is higher than 10MB", + Message: fmt.Sprintf("max video upload is %s, please upload in cloud and send via text if your file is higher than %s", maxSizeString, maxSizeString), }) } }