Browse Source

feat: introduce domain

pull/28/head
Aldino Kemal 3 years ago
parent
commit
223ba389c3
  1. 6
      src/controllers/app_controller.go
  2. 29
      src/controllers/send_controller.go
  3. 19
      src/controllers/user_controller.go
  4. 13
      src/domains/app/app.go
  5. 6
      src/domains/app/login.go
  6. 12
      src/domains/send/contact.go
  7. 13
      src/domains/send/file.go
  8. 16
      src/domains/send/image.go
  9. 18
      src/domains/send/send.go
  10. 11
      src/domains/send/text.go
  11. 16
      src/domains/send/video.go
  12. 48
      src/domains/user/account.go
  13. 12
      src/domains/user/user.go
  14. 116
      src/services/app_service.go
  15. 118
      src/services/app_service_impl.go
  16. 310
      src/services/send_service.go
  17. 310
      src/services/send_service_impl.go
  18. 13
      src/services/user_service.go
  19. 18
      src/services/user_service_impl.go
  20. 67
      src/structs/send_struct.go
  21. 12
      src/validations/send_validation.go
  22. 6
      src/validations/send_validation_test.go
  23. 6
      src/validations/user_validation.go

6
src/controllers/app_controller.go

@ -2,16 +2,16 @@ package controllers
import (
"fmt"
"github.com/aldinokemal/go-whatsapp-web-multidevice/services"
domainApp "github.com/aldinokemal/go-whatsapp-web-multidevice/domains/app"
"github.com/aldinokemal/go-whatsapp-web-multidevice/utils"
"github.com/gofiber/fiber/v2"
)
type AppController struct {
Service services.AppService
Service domainApp.IAppService
}
func NewAppController(service services.AppService) AppController {
func NewAppController(service domainApp.IAppService) AppController {
return AppController{Service: service}
}

29
src/controllers/send_controller.go

@ -1,18 +1,17 @@
package controllers
import (
"github.com/aldinokemal/go-whatsapp-web-multidevice/services"
"github.com/aldinokemal/go-whatsapp-web-multidevice/structs"
domainSend "github.com/aldinokemal/go-whatsapp-web-multidevice/domains/send"
"github.com/aldinokemal/go-whatsapp-web-multidevice/utils"
"github.com/aldinokemal/go-whatsapp-web-multidevice/validations"
"github.com/gofiber/fiber/v2"
)
type SendController struct {
Service services.SendService
Service domainSend.ISendService
}
func NewSendController(service services.SendService) SendController {
func NewSendController(service domainSend.ISendService) SendController {
return SendController{Service: service}
}
@ -25,14 +24,14 @@ func (controller *SendController) Route(app *fiber.App) {
}
func (controller *SendController) SendText(c *fiber.Ctx) error {
var request structs.SendMessageRequest
var request domainSend.MessageRequest
err := c.BodyParser(&request)
utils.PanicIfNeeded(err)
// add validation send message
validations.ValidateSendMessage(request)
if request.Type == structs.TypeGroup {
if request.Type == domainSend.TypeGroup {
request.Phone = request.Phone + "@g.us"
} else {
request.Phone = request.Phone + "@s.whatsapp.net"
@ -49,7 +48,7 @@ func (controller *SendController) SendText(c *fiber.Ctx) error {
}
func (controller *SendController) SendImage(c *fiber.Ctx) error {
var request structs.SendImageRequest
var request domainSend.ImageRequest
request.Compress = true
err := c.BodyParser(&request)
@ -63,7 +62,7 @@ func (controller *SendController) SendImage(c *fiber.Ctx) error {
//add validation send image
validations.ValidateSendImage(request)
if request.Type == structs.TypeGroup {
if request.Type == domainSend.TypeGroup {
request.Phone = request.Phone + "@g.us"
} else {
request.Phone = request.Phone + "@s.whatsapp.net"
@ -80,7 +79,7 @@ func (controller *SendController) SendImage(c *fiber.Ctx) error {
}
func (controller *SendController) SendFile(c *fiber.Ctx) error {
var request structs.SendFileRequest
var request domainSend.FileRequest
err := c.BodyParser(&request)
utils.PanicIfNeeded(err)
@ -92,7 +91,7 @@ func (controller *SendController) SendFile(c *fiber.Ctx) error {
//add validation send image
validations.ValidateSendFile(request)
if request.Type == structs.TypeGroup {
if request.Type == domainSend.TypeGroup {
request.Phone = request.Phone + "@g.us"
} else {
request.Phone = request.Phone + "@s.whatsapp.net"
@ -109,7 +108,7 @@ func (controller *SendController) SendFile(c *fiber.Ctx) error {
}
func (controller *SendController) SendVideo(c *fiber.Ctx) error {
var request structs.SendVideoRequest
var request domainSend.VideoRequest
err := c.BodyParser(&request)
utils.PanicIfNeeded(err)
@ -121,7 +120,7 @@ func (controller *SendController) SendVideo(c *fiber.Ctx) error {
//add validation send image
validations.ValidateSendVideo(request)
if request.Type == structs.TypeGroup {
if request.Type == domainSend.TypeGroup {
request.Phone = request.Phone + "@g.us"
} else {
request.Phone = request.Phone + "@s.whatsapp.net"
@ -137,15 +136,15 @@ func (controller *SendController) SendVideo(c *fiber.Ctx) error {
})
}
func (controller SendController) SendContact(c *fiber.Ctx) error {
var request structs.SendContactRequest
func (controller *SendController) SendContact(c *fiber.Ctx) error {
var request domainSend.ContactRequest
err := c.BodyParser(&request)
utils.PanicIfNeeded(err)
// add validation send contect
validations.ValidateSendContact(request)
if request.Type == structs.TypeGroup {
if request.Type == domainSend.TypeGroup {
request.Phone = request.Phone + "@g.us"
} else {
request.Phone = request.Phone + "@s.whatsapp.net"

19
src/controllers/user_controller.go

@ -1,18 +1,17 @@
package controllers
import (
"github.com/aldinokemal/go-whatsapp-web-multidevice/services"
"github.com/aldinokemal/go-whatsapp-web-multidevice/structs"
domainUser "github.com/aldinokemal/go-whatsapp-web-multidevice/domains/user"
"github.com/aldinokemal/go-whatsapp-web-multidevice/utils"
"github.com/aldinokemal/go-whatsapp-web-multidevice/validations"
"github.com/gofiber/fiber/v2"
)
type UserController struct {
Service services.UserService
Service domainUser.IUserService
}
func NewUserController(service services.UserService) UserController {
func NewUserController(service domainUser.IUserService) UserController {
return UserController{Service: service}
}
@ -24,7 +23,7 @@ func (controller *UserController) Route(app *fiber.App) {
}
func (controller *UserController) UserInfo(c *fiber.Ctx) error {
var request structs.UserInfoRequest
var request domainUser.InfoRequest
err := c.QueryParser(&request)
utils.PanicIfNeeded(err)
@ -32,7 +31,7 @@ func (controller *UserController) UserInfo(c *fiber.Ctx) error {
validations.ValidateUserInfo(request)
request.Phone = request.Phone + "@s.whatsapp.net"
response, err := controller.Service.UserInfo(c, request)
response, err := controller.Service.Info(c, request)
utils.PanicIfNeeded(err)
return c.JSON(utils.ResponseData{
@ -43,7 +42,7 @@ func (controller *UserController) UserInfo(c *fiber.Ctx) error {
}
func (controller *UserController) UserAvatar(c *fiber.Ctx) error {
var request structs.UserAvatarRequest
var request domainUser.AvatarRequest
err := c.QueryParser(&request)
utils.PanicIfNeeded(err)
@ -51,7 +50,7 @@ func (controller *UserController) UserAvatar(c *fiber.Ctx) error {
validations.ValidateUserAvatar(request)
request.Phone = request.Phone + "@s.whatsapp.net"
response, err := controller.Service.UserAvatar(c, request)
response, err := controller.Service.Avatar(c, request)
utils.PanicIfNeeded(err)
return c.JSON(utils.ResponseData{
@ -62,7 +61,7 @@ func (controller *UserController) UserAvatar(c *fiber.Ctx) error {
}
func (controller *UserController) UserMyPrivacySetting(c *fiber.Ctx) error {
response, err := controller.Service.UserMyPrivacySetting(c)
response, err := controller.Service.MyPrivacySetting(c)
utils.PanicIfNeeded(err)
return c.JSON(utils.ResponseData{
@ -73,7 +72,7 @@ func (controller *UserController) UserMyPrivacySetting(c *fiber.Ctx) error {
}
func (controller *UserController) UserMyListGroups(c *fiber.Ctx) error {
response, err := controller.Service.UserMyListGroups(c)
response, err := controller.Service.MyListGroups(c)
utils.PanicIfNeeded(err)
return c.JSON(utils.ResponseData{

13
src/structs/user_struct.go → src/domains/app/app.go

@ -1,6 +1,15 @@
package structs
package app
import "go.mau.fi/whatsmeow/types"
import (
"github.com/gofiber/fiber/v2"
"go.mau.fi/whatsmeow/types"
)
type IAppService interface {
Login(c *fiber.Ctx) (response LoginResponse, err error)
Logout(c *fiber.Ctx) (err error)
Reconnect(c *fiber.Ctx) (err error)
}
type UserInfoRequest struct {
Phone string `json:"phone" query:"phone"`

6
src/structs/auth_struct.go → src/domains/app/login.go

@ -1,8 +1,6 @@
package structs
package app
import (
"time"
)
import "time"
type LoginResponse struct {
ImagePath string `json:"image_path"`

12
src/domains/send/contact.go

@ -0,0 +1,12 @@
package send
type ContactRequest struct {
Phone string `json:"phone" form:"phone"`
ContactName string `json:"contact_name" form:"contact_name"`
ContactPhone string `json:"contact_phone" form:"contact_phone"`
Type Type `json:"type" form:"type"`
}
type ContactResponse struct {
Status string `json:"status"`
}

13
src/domains/send/file.go

@ -0,0 +1,13 @@
package send
import "mime/multipart"
type FileRequest struct {
Phone string `json:"phone" form:"phone"`
File *multipart.FileHeader `json:"file" form:"file"`
Type Type `json:"type" form:"type"`
}
type FileResponse struct {
Status string `json:"status"`
}

16
src/domains/send/image.go

@ -0,0 +1,16 @@
package send
import "mime/multipart"
type ImageRequest struct {
Phone string `json:"phone" form:"phone"`
Caption string `json:"caption" form:"caption"`
Image *multipart.FileHeader `json:"image" form:"image"`
ViewOnce bool `json:"view_once" form:"view_once"`
Type Type `json:"type" form:"type"`
Compress bool `json:"compress"`
}
type ImageResponse struct {
Status string `json:"status"`
}

18
src/domains/send/send.go

@ -0,0 +1,18 @@
package send
import (
"github.com/gofiber/fiber/v2"
)
type Type string
const TypeUser Type = "user"
const TypeGroup Type = "group"
type ISendService interface {
SendText(c *fiber.Ctx, request MessageRequest) (response MessageResponse, err error)
SendImage(c *fiber.Ctx, request ImageRequest) (response ImageResponse, err error)
SendFile(c *fiber.Ctx, request FileRequest) (response FileResponse, err error)
SendVideo(c *fiber.Ctx, request VideoRequest) (response VideoResponse, err error)
SendContact(c *fiber.Ctx, request ContactRequest) (response ContactResponse, err error)
}

11
src/domains/send/text.go

@ -0,0 +1,11 @@
package send
type MessageRequest struct {
Phone string `json:"phone" form:"phone"`
Message string `json:"message" form:"message"`
Type Type `json:"type" form:"type"`
}
type MessageResponse struct {
Status string `json:"status"`
}

16
src/domains/send/video.go

@ -0,0 +1,16 @@
package send
import "mime/multipart"
type VideoRequest struct {
Phone string `json:"phone" form:"phone"`
Caption string `json:"caption" form:"caption"`
Video *multipart.FileHeader `json:"video" form:"video"`
Type Type `json:"type" form:"type"`
ViewOnce bool `json:"view_once" form:"view_once"`
Compress bool `json:"compress"`
}
type VideoResponse struct {
Status string `json:"status"`
}

48
src/domains/user/account.go

@ -0,0 +1,48 @@
package user
import "go.mau.fi/whatsmeow/types"
type InfoRequest struct {
Phone string `json:"phone" query:"phone"`
}
type InfoResponseDataDevice struct {
User string
Agent uint8
Device string
Server string
AD bool
}
type InfoResponseData struct {
VerifiedName string `json:"verified_name"`
Status string `json:"status"`
PictureID string `json:"picture_id"`
Devices []InfoResponseDataDevice `json:"devices"`
}
type InfoResponse struct {
Data []InfoResponseData `json:"data"`
}
type AvatarRequest struct {
Phone string `json:"phone" query:"phone"`
}
type AvatarResponse struct {
URL string `json:"url"`
ID string `json:"id"`
Type string `json:"type"`
}
type MyPrivacySettingResponse struct {
GroupAdd string `json:"group_add"`
LastSeen string `json:"last_seen"`
Status string `json:"status"`
Profile string `json:"profile"`
ReadReceipts string `json:"read_receipts"`
}
type MyListGroupsResponse struct {
Data []types.GroupInfo `json:"data"`
}

12
src/domains/user/user.go

@ -0,0 +1,12 @@
package user
import (
"github.com/gofiber/fiber/v2"
)
type IUserService interface {
Info(c *fiber.Ctx, request InfoRequest) (response InfoResponse, err error)
Avatar(c *fiber.Ctx, request AvatarRequest) (response AvatarResponse, err error)
MyListGroups(c *fiber.Ctx) (response MyListGroupsResponse, err error)
MyPrivacySetting(c *fiber.Ctx) (response MyPrivacySettingResponse, err error)
}

116
src/services/app_service.go

@ -1,12 +1,118 @@
package services
import (
"github.com/aldinokemal/go-whatsapp-web-multidevice/structs"
"context"
"errors"
"fmt"
"github.com/aldinokemal/go-whatsapp-web-multidevice/config"
domainApp "github.com/aldinokemal/go-whatsapp-web-multidevice/domains/app"
"github.com/gofiber/fiber/v2"
fiberUtils "github.com/gofiber/fiber/v2/utils"
"github.com/skip2/go-qrcode"
"go.mau.fi/whatsmeow"
"os"
"path/filepath"
"time"
)
type AppService interface {
Login(c *fiber.Ctx) (response structs.LoginResponse, err error)
Logout(c *fiber.Ctx) (err error)
Reconnect(c *fiber.Ctx) (err error)
type serviceApp struct {
WaCli *whatsmeow.Client
}
func NewAppService(waCli *whatsmeow.Client) domainApp.IAppService {
return &serviceApp{
WaCli: waCli,
}
}
func (service serviceApp) Login(c *fiber.Ctx) (response domainApp.LoginResponse, err error) {
if service.WaCli == nil {
return response, errors.New("wa cli nil cok")
}
// Disconnect for reconnecting
service.WaCli.Disconnect()
chImage := make(chan string)
ch, err := service.WaCli.GetQRChannel(context.Background())
if err != nil {
// This error means that we're already logged in, so ignore it.
if errors.Is(err, whatsmeow.ErrQRStoreContainsID) {
_ = service.WaCli.Connect() // just connect to websocket
if service.WaCli.IsLoggedIn() {
return response, errors.New("you already logged in :)")
}
return response, errors.New("your session have been saved, please wait to connect 2 second and refresh again")
} else {
return response, errors.New("Error when GetQRChannel:" + err.Error())
}
} else {
go func() {
for evt := range ch {
response.Code = evt.Code
response.Duration = evt.Timeout / time.Second / 2
if evt.Event == "code" {
qrPath := fmt.Sprintf("%s/scan-qr-%s.png", config.PathQrCode, fiberUtils.UUIDv4())
err = qrcode.WriteFile(evt.Code, qrcode.Medium, 512, qrPath)
if err != nil {
fmt.Println("error when write qrImage file", err.Error())
}
go func() {
time.Sleep(response.Duration * time.Second)
err := os.Remove(qrPath)
if err != nil {
fmt.Println("Failed to remove qrPath " + qrPath)
}
}()
chImage <- qrPath
} else {
fmt.Printf("QR channel result: %s", evt.Event)
}
}
}()
}
err = service.WaCli.Connect()
if err != nil {
return response, errors.New("Failed to connect bro " + err.Error())
}
response.ImagePath = <-chImage
return response, nil
}
func (service serviceApp) Logout(c *fiber.Ctx) (err error) {
// delete history
files, err := filepath.Glob("./history-*")
if err != nil {
panic(err)
}
for _, f := range files {
err = os.Remove(f)
if err != nil {
return err
}
}
// delete qr images
qrImages, err := filepath.Glob("./statics/images/qrcode/scan-*")
if err != nil {
panic(err)
}
for _, f := range qrImages {
err = os.Remove(f)
if err != nil {
return err
}
}
err = service.WaCli.Logout()
return
}
func (service serviceApp) Reconnect(c *fiber.Ctx) (err error) {
service.WaCli.Disconnect()
return service.WaCli.Connect()
}

118
src/services/app_service_impl.go

@ -1,118 +0,0 @@
package services
import (
"context"
"errors"
"fmt"
"github.com/aldinokemal/go-whatsapp-web-multidevice/config"
"github.com/aldinokemal/go-whatsapp-web-multidevice/structs"
"github.com/gofiber/fiber/v2"
fiberutils "github.com/gofiber/fiber/v2/utils"
"github.com/skip2/go-qrcode"
"go.mau.fi/whatsmeow"
"os"
"path/filepath"
"time"
)
type AppServiceImpl struct {
WaCli *whatsmeow.Client
}
func NewAppService(waCli *whatsmeow.Client) AppService {
return &AppServiceImpl{
WaCli: waCli,
}
}
func (service AppServiceImpl) Login(c *fiber.Ctx) (response structs.LoginResponse, err error) {
if service.WaCli == nil {
return response, errors.New("wa cli nil cok")
}
// Disconnect for reconnecting
service.WaCli.Disconnect()
chImage := make(chan string)
ch, err := service.WaCli.GetQRChannel(context.Background())
if err != nil {
// This error means that we're already logged in, so ignore it.
if errors.Is(err, whatsmeow.ErrQRStoreContainsID) {
_ = service.WaCli.Connect() // just connect to websocket
if service.WaCli.IsLoggedIn() {
return response, errors.New("you already logged in :)")
}
return response, errors.New("your session have been saved, please wait to connect 2 second and refresh again")
} else {
return response, errors.New("Error when GetQRChannel:" + err.Error())
}
} else {
go func() {
for evt := range ch {
response.Code = evt.Code
response.Duration = evt.Timeout / time.Second / 2
if evt.Event == "code" {
qrPath := fmt.Sprintf("%s/scan-qr-%s.png", config.PathQrCode, fiberutils.UUIDv4())
err = qrcode.WriteFile(evt.Code, qrcode.Medium, 512, qrPath)
if err != nil {
fmt.Println("error when write qrImage file", err.Error())
}
go func() {
time.Sleep(response.Duration * time.Second)
err := os.Remove(qrPath)
if err != nil {
fmt.Println("Failed to remove qrPath " + qrPath)
}
}()
chImage <- qrPath
} else {
fmt.Printf("QR channel result: %s", evt.Event)
}
}
}()
}
err = service.WaCli.Connect()
if err != nil {
return response, errors.New("Failed to connect bro " + err.Error())
}
response.ImagePath = <-chImage
return response, nil
}
func (service AppServiceImpl) Logout(c *fiber.Ctx) (err error) {
// delete history
files, err := filepath.Glob("./history-*")
if err != nil {
panic(err)
}
for _, f := range files {
err = os.Remove(f)
if err != nil {
return err
}
}
// delete qr images
qrImages, err := filepath.Glob("./statics/images/qrcode/scan-*")
if err != nil {
panic(err)
}
for _, f := range qrImages {
err = os.Remove(f)
if err != nil {
return err
}
}
err = service.WaCli.Logout()
return
}
func (service AppServiceImpl) Reconnect(c *fiber.Ctx) (err error) {
service.WaCli.Disconnect()
return service.WaCli.Connect()
}

310
src/services/send_service.go

@ -1,14 +1,310 @@
package services
import (
"github.com/aldinokemal/go-whatsapp-web-multidevice/structs"
"context"
"errors"
"fmt"
"github.com/aldinokemal/go-whatsapp-web-multidevice/config"
domainSend "github.com/aldinokemal/go-whatsapp-web-multidevice/domains/send"
"github.com/aldinokemal/go-whatsapp-web-multidevice/utils"
"github.com/gofiber/fiber/v2"
fiberUtils "github.com/gofiber/fiber/v2/utils"
"github.com/h2non/bimg"
"go.mau.fi/whatsmeow"
waProto "go.mau.fi/whatsmeow/binary/proto"
"google.golang.org/protobuf/proto"
"net/http"
"os"
"os/exec"
)
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)
SendContact(c *fiber.Ctx, request structs.SendContactRequest) (response structs.SendContactResponse, err error)
type serviceSend struct {
WaCli *whatsmeow.Client
}
func NewSendService(waCli *whatsmeow.Client) domainSend.ISendService {
return &serviceSend{
WaCli: waCli,
}
}
func (service serviceSend) SendText(c *fiber.Ctx, request domainSend.MessageRequest) (response domainSend.MessageResponse, err error) {
utils.MustLogin(service.WaCli)
recipient, ok := utils.ParseJID(request.Phone)
if !ok {
return response, errors.New("invalid JID " + request.Phone)
}
msg := &waProto.Message{Conversation: proto.String(request.Message)}
ts, err := service.WaCli.SendMessage(c.Context(), recipient, "", msg)
if err != nil {
return response, err
} else {
response.Status = fmt.Sprintf("Message sent to %s (server timestamp: %s)", request.Phone, ts)
}
return response, nil
}
func (service serviceSend) SendImage(c *fiber.Ctx, request domainSend.ImageRequest) (response domainSend.ImageResponse, err error) {
utils.MustLogin(service.WaCli)
var (
imagePath string
imageThumbnail string
deletedItems []string
)
// 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
}
deletedItems = append(deletedItems, oriImagePath)
// Generate thumbnail with smalled image
openThumbnailBuffer, err := bimg.Read(oriImagePath)
imageThumbnail = fmt.Sprintf("%s/thumbnails-%s", config.PathSendItems, request.Image.Filename)
thumbnailImage, err := bimg.NewImage(openThumbnailBuffer).Process(bimg.Options{Quality: 90, Width: 100, Embed: true})
if err != nil {
return response, err
}
err = bimg.Write(imageThumbnail, thumbnailImage)
if err != nil {
return response, err
}
deletedItems = append(deletedItems, imageThumbnail)
if request.Compress {
// Resize image
openImageBuffer, err := bimg.Read(oriImagePath)
newImage, err := bimg.NewImage(openImageBuffer).Process(bimg.Options{Quality: 90, Width: 600, Embed: true})
if err != nil {
return response, err
}
newImagePath := fmt.Sprintf("%s/new-%s", config.PathSendItems, request.Image.Filename)
err = bimg.Write(newImagePath, newImage)
if err != nil {
return response, err
}
deletedItems = append(deletedItems, newImagePath)
imagePath = newImagePath
} else {
imagePath = oriImagePath
}
// Send to WA server
dataWaCaption := request.Caption
dataWaRecipient, ok := utils.ParseJID(request.Phone)
if !ok {
return response, errors.New("invalid JID " + request.Phone)
}
dataWaImage, err := os.ReadFile(imagePath)
if err != nil {
return response, err
}
uploadedImage, err := service.WaCli.Upload(context.Background(), dataWaImage, whatsmeow.MediaImage)
if err != nil {
fmt.Printf("Failed to upload file: %v", err)
return response, err
}
dataWaThumbnail, err := os.ReadFile(imageThumbnail)
msg := &waProto.Message{ImageMessage: &waProto.ImageMessage{
JpegThumbnail: dataWaThumbnail,
Caption: proto.String(dataWaCaption),
Url: proto.String(uploadedImage.URL),
DirectPath: proto.String(uploadedImage.DirectPath),
MediaKey: uploadedImage.MediaKey,
Mimetype: proto.String(http.DetectContentType(dataWaImage)),
FileEncSha256: uploadedImage.FileEncSHA256,
FileSha256: uploadedImage.FileSHA256,
FileLength: proto.Uint64(uint64(len(dataWaImage))),
ViewOnce: proto.Bool(request.ViewOnce),
}}
ts, err := service.WaCli.SendMessage(c.Context(), dataWaRecipient, "", msg)
go func() {
errDelete := utils.RemoveFile(0, deletedItems...)
if errDelete != nil {
fmt.Println("error when deleting picture: ", errDelete)
}
}()
if err != nil {
return response, err
} else {
response.Status = fmt.Sprintf("Message sent to %s (server timestamp: %s)", request.Phone, ts)
return response, nil
}
}
func (service serviceSend) SendFile(c *fiber.Ctx, request domainSend.FileRequest) (response domainSend.FileResponse, err error) {
utils.MustLogin(service.WaCli)
oriFilePath := fmt.Sprintf("%s/%s", config.PathSendItems, request.File.Filename)
err = c.SaveFile(request.File, oriFilePath)
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(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),
MediaKey: uploadedFile.MediaKey,
FileName: proto.String(request.File.Filename),
FileEncSha256: uploadedFile.FileEncSHA256,
DirectPath: proto.String(uploadedFile.DirectPath),
}}
ts, err := service.WaCli.SendMessage(c.Context(), dataWaRecipient, "", msg)
go func() {
errDelete := utils.RemoveFile(0, oriFilePath)
if errDelete != nil {
fmt.Println(errDelete)
}
}()
if err != nil {
return response, err
} else {
response.Status = fmt.Sprintf("Document sent to %s (server timestamp: %s)", request.Phone, ts)
return response, nil
}
}
func (service serviceSend) SendVideo(c *fiber.Ctx, request domainSend.VideoRequest) (response domainSend.VideoResponse, err error) {
utils.MustLogin(service.WaCli)
var (
videoPath string
videoThumbnail string
deletedItems []string
)
generateUUID := fiberUtils.UUIDv4()
// Save video to server
oriVideoPath := fmt.Sprintf("%s/%s", config.PathSendItems, generateUUID+request.Video.Filename)
err = c.SaveFile(request.Video, oriVideoPath)
if err != nil {
return response, err
}
// Get thumbnail video with ffmpeg
thumbnailVideoPath := fmt.Sprintf("%s/%s", config.PathSendItems, generateUUID+".png")
cmdThumbnail := exec.Command("ffmpeg", "-i", oriVideoPath, "-ss", "00:00:01.000", "-vframes", "1", thumbnailVideoPath)
err = cmdThumbnail.Run()
utils.PanicIfNeeded(err, "error when getting thumbnail")
// Resize Thumbnail
openImageBuffer, err := bimg.Read(thumbnailVideoPath)
resize, err := bimg.NewImage(openImageBuffer).Process(bimg.Options{Quality: 90, Width: 600, Embed: true})
if err != nil {
return response, err
}
thumbnailResizeVideoPath := fmt.Sprintf("%s/%s", config.PathSendItems, generateUUID+"_resize.png")
err = bimg.Write(thumbnailResizeVideoPath, resize)
if err != nil {
return response, err
}
deletedItems = append(deletedItems, thumbnailVideoPath)
deletedItems = append(deletedItems, thumbnailResizeVideoPath)
videoThumbnail = thumbnailResizeVideoPath
if request.Compress {
compresVideoPath := fmt.Sprintf("%s/%s", config.PathSendItems, generateUUID+".mp4")
// Compress video with ffmpeg
cmdCompress := exec.Command("ffmpeg", "-i", oriVideoPath, "-strict", "-2", compresVideoPath)
err = cmdCompress.Run()
utils.PanicIfNeeded(err, "error when compress video")
videoPath = compresVideoPath
deletedItems = append(deletedItems, compresVideoPath)
} else {
videoPath = oriVideoPath
deletedItems = append(deletedItems, oriVideoPath)
}
//Send to WA server
dataWaRecipient, ok := utils.ParseJID(request.Phone)
if !ok {
return response, errors.New("invalid JID " + request.Phone)
}
dataWaVideo, err := os.ReadFile(videoPath)
if err != nil {
return response, err
}
uploadedFile, err := service.WaCli.Upload(context.Background(), dataWaVideo, whatsmeow.MediaVideo)
if err != nil {
fmt.Printf("Failed to upload file: %v", err)
return response, err
}
dataWaThumbnail, err := os.ReadFile(videoThumbnail)
if err != nil {
return response, err
}
msg := &waProto.Message{VideoMessage: &waProto.VideoMessage{
Url: proto.String(uploadedFile.URL),
Mimetype: proto.String(http.DetectContentType(dataWaVideo)),
Caption: proto.String(request.Caption),
FileLength: proto.Uint64(uploadedFile.FileLength),
FileSha256: uploadedFile.FileSHA256,
FileEncSha256: uploadedFile.FileEncSHA256,
MediaKey: uploadedFile.MediaKey,
DirectPath: proto.String(uploadedFile.DirectPath),
ViewOnce: proto.Bool(request.ViewOnce),
JpegThumbnail: dataWaThumbnail,
}}
ts, err := service.WaCli.SendMessage(c.Context(), dataWaRecipient, "", msg)
go func() {
errDelete := utils.RemoveFile(0, deletedItems...)
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
}
}
func (service serviceSend) SendContact(c *fiber.Ctx, request domainSend.ContactRequest) (response domainSend.ContactResponse, err error) {
utils.MustLogin(service.WaCli)
recipient, ok := utils.ParseJID(request.Phone)
if !ok {
return response, errors.New("invalid JID " + request.Phone)
}
msgVCard := fmt.Sprintf("BEGIN:VCARD\nVERSION:3.0\nN:;%v;;;\nFN:%v\nTEL;type=CELL;waid=%v:+%v\nEND:VCARD",
request.ContactName, request.ContactName, request.ContactPhone, request.ContactPhone)
msg := &waProto.Message{ContactMessage: &waProto.ContactMessage{
DisplayName: proto.String(request.ContactName),
Vcard: proto.String(msgVCard),
}}
ts, err := service.WaCli.SendMessage(c.Context(), recipient, "", msg)
if err != nil {
return response, err
} else {
response.Status = fmt.Sprintf("Contact sent to %s (server timestamp: %s)", request.Phone, ts)
}
return response, nil
}

310
src/services/send_service_impl.go

@ -1,310 +0,0 @@
package services
import (
"context"
"errors"
"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/gofiber/fiber/v2"
fiberUtils "github.com/gofiber/fiber/v2/utils"
"github.com/h2non/bimg"
"go.mau.fi/whatsmeow"
waProto "go.mau.fi/whatsmeow/binary/proto"
"google.golang.org/protobuf/proto"
"net/http"
"os"
"os/exec"
)
type SendServiceImpl struct {
WaCli *whatsmeow.Client
}
func NewSendService(waCli *whatsmeow.Client) SendService {
return &SendServiceImpl{
WaCli: waCli,
}
}
func (service SendServiceImpl) SendText(c *fiber.Ctx, request structs.SendMessageRequest) (response structs.SendMessageResponse, err error) {
utils.MustLogin(service.WaCli)
recipient, ok := utils.ParseJID(request.Phone)
if !ok {
return response, errors.New("invalid JID " + request.Phone)
}
msg := &waProto.Message{Conversation: proto.String(request.Message)}
ts, err := service.WaCli.SendMessage(c.Context(), recipient, "", msg)
if err != nil {
return response, err
} else {
response.Status = fmt.Sprintf("Message sent to %s (server timestamp: %s)", request.Phone, ts)
}
return response, nil
}
func (service SendServiceImpl) SendImage(c *fiber.Ctx, request structs.SendImageRequest) (response structs.SendImageResponse, err error) {
utils.MustLogin(service.WaCli)
var (
imagePath string
imageThumbnail string
deletedItems []string
)
// 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
}
deletedItems = append(deletedItems, oriImagePath)
// Generate thumbnail with smalled image
openThumbnailBuffer, err := bimg.Read(oriImagePath)
imageThumbnail = fmt.Sprintf("%s/thumbnails-%s", config.PathSendItems, request.Image.Filename)
thumbnailImage, err := bimg.NewImage(openThumbnailBuffer).Process(bimg.Options{Quality: 90, Width: 100, Embed: true})
if err != nil {
return response, err
}
err = bimg.Write(imageThumbnail, thumbnailImage)
if err != nil {
return response, err
}
deletedItems = append(deletedItems, imageThumbnail)
if request.Compress {
// Resize image
openImageBuffer, err := bimg.Read(oriImagePath)
newImage, err := bimg.NewImage(openImageBuffer).Process(bimg.Options{Quality: 90, Width: 600, Embed: true})
if err != nil {
return response, err
}
newImagePath := fmt.Sprintf("%s/new-%s", config.PathSendItems, request.Image.Filename)
err = bimg.Write(newImagePath, newImage)
if err != nil {
return response, err
}
deletedItems = append(deletedItems, newImagePath)
imagePath = newImagePath
} else {
imagePath = oriImagePath
}
// Send to WA server
dataWaCaption := request.Caption
dataWaRecipient, ok := utils.ParseJID(request.Phone)
if !ok {
return response, errors.New("invalid JID " + request.Phone)
}
dataWaImage, err := os.ReadFile(imagePath)
if err != nil {
return response, err
}
uploadedImage, err := service.WaCli.Upload(context.Background(), dataWaImage, whatsmeow.MediaImage)
if err != nil {
fmt.Printf("Failed to upload file: %v", err)
return response, err
}
dataWaThumbnail, err := os.ReadFile(imageThumbnail)
msg := &waProto.Message{ImageMessage: &waProto.ImageMessage{
JpegThumbnail: dataWaThumbnail,
Caption: proto.String(dataWaCaption),
Url: proto.String(uploadedImage.URL),
DirectPath: proto.String(uploadedImage.DirectPath),
MediaKey: uploadedImage.MediaKey,
Mimetype: proto.String(http.DetectContentType(dataWaImage)),
FileEncSha256: uploadedImage.FileEncSHA256,
FileSha256: uploadedImage.FileSHA256,
FileLength: proto.Uint64(uint64(len(dataWaImage))),
ViewOnce: proto.Bool(request.ViewOnce),
}}
ts, err := service.WaCli.SendMessage(c.Context(), dataWaRecipient, "", msg)
go func() {
errDelete := utils.RemoveFile(0, deletedItems...)
if errDelete != nil {
fmt.Println("error when deleting picture: ", errDelete)
}
}()
if err != nil {
return response, err
} else {
response.Status = fmt.Sprintf("Message sent to %s (server timestamp: %s)", request.Phone, ts)
return response, nil
}
}
func (service SendServiceImpl) SendFile(c *fiber.Ctx, request structs.SendFileRequest) (response structs.SendFileResponse, err error) {
utils.MustLogin(service.WaCli)
oriFilePath := fmt.Sprintf("%s/%s", config.PathSendItems, request.File.Filename)
err = c.SaveFile(request.File, oriFilePath)
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(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),
MediaKey: uploadedFile.MediaKey,
FileName: proto.String(request.File.Filename),
FileEncSha256: uploadedFile.FileEncSHA256,
DirectPath: proto.String(uploadedFile.DirectPath),
}}
ts, err := service.WaCli.SendMessage(c.Context(), dataWaRecipient, "", msg)
go func() {
errDelete := utils.RemoveFile(0, oriFilePath)
if errDelete != nil {
fmt.Println(errDelete)
}
}()
if err != nil {
return response, err
} else {
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)
var (
videoPath string
videoThumbnail string
deletedItems []string
)
generateUUID := fiberUtils.UUIDv4()
// Save video to server
oriVideoPath := fmt.Sprintf("%s/%s", config.PathSendItems, generateUUID+request.Video.Filename)
err = c.SaveFile(request.Video, oriVideoPath)
if err != nil {
return response, err
}
// Get thumbnail video with ffmpeg
thumbnailVideoPath := fmt.Sprintf("%s/%s", config.PathSendItems, generateUUID+".png")
cmdThumbnail := exec.Command("ffmpeg", "-i", oriVideoPath, "-ss", "00:00:01.000", "-vframes", "1", thumbnailVideoPath)
err = cmdThumbnail.Run()
utils.PanicIfNeeded(err, "error when getting thumbnail")
// Resize Thumbnail
openImageBuffer, err := bimg.Read(thumbnailVideoPath)
resize, err := bimg.NewImage(openImageBuffer).Process(bimg.Options{Quality: 90, Width: 600, Embed: true})
if err != nil {
return response, err
}
thumbnailResizeVideoPath := fmt.Sprintf("%s/%s", config.PathSendItems, generateUUID+"_resize.png")
err = bimg.Write(thumbnailResizeVideoPath, resize)
if err != nil {
return response, err
}
deletedItems = append(deletedItems, thumbnailVideoPath)
deletedItems = append(deletedItems, thumbnailResizeVideoPath)
videoThumbnail = thumbnailResizeVideoPath
if request.Compress {
compresVideoPath := fmt.Sprintf("%s/%s", config.PathSendItems, generateUUID+".mp4")
// Compress video with ffmpeg
cmdCompress := exec.Command("ffmpeg", "-i", oriVideoPath, "-strict", "-2", compresVideoPath)
err = cmdCompress.Run()
utils.PanicIfNeeded(err, "error when compress video")
videoPath = compresVideoPath
deletedItems = append(deletedItems, compresVideoPath)
} else {
videoPath = oriVideoPath
deletedItems = append(deletedItems, oriVideoPath)
}
//Send to WA server
dataWaRecipient, ok := utils.ParseJID(request.Phone)
if !ok {
return response, errors.New("invalid JID " + request.Phone)
}
dataWaVideo, err := os.ReadFile(videoPath)
if err != nil {
return response, err
}
uploadedFile, err := service.WaCli.Upload(context.Background(), dataWaVideo, whatsmeow.MediaVideo)
if err != nil {
fmt.Printf("Failed to upload file: %v", err)
return response, err
}
dataWaThumbnail, err := os.ReadFile(videoThumbnail)
if err != nil {
return response, err
}
msg := &waProto.Message{VideoMessage: &waProto.VideoMessage{
Url: proto.String(uploadedFile.URL),
Mimetype: proto.String(http.DetectContentType(dataWaVideo)),
Caption: proto.String(request.Caption),
FileLength: proto.Uint64(uploadedFile.FileLength),
FileSha256: uploadedFile.FileSHA256,
FileEncSha256: uploadedFile.FileEncSHA256,
MediaKey: uploadedFile.MediaKey,
DirectPath: proto.String(uploadedFile.DirectPath),
ViewOnce: proto.Bool(request.ViewOnce),
JpegThumbnail: dataWaThumbnail,
}}
ts, err := service.WaCli.SendMessage(c.Context(), dataWaRecipient, "", msg)
go func() {
errDelete := utils.RemoveFile(0, deletedItems...)
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
}
}
func (service SendServiceImpl) SendContact(c *fiber.Ctx, request structs.SendContactRequest) (response structs.SendContactResponse, err error) {
utils.MustLogin(service.WaCli)
recipient, ok := utils.ParseJID(request.Phone)
if !ok {
return response, errors.New("invalid JID " + request.Phone)
}
msgVCard := fmt.Sprintf("BEGIN:VCARD\nVERSION:3.0\nN:;%v;;;\nFN:%v\nTEL;type=CELL;waid=%v:+%v\nEND:VCARD",
request.ContactName, request.ContactName, request.ContactPhone, request.ContactPhone)
msg := &waProto.Message{ContactMessage: &waProto.ContactMessage{
DisplayName: proto.String(request.ContactName),
Vcard: proto.String(msgVCard),
}}
ts, err := service.WaCli.SendMessage(c.Context(), recipient, "", msg)
if err != nil {
return response, err
} else {
response.Status = fmt.Sprintf("Contact sent to %s (server timestamp: %s)", request.Phone, ts)
}
return response, nil
}

13
src/services/user_service.go

@ -1,13 +0,0 @@
package services
import (
"github.com/aldinokemal/go-whatsapp-web-multidevice/structs"
"github.com/gofiber/fiber/v2"
)
type UserService interface {
UserInfo(c *fiber.Ctx, request structs.UserInfoRequest) (response structs.UserInfoResponse, err error)
UserAvatar(c *fiber.Ctx, request structs.UserAvatarRequest) (response structs.UserAvatarResponse, err error)
UserMyListGroups(c *fiber.Ctx) (response structs.UserMyListGroupsResponse, err error)
UserMyPrivacySetting(c *fiber.Ctx) (response structs.UserMyPrivacySettingResponse, err error)
}

18
src/services/user_service_impl.go

@ -3,7 +3,7 @@ package services
import (
"errors"
"fmt"
"github.com/aldinokemal/go-whatsapp-web-multidevice/structs"
domainUser "github.com/aldinokemal/go-whatsapp-web-multidevice/domains/user"
"github.com/aldinokemal/go-whatsapp-web-multidevice/utils"
"github.com/gofiber/fiber/v2"
"go.mau.fi/whatsmeow"
@ -14,13 +14,13 @@ type UserServiceImpl struct {
WaCli *whatsmeow.Client
}
func NewUserService(waCli *whatsmeow.Client) UserService {
func NewUserService(waCli *whatsmeow.Client) domainUser.IUserService {
return &UserServiceImpl{
WaCli: waCli,
}
}
func (service UserServiceImpl) UserInfo(_ *fiber.Ctx, request structs.UserInfoRequest) (response structs.UserInfoResponse, err error) {
func (service UserServiceImpl) Info(_ *fiber.Ctx, request domainUser.InfoRequest) (response domainUser.InfoResponse, err error) {
utils.MustLogin(service.WaCli)
var jids []types.JID
@ -36,9 +36,9 @@ func (service UserServiceImpl) UserInfo(_ *fiber.Ctx, request structs.UserInfoRe
}
for _, userInfo := range resp {
var device []structs.UserInfoResponseDataDevice
var device []domainUser.InfoResponseDataDevice
for _, j := range userInfo.Devices {
device = append(device, structs.UserInfoResponseDataDevice{
device = append(device, domainUser.InfoResponseDataDevice{
User: j.User,
Agent: j.Agent,
Device: utils.GetPlatformName(int(j.Device)),
@ -47,7 +47,7 @@ func (service UserServiceImpl) UserInfo(_ *fiber.Ctx, request structs.UserInfoRe
})
}
data := structs.UserInfoResponseData{
data := domainUser.InfoResponseData{
Status: userInfo.Status,
PictureID: userInfo.PictureID,
Devices: device,
@ -61,7 +61,7 @@ func (service UserServiceImpl) UserInfo(_ *fiber.Ctx, request structs.UserInfoRe
return response, nil
}
func (service UserServiceImpl) UserAvatar(c *fiber.Ctx, request structs.UserAvatarRequest) (response structs.UserAvatarResponse, err error) {
func (service UserServiceImpl) Avatar(c *fiber.Ctx, request domainUser.AvatarRequest) (response domainUser.AvatarResponse, err error) {
utils.MustLogin(service.WaCli)
jid, ok := utils.ParseJID(request.Phone)
@ -82,7 +82,7 @@ func (service UserServiceImpl) UserAvatar(c *fiber.Ctx, request structs.UserAvat
}
}
func (service UserServiceImpl) UserMyListGroups(_ *fiber.Ctx) (response structs.UserMyListGroupsResponse, err error) {
func (service UserServiceImpl) MyListGroups(_ *fiber.Ctx) (response domainUser.MyListGroupsResponse, err error) {
utils.MustLogin(service.WaCli)
groups, err := service.WaCli.GetJoinedGroups()
@ -98,7 +98,7 @@ func (service UserServiceImpl) UserMyListGroups(_ *fiber.Ctx) (response structs.
return response, nil
}
func (service UserServiceImpl) UserMyPrivacySetting(_ *fiber.Ctx) (response structs.UserMyPrivacySettingResponse, err error) {
func (service UserServiceImpl) MyPrivacySetting(_ *fiber.Ctx) (response domainUser.MyPrivacySettingResponse, err error) {
utils.MustLogin(service.WaCli)
resp, err := service.WaCli.TryFetchPrivacySettings(false)

67
src/structs/send_struct.go

@ -1,67 +0,0 @@
package structs
import (
"mime/multipart"
)
type SendType string
const TypeUser SendType = "user"
const TypeGroup SendType = "group"
type SendMessageRequest struct {
Phone string `json:"phone" form:"phone"`
Message string `json:"message" form:"message"`
Type SendType `json:"type" form:"type"`
}
type SendMessageResponse struct {
Status string `json:"status"`
}
type SendImageRequest struct {
Phone string `json:"phone" form:"phone"`
Caption string `json:"caption" form:"caption"`
Image *multipart.FileHeader `json:"image" form:"image"`
ViewOnce bool `json:"view_once" form:"view_once"`
Type SendType `json:"type" form:"type"`
Compress bool `json:"compress"`
}
type SendImageResponse struct {
Status string `json:"status"`
}
type SendFileRequest struct {
Phone string `json:"phone" form:"phone"`
File *multipart.FileHeader `json:"file" form:"file"`
Type SendType `json:"type" form:"type"`
}
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:"type"`
ViewOnce bool `json:"view_once" form:"view_once"`
Compress bool `json:"compress"`
}
type SendVideoResponse struct {
Status string `json:"status"`
}
type SendContactRequest struct {
Phone string `json:"phone" form:"phone"`
ContactName string `json:"contact_name" form:"contact_name"`
ContactPhone string `json:"contact_phone" form:"contact_phone"`
Type SendType `json:"type" form:"type"`
}
type SendContactResponse struct {
Status string `json:"status"`
}

12
src/validations/send_validation.go

@ -3,13 +3,13 @@ package validations
import (
"fmt"
"github.com/aldinokemal/go-whatsapp-web-multidevice/config"
"github.com/aldinokemal/go-whatsapp-web-multidevice/structs"
domainSend "github.com/aldinokemal/go-whatsapp-web-multidevice/domains/send"
"github.com/aldinokemal/go-whatsapp-web-multidevice/utils"
"github.com/dustin/go-humanize"
validation "github.com/go-ozzo/ozzo-validation/v4"
)
func ValidateSendMessage(request structs.SendMessageRequest) {
func ValidateSendMessage(request domainSend.MessageRequest) {
err := validation.ValidateStruct(&request,
validation.Field(&request.Phone, validation.Required, validation.Length(10, 25)),
validation.Field(&request.Message, validation.Required, validation.Length(1, 1000)),
@ -22,7 +22,7 @@ func ValidateSendMessage(request structs.SendMessageRequest) {
}
}
func ValidateSendImage(request structs.SendImageRequest) {
func ValidateSendImage(request domainSend.ImageRequest) {
err := validation.ValidateStruct(&request,
validation.Field(&request.Phone, validation.Required, validation.Length(10, 25)),
validation.Field(&request.Caption, validation.When(true, validation.Length(1, 1000))),
@ -48,7 +48,7 @@ func ValidateSendImage(request structs.SendImageRequest) {
}
}
func ValidateSendFile(request structs.SendFileRequest) {
func ValidateSendFile(request domainSend.FileRequest) {
err := validation.ValidateStruct(&request,
validation.Field(&request.Phone, validation.Required, validation.Length(10, 25)),
validation.Field(&request.File, validation.Required),
@ -68,7 +68,7 @@ func ValidateSendFile(request structs.SendFileRequest) {
}
}
func ValidateSendVideo(request structs.SendVideoRequest) {
func ValidateSendVideo(request domainSend.VideoRequest) {
err := validation.ValidateStruct(&request,
validation.Field(&request.Phone, validation.Required, validation.Length(10, 25)),
validation.Field(&request.Video, validation.Required),
@ -100,7 +100,7 @@ func ValidateSendVideo(request structs.SendVideoRequest) {
}
}
func ValidateSendContact(request structs.SendContactRequest) {
func ValidateSendContact(request domainSend.ContactRequest) {
err := validation.ValidateStruct(&request,
validation.Field(&request.Phone, validation.Required, validation.Length(10, 25)),
validation.Field(&request.ContactName, validation.Required),

6
src/validations/send_validation_test.go

@ -1,14 +1,14 @@
package validations
import (
"github.com/aldinokemal/go-whatsapp-web-multidevice/structs"
domainSend "github.com/aldinokemal/go-whatsapp-web-multidevice/domains/send"
"github.com/stretchr/testify/assert"
"testing"
)
func TestValidateSendMessage(t *testing.T) {
type args struct {
request structs.SendMessageRequest
request domainSend.MessageRequest
}
tests := []struct {
name string
@ -17,7 +17,7 @@ func TestValidateSendMessage(t *testing.T) {
}{
{
name: "success phone & message normal",
args: args{request: structs.SendMessageRequest{
args: args{request: domainSend.MessageRequest{
Phone: "6289685024091",
Message: "Hello this is testing",
}},

6
src/validations/user_validation.go

@ -1,13 +1,13 @@
package validations
import (
"github.com/aldinokemal/go-whatsapp-web-multidevice/structs"
domainUser "github.com/aldinokemal/go-whatsapp-web-multidevice/domains/user"
"github.com/aldinokemal/go-whatsapp-web-multidevice/utils"
validation "github.com/go-ozzo/ozzo-validation/v4"
"github.com/go-ozzo/ozzo-validation/v4/is"
)
func ValidateUserInfo(request structs.UserInfoRequest) {
func ValidateUserInfo(request domainUser.InfoRequest) {
err := validation.ValidateStruct(&request,
validation.Field(&request.Phone, validation.Required, is.E164, validation.Length(10, 15)),
)
@ -18,7 +18,7 @@ func ValidateUserInfo(request structs.UserInfoRequest) {
})
}
}
func ValidateUserAvatar(request structs.UserAvatarRequest) {
func ValidateUserAvatar(request domainUser.AvatarRequest) {
err := validation.ValidateStruct(&request,
validation.Field(&request.Phone, validation.Required, is.E164, validation.Length(10, 15)),
)

Loading…
Cancel
Save