From 1a28bdb950c68fa8d1a83df13364eaa43cf95ddf Mon Sep 17 00:00:00 2001 From: Aldino Kemal Date: Fri, 11 Feb 2022 10:45:08 +0700 Subject: [PATCH] feat: add send document API --- config/settings.go | 2 +- controllers/send_controller.go | 25 +++++++ services/send_service.go | 1 + services/send_service_impl.go | 74 ++++++++++++++++++- .../{sendimages => senditems}/.gitignore | 0 structs/send_struct.go | 9 +++ validations/send_validation.go | 23 ++++++ 7 files changed, 131 insertions(+), 3 deletions(-) rename statics/images/{sendimages => senditems}/.gitignore (100%) diff --git a/config/settings.go b/config/settings.go index 9395424..7bcc1a8 100644 --- a/config/settings.go +++ b/config/settings.go @@ -1,5 +1,5 @@ package config const PathQrCode = "statics/images/qrcode" -const PathSendImage = "statics/images/sendimages" +const PathSendItems = "statics/images/senditems" const DBName = "hydrogenWaCli.db" diff --git a/controllers/send_controller.go b/controllers/send_controller.go index 5ebb858..69a84ec 100644 --- a/controllers/send_controller.go +++ b/controllers/send_controller.go @@ -19,6 +19,7 @@ func NewSendController(service services.SendService) SendController { 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) } func (controller *SendController) SendText(c *fiber.Ctx) error { @@ -63,3 +64,27 @@ func (controller *SendController) SendImage(c *fiber.Ctx) error { Results: response, }) } + +func (controller *SendController) SendFile(c *fiber.Ctx) error { + var request structs.SendFileRequest + err := c.BodyParser(&request) + utils.PanicIfNeeded(err) + + file, err := c.FormFile("file") + utils.PanicIfNeeded(err) + + request.File = file + + //add validation send image + validations.ValidateSendFile(request) + + request.PhoneNumber = request.PhoneNumber + "@s.whatsapp.net" + response, err := controller.Service.SendFile(c, request) + utils.PanicIfNeeded(err) + + return c.JSON(utils.ResponseData{ + Code: 200, + Message: "Success", + Results: response, + }) +} diff --git a/services/send_service.go b/services/send_service.go index 572a952..e3c4b5d 100644 --- a/services/send_service.go +++ b/services/send_service.go @@ -8,4 +8,5 @@ import ( 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) } diff --git a/services/send_service_impl.go b/services/send_service_impl.go index 0bcfd97..94b3260 100644 --- a/services/send_service_impl.go +++ b/services/send_service_impl.go @@ -53,7 +53,7 @@ func (service SendServiceImpl) SendImage(c *fiber.Ctx, request structs.SendImage } // Resize image - oriImagePath := fmt.Sprintf("%s/%s", config.PathSendImage, request.Image.Filename) + oriImagePath := fmt.Sprintf("%s/%s", config.PathSendItems, request.Image.Filename) err = c.SaveFile(request.Image, oriImagePath) if err != nil { return response, err @@ -64,7 +64,7 @@ func (service SendServiceImpl) SendImage(c *fiber.Ctx, request structs.SendImage return response, err } - newImagePath := fmt.Sprintf("%s/new-%s", config.PathSendImage, request.Image.Filename) + newImagePath := fmt.Sprintf("%s/new-%s", config.PathSendItems, request.Image.Filename) err = bimg.Write(newImagePath, newImage) if err != nil { return response, err @@ -117,3 +117,73 @@ func (service SendServiceImpl) SendImage(c *fiber.Ctx, request structs.SendImage return response, nil } } + +func (service SendServiceImpl) SendFile(c *fiber.Ctx, request structs.SendFileRequest) (response structs.SendFileResponse, err error) { + if !service.WaCli.IsLoggedIn() { + err = errors.New("you are not loggin") + return + } + + // Resize image + oriFilePath := fmt.Sprintf("%s/%s", config.PathSendItems, request.File.Filename) + err = c.SaveFile(request.File, oriFilePath) + if err != nil { + return response, err + } + + removeFile := func(paths ...string) { + time.Sleep(5 * time.Second) + for _, path := range paths { + err := os.Remove(path) + if err != nil { + fmt.Println("error when delete " + path) + } + } + + } + + // Send to WA server + dataWaRecipient, ok := utils.ParseJID(request.PhoneNumber) + if !ok { + return response, errors.New("invalid JID " + request.PhoneNumber) + } + dataWaFile, err := os.ReadFile(oriFilePath) + 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{DocumentMessage: &waProto.DocumentMessage{ + Url: proto.String(uploadedFile.URL), + Mimetype: proto.String(http.DetectContentType(dataWaFile)), + Title: proto.String(request.File.Filename), + FileSha256: uploadedFile.FileSHA256, + FileLength: proto.Uint64(uploadedFile.FileLength), + PageCount: nil, + MediaKey: uploadedFile.MediaKey, + FileName: proto.String(request.File.Filename), + FileEncSha256: uploadedFile.FileEncSHA256, + DirectPath: proto.String(uploadedFile.DirectPath), + MediaKeyTimestamp: nil, + ContactVcard: nil, + ThumbnailDirectPath: nil, + ThumbnailSha256: nil, + ThumbnailEncSha256: nil, + JpegThumbnail: nil, + ContextInfo: nil, + ThumbnailHeight: nil, + ThumbnailWidth: nil, + }} + ts, err := service.WaCli.SendMessage(dataWaRecipient, "", msg) + go removeFile(oriFilePath) + if err != nil { + return response, err + } else { + response.Status = fmt.Sprintf("File message sent (server timestamp: %s)", ts) + return response, nil + } +} diff --git a/statics/images/sendimages/.gitignore b/statics/images/senditems/.gitignore similarity index 100% rename from statics/images/sendimages/.gitignore rename to statics/images/senditems/.gitignore diff --git a/structs/send_struct.go b/structs/send_struct.go index f7a2df3..a8239c4 100644 --- a/structs/send_struct.go +++ b/structs/send_struct.go @@ -63,4 +63,13 @@ type SendImageResponse struct { Status string `json:"status"` } +type SendFileRequest struct { + PhoneNumber string `json:"phone_number" form:"phone_number"` + File *multipart.FileHeader `json:"file" form:"file"` +} + +type SendFileResponse struct { + Status string `json:"status"` +} + // ============================== END SEND ============================== diff --git a/validations/send_validation.go b/validations/send_validation.go index 807c19a..1fa6d04 100644 --- a/validations/send_validation.go +++ b/validations/send_validation.go @@ -55,3 +55,26 @@ func ValidateSendImage(request structs.SendImageRequest) { } } + +func ValidateSendFile(request structs.SendFileRequest) { + err := validation.ValidateStruct(&request, + validation.Field(&request.PhoneNumber, validation.Required, is.E164, validation.Length(10, 15)), + validation.Field(&request.File, validation.Required), + ) + + if err != nil { + panic(utils.ValidationError{ + Message: err.Error(), + }) + } else if !strings.HasPrefix(request.PhoneNumber, "62") { + panic(utils.ValidationError{ + Message: "this is only work for indonesia country (start with 62)", + }) + } + + if request.File.Size > 10240000 { // 10MB + panic(utils.ValidationError{ + Message: "max file upload is 10MB, please upload in cloud and send via text if your file is higher than 10MB", + }) + } +}