You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

233 lines
5.7 KiB

package services
import (
"bytes"
"context"
"errors"
"fmt"
"image"
"time"
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"
"github.com/disintegration/imaging"
"go.mau.fi/whatsmeow"
"go.mau.fi/whatsmeow/types"
)
type userService struct {
WaCli *whatsmeow.Client
}
func NewUserService(waCli *whatsmeow.Client) domainUser.IUserService {
return &userService{
WaCli: waCli,
}
}
func (service userService) Info(ctx context.Context, request domainUser.InfoRequest) (response domainUser.InfoResponse, err error) {
err = validations.ValidateUserInfo(ctx, request)
if err != nil {
return response, err
}
var jids []types.JID
dataWaRecipient, err := whatsapp.ValidateJidWithLogin(service.WaCli, request.Phone)
if err != nil {
return response, err
}
jids = append(jids, dataWaRecipient)
resp, err := service.WaCli.GetUserInfo(jids)
if err != nil {
return response, err
}
for _, userInfo := range resp {
var device []domainUser.InfoResponseDataDevice
for _, j := range userInfo.Devices {
device = append(device, domainUser.InfoResponseDataDevice{
User: j.User,
Agent: j.RawAgent,
Device: whatsapp.GetPlatformName(int(j.Device)),
Server: j.Server,
AD: j.ADString(),
})
}
data := domainUser.InfoResponseData{
Status: userInfo.Status,
PictureID: userInfo.PictureID,
Devices: device,
}
if userInfo.VerifiedName != nil {
data.VerifiedName = fmt.Sprintf("%v", *userInfo.VerifiedName)
}
response.Data = append(response.Data, data)
}
return response, nil
}
func (service userService) Avatar(ctx context.Context, request domainUser.AvatarRequest) (response domainUser.AvatarResponse, err error) {
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) {
whatsapp.MustLogin(service.WaCli)
groups, err := service.WaCli.GetJoinedGroups()
if err != nil {
return
}
fmt.Printf("%+v\n", groups)
for _, group := range groups {
response.Data = append(response.Data, *group)
}
return response, nil
}
func (service userService) MyListNewsletter(_ context.Context) (response domainUser.MyListNewsletterResponse, err error) {
whatsapp.MustLogin(service.WaCli)
datas, err := service.WaCli.GetSubscribedNewsletters()
if err != nil {
return
}
fmt.Printf("%+v\n", datas)
for _, data := range datas {
response.Data = append(response.Data, *data)
}
return response, nil
}
func (service userService) MyPrivacySetting(_ context.Context) (response domainUser.MyPrivacySettingResponse, err error) {
whatsapp.MustLogin(service.WaCli)
resp, err := service.WaCli.TryFetchPrivacySettings(true)
if err != nil {
return
}
response.GroupAdd = string(resp.GroupAdd)
response.Status = string(resp.Status)
response.ReadReceipts = string(resp.ReadReceipts)
response.Profile = string(resp.Profile)
return response, nil
}
func (service userService) MyListContacts(ctx context.Context) (response domainUser.MyListContactsResponse, err error) {
whatsapp.MustLogin(service.WaCli)
contacts, err := service.WaCli.Store.Contacts.GetAllContacts()
if err != nil {
return
}
for jid, contact := range contacts {
response.Data = append(response.Data, domainUser.MyListContactsResponseData{
JID: jid,
Name: contact.FullName,
})
}
return response, nil
}
func (service userService) ChangeAvatar(ctx context.Context, request domainUser.ChangeAvatarRequest) (err error) {
whatsapp.MustLogin(service.WaCli)
file, err := request.Avatar.Open()
if err != nil {
return err
}
defer file.Close()
// Read original image
srcImage, err := imaging.Decode(file)
if err != nil {
return fmt.Errorf("failed to decode image: %v", err)
}
// Get original dimensions
bounds := srcImage.Bounds()
width := bounds.Dx()
height := bounds.Dy()
// Calculate new dimensions for 1:1 aspect ratio
size := width
if height < width {
size = height
}
if size > 640 {
size = 640
}
// Create a square crop from the center
left := (width - size) / 2
top := (height - size) / 2
croppedImage := imaging.Crop(srcImage, image.Rect(left, top, left+size, top+size))
// Resize if needed
if size > 640 {
croppedImage = imaging.Resize(croppedImage, 640, 640, imaging.Lanczos)
}
// Convert to bytes
var buf bytes.Buffer
err = imaging.Encode(&buf, croppedImage, imaging.JPEG, imaging.JPEGQuality(80))
if err != nil {
return fmt.Errorf("failed to encode image: %v", err)
}
_, err = service.WaCli.SetGroupPhoto(types.JID{}, buf.Bytes())
if err != nil {
return err
}
return nil
}