Browse Source

feat: add send rest

pull/15/head
Aldino Kemal 4 years ago
parent
commit
f30a496ba8
  1. 2
      readme.md
  2. 6
      src/config/settings.go
  3. 33
      src/controllers/send_controller.go
  4. 1
      src/go.mod
  5. 2
      src/go.sum
  6. 1
      src/services/send_service.go
  7. 58
      src/services/send_service_impl.go
  8. 11
      src/structs/send_struct.go
  9. 29
      src/validations/send_validation.go

2
readme.md

@ -55,7 +55,7 @@
7. open `http://localhost:3000` in browser 7. open `http://localhost:3000` in browser
### Production Mode (docker) ### 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) ### Production Mode (binary)
- download binary from [release](https://github.com/aldinokemal/go-whatsapp-web-multidevice/releases) - download binary from [release](https://github.com/aldinokemal/go-whatsapp-web-multidevice/releases)

6
src/config/settings.go

@ -11,6 +11,8 @@ var (
DBName string = "hydrogenWaCli.db" DBName string = "hydrogenWaCli.db"
WhatsappLogLevel string = "ERROR"
WhatsappAutoReplyMessage string
WhatsappLogLevel string = "ERROR"
WhatsappAutoReplyMessage string
WhatsappSettingMaxFileSize int64 = 10240000 // 10MB
WhatsappSettingMaxVideoSize int64 = 30000000 // 30MB
) )

33
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/message", controller.SendText)
app.Post("/send/image", controller.SendImage) app.Post("/send/image", controller.SendImage)
app.Post("/send/file", controller.SendFile) app.Post("/send/file", controller.SendFile)
app.Post("/send/video", controller.SendVideo)
} }
func (controller *SendController) SendText(c *fiber.Ctx) error { func (controller *SendController) SendText(c *fiber.Ctx) error {
@ -93,7 +94,7 @@ func (controller *SendController) SendFile(c *fiber.Ctx) error {
} else { } else {
request.Phone = request.Phone + "@s.whatsapp.net" request.Phone = request.Phone + "@s.whatsapp.net"
} }
response, err := controller.Service.SendFile(c, request) response, err := controller.Service.SendFile(c, request)
utils.PanicIfNeeded(err) utils.PanicIfNeeded(err)
@ -103,3 +104,33 @@ func (controller *SendController) SendFile(c *fiber.Ctx) error {
Results: response, 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,
})
}

1
src/go.mod

@ -3,6 +3,7 @@ module github.com/aldinokemal/go-whatsapp-web-multidevice
go 1.17 go 1.17
require ( require (
github.com/dustin/go-humanize v1.0.0
github.com/go-ozzo/ozzo-validation/v4 v4.3.0 github.com/go-ozzo/ozzo-validation/v4 v4.3.0
github.com/gofiber/fiber/v2 v2.26.0 github.com/gofiber/fiber/v2 v2.26.0
github.com/gofiber/template v1.6.22 github.com/gofiber/template v1.6.22

2
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.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 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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/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.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= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=

1
src/services/send_service.go

@ -9,4 +9,5 @@ type SendService interface {
SendText(c *fiber.Ctx, request structs.SendMessageRequest) (response structs.SendMessageResponse, err error) SendText(c *fiber.Ctx, request structs.SendMessageRequest) (response structs.SendMessageResponse, err error)
SendImage(c *fiber.Ctx, request structs.SendImageRequest) (response structs.SendImageResponse, 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) SendFile(c *fiber.Ctx, request structs.SendFileRequest) (response structs.SendFileResponse, err error)
SendVideo(c *fiber.Ctx, request structs.SendVideoRequest) (response structs.SendVideoResponse, err error)
} }

58
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) { func (service SendServiceImpl) SendImage(c *fiber.Ctx, request structs.SendImageRequest) (response structs.SendImageResponse, err error) {
utils.MustLogin(service.WaCli) utils.MustLogin(service.WaCli)
// Resize image
// Save image to server
oriImagePath := fmt.Sprintf("%s/%s", config.PathSendItems, request.Image.Filename) oriImagePath := fmt.Sprintf("%s/%s", config.PathSendItems, request.Image.Filename)
err = c.SaveFile(request.Image, oriImagePath) err = c.SaveFile(request.Image, oriImagePath)
if err != nil { if err != nil {
return response, err return response, err
} }
// Resize image
openImageBuffer, err := bimg.Read(oriImagePath) openImageBuffer, err := bimg.Read(oriImagePath)
newImage, err := bimg.NewImage(openImageBuffer).Process(bimg.Options{Quality: 90, Width: 600, Height: 600, Embed: true}) newImage, err := bimg.NewImage(openImageBuffer).Process(bimg.Options{Quality: 90, Width: 600, Height: 600, Embed: true})
if err != nil { if err != nil {
@ -63,7 +64,7 @@ func (service SendServiceImpl) SendImage(c *fiber.Ctx, request structs.SendImage
if err != nil { if err != nil {
return response, err return response, err
} }
// Send to WA server // Send to WA server
dataWaCaption := request.Caption dataWaCaption := request.Caption
dataWaRecipient, ok := utils.ParseJID(request.Phone) 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) { func (service SendServiceImpl) SendFile(c *fiber.Ctx, request structs.SendFileRequest) (response structs.SendFileResponse, err error) {
utils.MustLogin(service.WaCli) utils.MustLogin(service.WaCli)
// Resize image
oriFilePath := fmt.Sprintf("%s/%s", config.PathSendItems, request.File.Filename) oriFilePath := fmt.Sprintf("%s/%s", config.PathSendItems, request.File.Filename)
err = c.SaveFile(request.File, oriFilePath) err = c.SaveFile(request.File, oriFilePath)
if err != nil { if err != nil {
@ -153,7 +153,57 @@ func (service SendServiceImpl) SendFile(c *fiber.Ctx, request structs.SendFileRe
if err != nil { if err != nil {
return response, err return response, err
} else { } 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 return response, nil
} }
} }

11
src/structs/send_struct.go

@ -40,3 +40,14 @@ type SendFileRequest struct {
type SendFileResponse struct { type SendFileResponse struct {
Status string `json:"status"` 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"`
}

29
src/validations/send_validation.go

@ -1,8 +1,11 @@
package validations package validations
import ( 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/structs"
"github.com/aldinokemal/go-whatsapp-web-multidevice/utils" "github.com/aldinokemal/go-whatsapp-web-multidevice/utils"
"github.com/dustin/go-humanize"
validation "github.com/go-ozzo/ozzo-validation/v4" validation "github.com/go-ozzo/ozzo-validation/v4"
"github.com/go-ozzo/ozzo-validation/v4/is" "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", Message: "your image is not allowed. please use jpg/jpeg/png",
}) })
} }
} }
func ValidateSendFile(request structs.SendFileRequest) { 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{ 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),
}) })
} }
} }
Loading…
Cancel
Save