Browse Source

feat: add avatar preview and community

pull/45/head
Aldino Kemal 3 years ago
parent
commit
10976dfac2
  1. 4
      src/domains/user/account.go
  2. 11
      src/internal/rest/user.go
  3. 17
      src/pkg/error/generic_error.go
  4. 64
      src/services/user.go
  5. 2
      src/validations/user_validation.go
  6. 8
      src/validations/user_validation_test.go
  7. 20
      src/views/index.html

4
src/domains/user/account.go

@ -26,7 +26,9 @@ type InfoResponse struct {
} }
type AvatarRequest 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 { type AvatarResponse struct {

11
src/internal/rest/user.go

@ -21,13 +21,6 @@ func InitRestUser(app *fiber.App, service domainUser.IUserService) User {
return rest 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 { func (controller *User) UserInfo(c *fiber.Ctx) error {
var request domainUser.InfoRequest var request domainUser.InfoRequest
err := c.QueryParser(&request) err := c.QueryParser(&request)
@ -35,7 +28,7 @@ func (controller *User) UserInfo(c *fiber.Ctx) error {
whatsapp.SanitizePhone(&request.Phone) whatsapp.SanitizePhone(&request.Phone)
response, err := controller.Service.Info(c.Context(), request)
response, err := controller.Service.Info(c.UserContext(), request)
utils.PanicIfNeeded(err) utils.PanicIfNeeded(err)
return c.JSON(utils.ResponseData{ return c.JSON(utils.ResponseData{
@ -52,7 +45,7 @@ func (controller *User) UserAvatar(c *fiber.Ctx) error {
whatsapp.SanitizePhone(&request.Phone) whatsapp.SanitizePhone(&request.Phone)
response, err := controller.Service.Avatar(c.Context(), request)
response, err := controller.Service.Avatar(c.UserContext(), request)
utils.PanicIfNeeded(err) utils.PanicIfNeeded(err)
return c.JSON(utils.ResponseData{ return c.JSON(utils.ResponseData{

17
src/pkg/error/generic_error.go

@ -25,3 +25,20 @@ func (e InternalServerError) ErrCode() string {
func (e InternalServerError) StatusCode() int { func (e InternalServerError) StatusCode() int {
return http.StatusInternalServerError 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
}

64
src/services/user.go

@ -5,10 +5,12 @@ import (
"errors" "errors"
"fmt" "fmt"
domainUser "github.com/aldinokemal/go-whatsapp-web-multidevice/domains/user" 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/pkg/whatsapp"
"github.com/aldinokemal/go-whatsapp-web-multidevice/validations" "github.com/aldinokemal/go-whatsapp-web-multidevice/validations"
"go.mau.fi/whatsmeow" "go.mau.fi/whatsmeow"
"go.mau.fi/whatsmeow/types" "go.mau.fi/whatsmeow/types"
"time"
) )
type userService struct { 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) { 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) { func (service userService) MyListGroups(_ context.Context) (response domainUser.MyListGroupsResponse, err error) {

2
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 { func ValidateUserAvatar(ctx context.Context, request domainUser.AvatarRequest) error {
err := validation.ValidateStructWithContext(ctx, &request, err := validation.ValidateStructWithContext(ctx, &request,
validation.Field(&request.Phone, validation.Required), 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 { if err != nil {

8
src/validations/user_validation_test.go

@ -20,14 +20,18 @@ func TestValidateUserAvatar(t *testing.T) {
{ {
name: "should success", name: "should success",
args: args{request: domainUser.AvatarRequest{ args: args{request: domainUser.AvatarRequest{
Phone: "1728937129312@s.whatsapp.net",
Phone: "1728937129312@s.whatsapp.net",
IsPreview: false,
IsCommunity: false,
}}, }},
err: nil, err: nil,
}, },
{ {
name: "should error with empty phone", name: "should error with empty phone",
args: args{request: domainUser.AvatarRequest{ args: args{request: domainUser.AvatarRequest{
Phone: "",
Phone: "",
IsPreview: false,
IsCommunity: false,
}}, }},
err: pkgError.ValidationError("phone: cannot be blank."), err: pkgError.ValidationError("phone: cannot be blank."),
}, },

20
src/views/index.html

@ -599,6 +599,22 @@
<input :value="avatar_phone_id" disabled aria-label="whatsapp_id"> <input :value="avatar_phone_id" disabled aria-label="whatsapp_id">
</div> </div>
<div class="field">
<label>Preview</label>
<div class="ui toggle checkbox">
<input type="checkbox" aria-label="compress" v-model="avatar_is_preview">
<label>Check for small size image</label>
</div>
</div>
<div class="field">
<label>Community</label>
<div class="ui toggle checkbox">
<input type="checkbox" aria-label="compress" v-model="avatar_is_community">
<label>Check is it's community image</label>
</div>
</div>
<button type="button" class="ui primary button" :class="{'loading': avatar_loading}" <button type="button" class="ui primary button" :class="{'loading': avatar_loading}"
@click="avatarProcess"> @click="avatarProcess">
Search Search
@ -1305,6 +1321,8 @@
avatar_phone: '', avatar_phone: '',
avatar_image: null, avatar_image: null,
avatar_loading: false, avatar_loading: false,
avatar_is_preview: false,
avatar_is_community: false,
} }
}, },
computed: { computed: {
@ -1331,7 +1349,7 @@
avatarApi() { avatarApi() {
return new Promise(async (resolve, reject) => { return new Promise(async (resolve, reject) => {
try { try {
let response = await http.get(`/user/avatar?phone=${this.avatar_phone_id}`)
let response = await http.get(`/user/avatar?phone=${this.avatar_phone_id}&is_preview=${this.avatar_is_preview}&is_community=${this.avatar_is_community}`)
this.avatar_image = response.data.results.url; this.avatar_image = response.data.results.url;
resolve() resolve()
} catch (error) { } catch (error) {

Loading…
Cancel
Save