From 10976dfac237dfa866cf5b366971a31a1f4cefff Mon Sep 17 00:00:00 2001 From: Aldino Kemal Date: Sun, 18 Dec 2022 11:56:57 +0700 Subject: [PATCH] feat: add avatar preview and community --- src/domains/user/account.go | 4 +- src/internal/rest/user.go | 11 +---- src/pkg/error/generic_error.go | 17 +++++++ src/services/user.go | 64 +++++++++++++++++-------- src/validations/user_validation.go | 2 + src/validations/user_validation_test.go | 8 +++- src/views/index.html | 20 +++++++- 7 files changed, 94 insertions(+), 32 deletions(-) diff --git a/src/domains/user/account.go b/src/domains/user/account.go index 2d6fc75..4d6369c 100644 --- a/src/domains/user/account.go +++ b/src/domains/user/account.go @@ -26,7 +26,9 @@ type InfoResponse struct { } type AvatarRequest struct { - Phone string `json:"phone" query:"phone"` + Phone string `json:"phone" query:"phone"` + IsPreview bool `json:"is_preview" query:"is_preview"` + IsCommunity bool `json:"is_community" query:"is_community"` } type AvatarResponse struct { diff --git a/src/internal/rest/user.go b/src/internal/rest/user.go index fa3cd25..80d0d2d 100644 --- a/src/internal/rest/user.go +++ b/src/internal/rest/user.go @@ -21,13 +21,6 @@ func InitRestUser(app *fiber.App, service domainUser.IUserService) User { return rest } -func (controller *User) Route(app *fiber.App) { - app.Get("/user/info", controller.UserInfo) - app.Get("/user/avatar", controller.UserAvatar) - app.Get("/user/my/privacy", controller.UserMyPrivacySetting) - app.Get("/user/my/groups", controller.UserMyListGroups) -} - func (controller *User) UserInfo(c *fiber.Ctx) error { var request domainUser.InfoRequest err := c.QueryParser(&request) @@ -35,7 +28,7 @@ func (controller *User) UserInfo(c *fiber.Ctx) error { whatsapp.SanitizePhone(&request.Phone) - response, err := controller.Service.Info(c.Context(), request) + response, err := controller.Service.Info(c.UserContext(), request) utils.PanicIfNeeded(err) return c.JSON(utils.ResponseData{ @@ -52,7 +45,7 @@ func (controller *User) UserAvatar(c *fiber.Ctx) error { whatsapp.SanitizePhone(&request.Phone) - response, err := controller.Service.Avatar(c.Context(), request) + response, err := controller.Service.Avatar(c.UserContext(), request) utils.PanicIfNeeded(err) return c.JSON(utils.ResponseData{ diff --git a/src/pkg/error/generic_error.go b/src/pkg/error/generic_error.go index 0a0ab8d..4665840 100644 --- a/src/pkg/error/generic_error.go +++ b/src/pkg/error/generic_error.go @@ -25,3 +25,20 @@ func (e InternalServerError) ErrCode() string { func (e InternalServerError) StatusCode() int { return http.StatusInternalServerError } + +type ContextError string + +// Error for complying the error interface +func (e ContextError) Error() string { + return string(e) +} + +// ErrCode will return the error code based on the error data type +func (e ContextError) ErrCode() string { + return "CONTEXT_ERROR" +} + +// StatusCode will return the HTTP status code based on the error data type +func (e ContextError) StatusCode() int { + return http.StatusRequestTimeout +} diff --git a/src/services/user.go b/src/services/user.go index ba24d7b..c87020c 100644 --- a/src/services/user.go +++ b/src/services/user.go @@ -5,10 +5,12 @@ import ( "errors" "fmt" domainUser "github.com/aldinokemal/go-whatsapp-web-multidevice/domains/user" + pkgError "github.com/aldinokemal/go-whatsapp-web-multidevice/pkg/error" "github.com/aldinokemal/go-whatsapp-web-multidevice/pkg/whatsapp" "github.com/aldinokemal/go-whatsapp-web-multidevice/validations" "go.mau.fi/whatsmeow" "go.mau.fi/whatsmeow/types" + "time" ) type userService struct { @@ -65,26 +67,50 @@ func (service userService) Info(ctx context.Context, request domainUser.InfoRequ } func (service userService) Avatar(ctx context.Context, request domainUser.AvatarRequest) (response domainUser.AvatarResponse, err error) { - err = validations.ValidateUserAvatar(ctx, request) - if err != nil { - return response, err - } - dataWaRecipient, err := whatsapp.ValidateJidWithLogin(service.WaCli, request.Phone) - if err != nil { - return response, err - } - pic, err := service.WaCli.GetProfilePictureInfo(dataWaRecipient, false, "") - if err != nil { - return response, err - } else if pic == nil { - return response, errors.New("no avatar found") - } else { - response.URL = pic.URL - response.ID = pic.ID - response.Type = pic.Type - - return response, nil + + chanResp := make(chan domainUser.AvatarResponse) + chanErr := make(chan error) + waktu := time.Now() + + go func() { + err = validations.ValidateUserAvatar(ctx, request) + if err != nil { + chanErr <- err + } + dataWaRecipient, err := whatsapp.ValidateJidWithLogin(service.WaCli, request.Phone) + if err != nil { + chanErr <- err + } + pic, err := service.WaCli.GetProfilePictureInfo(dataWaRecipient, &whatsmeow.GetProfilePictureParams{ + Preview: request.IsPreview, + IsCommunity: request.IsCommunity, + }) + if err != nil { + chanErr <- err + } else if pic == nil { + chanErr <- errors.New("no avatar found") + } else { + response.URL = pic.URL + response.ID = pic.ID + response.Type = pic.Type + + chanResp <- response + } + }() + + for { + select { + case err := <-chanErr: + return response, err + case response := <-chanResp: + return response, nil + default: + if waktu.Add(2 * time.Second).Before(time.Now()) { + return response, pkgError.ContextError("Error timeout get avatar !") + } + } } + } func (service userService) MyListGroups(_ context.Context) (response domainUser.MyListGroupsResponse, err error) { diff --git a/src/validations/user_validation.go b/src/validations/user_validation.go index 36a27fe..5f6e359 100644 --- a/src/validations/user_validation.go +++ b/src/validations/user_validation.go @@ -21,6 +21,8 @@ func ValidateUserInfo(ctx context.Context, request domainUser.InfoRequest) error func ValidateUserAvatar(ctx context.Context, request domainUser.AvatarRequest) error { err := validation.ValidateStructWithContext(ctx, &request, validation.Field(&request.Phone, validation.Required), + validation.Field(&request.IsCommunity, validation.When(request.IsCommunity, validation.Required, validation.In(true, false))), + validation.Field(&request.IsPreview, validation.When(request.IsPreview, validation.Required, validation.In(true, false))), ) if err != nil { diff --git a/src/validations/user_validation_test.go b/src/validations/user_validation_test.go index 15f7751..95b7a16 100644 --- a/src/validations/user_validation_test.go +++ b/src/validations/user_validation_test.go @@ -20,14 +20,18 @@ func TestValidateUserAvatar(t *testing.T) { { name: "should success", args: args{request: domainUser.AvatarRequest{ - Phone: "1728937129312@s.whatsapp.net", + Phone: "1728937129312@s.whatsapp.net", + IsPreview: false, + IsCommunity: false, }}, err: nil, }, { name: "should error with empty phone", args: args{request: domainUser.AvatarRequest{ - Phone: "", + Phone: "", + IsPreview: false, + IsCommunity: false, }}, err: pkgError.ValidationError("phone: cannot be blank."), }, diff --git a/src/views/index.html b/src/views/index.html index 28f3d16..5719d69 100644 --- a/src/views/index.html +++ b/src/views/index.html @@ -599,6 +599,22 @@ +
+ +
+ + +
+
+ +
+ +
+ + +
+
+