From e995a0ef9050c65aeddcabc42c31f7ed5a93fbf2 Mon Sep 17 00:00:00 2001 From: Aldino Kemal Date: Tue, 9 Apr 2024 08:00:01 +0700 Subject: [PATCH] feat: add group participant api --- src/config/settings.go | 2 +- src/domains/group/group.go | 12 +++++ src/internal/rest/group.go | 20 +++++++++ src/pkg/whatsapp/whatsapp.go | 3 -- src/services/group.go | 70 ++++++++++++++++++++++++----- src/validations/group_validation.go | 14 ++++++ 6 files changed, 106 insertions(+), 15 deletions(-) diff --git a/src/config/settings.go b/src/config/settings.go index 0538c16..6e40818 100644 --- a/src/config/settings.go +++ b/src/config/settings.go @@ -5,7 +5,7 @@ import ( ) var ( - AppVersion = "v4.12.0" + AppVersion = "v4.13.0" AppPort = "3000" AppDebug = false AppOs = "AldinoKemal" diff --git a/src/domains/group/group.go b/src/domains/group/group.go index 689cce9..c89e4ed 100644 --- a/src/domains/group/group.go +++ b/src/domains/group/group.go @@ -6,6 +6,7 @@ type IGroupService interface { JoinGroupWithLink(ctx context.Context, request JoinGroupWithLinkRequest) (groupID string, err error) LeaveGroup(ctx context.Context, request LeaveGroupRequest) (err error) CreateGroup(ctx context.Context, request CreateGroupRequest) (groupID string, err error) + AddParticipant(ctx context.Context, request ParticipantRequest) (result []ParticipantStatus, err error) } type JoinGroupWithLinkRequest struct { @@ -20,3 +21,14 @@ type CreateGroupRequest struct { Title string `json:"title" form:"title"` Participants []string `json:"participants" form:"participants"` } + +type ParticipantRequest struct { + GroupID string `json:"group_id" form:"group_id"` + Participants []string `json:"participants" form:"participants"` +} + +type ParticipantStatus struct { + Participant string `json:"participant"` + Status string `json:"status"` + Message string `json:"message"` +} diff --git a/src/internal/rest/group.go b/src/internal/rest/group.go index 9edb2d7..7fc9078 100644 --- a/src/internal/rest/group.go +++ b/src/internal/rest/group.go @@ -4,6 +4,7 @@ import ( "fmt" domainGroup "github.com/aldinokemal/go-whatsapp-web-multidevice/domains/group" "github.com/aldinokemal/go-whatsapp-web-multidevice/pkg/utils" + "github.com/aldinokemal/go-whatsapp-web-multidevice/pkg/whatsapp" "github.com/gofiber/fiber/v2" ) @@ -16,6 +17,7 @@ func InitRestGroup(app *fiber.App, service domainGroup.IGroupService) Group { app.Post("/group", rest.CreateGroup) app.Post("/group/join-with-link", rest.JoinGroupWithLink) app.Post("/group/leave", rest.LeaveGroup) + app.Post("/group/participants", rest.AddParticipants) return rest } @@ -69,3 +71,21 @@ func (controller *Group) CreateGroup(c *fiber.Ctx) error { }, }) } + +func (controller *Group) AddParticipants(c *fiber.Ctx) error { + var request domainGroup.ParticipantRequest + err := c.BodyParser(&request) + utils.PanicIfNeeded(err) + + whatsapp.SanitizePhone(&request.GroupID) + + result, err := controller.Service.AddParticipant(c.UserContext(), request) + utils.PanicIfNeeded(err) + + return c.JSON(utils.ResponseData{ + Status: 200, + Code: "SUCCESS", + Message: "Success add participants", + Results: result, + }) +} diff --git a/src/pkg/whatsapp/whatsapp.go b/src/pkg/whatsapp/whatsapp.go index 139dc0b..97d0a66 100644 --- a/src/pkg/whatsapp/whatsapp.go +++ b/src/pkg/whatsapp/whatsapp.go @@ -233,9 +233,6 @@ func handler(rawEvt interface{}) { if evt.IsViewOnce { metaParts = append(metaParts, "view once") } - if evt.IsViewOnce { - metaParts = append(metaParts, "ephemeral") - } log.Infof("Received message %s from %s (%s): %+v", evt.Info.ID, evt.Info.SourceString(), strings.Join(metaParts, ", "), evt.Message) diff --git a/src/services/group.go b/src/services/group.go index c386639..3e096cb 100644 --- a/src/services/group.go +++ b/src/services/group.go @@ -53,17 +53,9 @@ func (service groupService) CreateGroup(ctx context.Context, request domainGroup } whatsapp.MustLogin(service.WaCli) - var participantsJID []types.JID - for _, participant := range request.Participants { - formattedParticipant := participant + config.WhatsappTypeUser - - if !whatsapp.IsOnWhatsapp(service.WaCli, formattedParticipant) { - return "", pkgError.ErrUserNotRegistered - } - - if participantJID, err := types.ParseJID(formattedParticipant); err == nil { - participantsJID = append(participantsJID, participantJID) - } + participantsJID, err := service.participantToJID(request.Participants) + if err != nil { + return } groupConfig := whatsmeow.ReqCreateGroup{ @@ -80,3 +72,59 @@ func (service groupService) CreateGroup(ctx context.Context, request domainGroup return groupInfo.JID.String(), nil } + +func (service groupService) AddParticipant(ctx context.Context, request domainGroup.ParticipantRequest) (result []domainGroup.ParticipantStatus, err error) { + if err = validations.ValidateParticipant(ctx, request); err != nil { + return result, err + } + whatsapp.MustLogin(service.WaCli) + + groupJID, err := whatsapp.ValidateJidWithLogin(service.WaCli, request.GroupID) + if err != nil { + return result, err + } + + participantsJID, err := service.participantToJID(request.Participants) + if err != nil { + return result, err + } + + participants, err := service.WaCli.UpdateGroupParticipants(groupJID, participantsJID, whatsmeow.ParticipantChangeAdd) + if err != nil { + return result, err + } + + for _, participant := range participants { + if participant.Error == 403 && participant.AddRequest != nil { + result = append(result, domainGroup.ParticipantStatus{ + Participant: participant.JID.String(), + Status: "error", + Message: "Failed to add participant", + }) + } else { + result = append(result, domainGroup.ParticipantStatus{ + Participant: participant.JID.String(), + Status: "success", + Message: "Participant added", + }) + } + } + + return result, nil +} + +func (service groupService) participantToJID(participants []string) ([]types.JID, error) { + var participantsJID []types.JID + for _, participant := range participants { + formattedParticipant := participant + config.WhatsappTypeUser + + if !whatsapp.IsOnWhatsapp(service.WaCli, formattedParticipant) { + return nil, pkgError.ErrUserNotRegistered + } + + if participantJID, err := types.ParseJID(formattedParticipant); err == nil { + participantsJID = append(participantsJID, participantJID) + } + } + return participantsJID, nil +} diff --git a/src/validations/group_validation.go b/src/validations/group_validation.go index 69742e5..0758c1f 100644 --- a/src/validations/group_validation.go +++ b/src/validations/group_validation.go @@ -44,3 +44,17 @@ func ValidateCreateGroup(ctx context.Context, request domainGroup.CreateGroupReq return nil } + +func ValidateParticipant(ctx context.Context, request domainGroup.ParticipantRequest) error { + err := validation.ValidateStructWithContext(ctx, &request, + validation.Field(&request.GroupID, validation.Required), + validation.Field(&request.Participants, validation.Required), + validation.Field(&request.Participants, validation.Each(validation.Required)), + ) + + if err != nil { + return pkgError.ValidationError(err.Error()) + } + + return nil +}