From 558983f9c75d2ed757435c4dd36318c8256727ab Mon Sep 17 00:00:00 2001 From: Aldino Kemal Date: Sat, 13 Jul 2024 21:49:37 +0700 Subject: [PATCH] feat: manage participant --- readme.md | 7 +- src/config/settings.go | 2 +- src/domains/group/group.go | 12 ++-- src/internal/rest/group.go | 68 +++++++++++++++++- src/pkg/whatsapp/whatsapp.go | 11 +-- src/services/group.go | 6 +- ...icipants.js => GroupManageParticipants.js} | 69 +++++++++++++------ src/views/index.html | 2 +- 8 files changed, 140 insertions(+), 37 deletions(-) rename src/views/components/{GroupAddParticipants.js => GroupManageParticipants.js} (65%) diff --git a/readme.md b/readme.md index efc4f54..519c047 100644 --- a/readme.md +++ b/readme.md @@ -121,13 +121,14 @@ You can fork or edit this source code ! | ✅ | React Message | POST | /message/:message_id/reaction | | ✅ | Delete Message | POST | /message/:message_id/delete | | ✅ | Edit Message | POST | /message/:message_id/update | +| ❌ | Star message | POST | /message/:message_id/star | | ✅ | Join Group With Link | POST | /group/join-with-link | | ✅ | Leave Group | POST | /group/leave | | ✅ | Create Group | POST | /group | | ✅ | Add Participants in Group | POST | /group/participants | -| ❌ | Remove Participant in Group | DELETE | /group/participants | -| ❌ | Promote Participant in Group | POST | /group/participants/promote | -| ❌ | Demote Participant in Group | POST | /group/participants/demote | +| ✅ | Remove Participant in Group | DELETE | /group/participants | +| ✅ | Promote Participant in Group | PATCH | /group/participants/promote | +| ✅ | Demote Participant in Group | PATCH | /group/participants/demote | ``` ✅ = Available diff --git a/src/config/settings.go b/src/config/settings.go index 7f41dd1..35d72b7 100644 --- a/src/config/settings.go +++ b/src/config/settings.go @@ -5,7 +5,7 @@ import ( ) var ( - AppVersion = "v4.14.2" + AppVersion = "v4.15.0" AppPort = "3000" AppDebug = false AppOs = "AldinoKemal" diff --git a/src/domains/group/group.go b/src/domains/group/group.go index c89e4ed..59d6764 100644 --- a/src/domains/group/group.go +++ b/src/domains/group/group.go @@ -1,12 +1,15 @@ package group -import "context" +import ( + "context" + "go.mau.fi/whatsmeow" +) 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) + ManageParticipant(ctx context.Context, request ParticipantRequest) (result []ParticipantStatus, err error) } type JoinGroupWithLinkRequest struct { @@ -23,8 +26,9 @@ type CreateGroupRequest struct { } type ParticipantRequest struct { - GroupID string `json:"group_id" form:"group_id"` - Participants []string `json:"participants" form:"participants"` + GroupID string `json:"group_id" form:"group_id"` + Participants []string `json:"participants" form:"participants"` + Action whatsmeow.ParticipantChange `json:"action" form:"action"` } type ParticipantStatus struct { diff --git a/src/internal/rest/group.go b/src/internal/rest/group.go index 95ccef6..c048681 100644 --- a/src/internal/rest/group.go +++ b/src/internal/rest/group.go @@ -6,6 +6,7 @@ import ( "github.com/aldinokemal/go-whatsapp-web-multidevice/pkg/utils" "github.com/aldinokemal/go-whatsapp-web-multidevice/pkg/whatsapp" "github.com/gofiber/fiber/v2" + "go.mau.fi/whatsmeow" ) type Group struct { @@ -18,6 +19,9 @@ func InitRestGroup(app *fiber.App, service domainGroup.IGroupService) Group { app.Post("/group/join-with-link", rest.JoinGroupWithLink) app.Post("/group/leave", rest.LeaveGroup) app.Post("/group/participants", rest.AddParticipants) + app.Delete("/group/participants", rest.DeleteParticipants) + app.Patch("/group/participants/promote", rest.PromoteParticipants) + app.Patch("/group/participants/demote", rest.DemoteParticipants) return rest } @@ -81,7 +85,9 @@ func (controller *Group) AddParticipants(c *fiber.Ctx) error { whatsapp.SanitizePhone(&request.GroupID) - result, err := controller.Service.AddParticipant(c.UserContext(), request) + request.Action = whatsmeow.ParticipantChangeAdd + + result, err := controller.Service.ManageParticipant(c.UserContext(), request) utils.PanicIfNeeded(err) return c.JSON(utils.ResponseData{ @@ -91,3 +97,63 @@ func (controller *Group) AddParticipants(c *fiber.Ctx) error { Results: result, }) } + +func (controller *Group) DeleteParticipants(c *fiber.Ctx) error { + var request domainGroup.ParticipantRequest + err := c.BodyParser(&request) + utils.PanicIfNeeded(err) + + whatsapp.SanitizePhone(&request.GroupID) + + request.Action = whatsmeow.ParticipantChangeRemove + + result, err := controller.Service.ManageParticipant(c.UserContext(), request) + utils.PanicIfNeeded(err) + + return c.JSON(utils.ResponseData{ + Status: 200, + Code: "SUCCESS", + Message: "Success delete participants", + Results: result, + }) +} + +func (controller *Group) PromoteParticipants(c *fiber.Ctx) error { + var request domainGroup.ParticipantRequest + err := c.BodyParser(&request) + utils.PanicIfNeeded(err) + + whatsapp.SanitizePhone(&request.GroupID) + + request.Action = whatsmeow.ParticipantChangePromote + + result, err := controller.Service.ManageParticipant(c.UserContext(), request) + utils.PanicIfNeeded(err) + + return c.JSON(utils.ResponseData{ + Status: 200, + Code: "SUCCESS", + Message: "Success promote participants", + Results: result, + }) +} + +func (controller *Group) DemoteParticipants(c *fiber.Ctx) error { + var request domainGroup.ParticipantRequest + err := c.BodyParser(&request) + utils.PanicIfNeeded(err) + + whatsapp.SanitizePhone(&request.GroupID) + + request.Action = whatsmeow.ParticipantChangeDemote + + result, err := controller.Service.ManageParticipant(c.UserContext(), request) + utils.PanicIfNeeded(err) + + return c.JSON(utils.ResponseData{ + Status: 200, + Code: "SUCCESS", + Message: "Success demote participants", + Results: result, + }) +} diff --git a/src/pkg/whatsapp/whatsapp.go b/src/pkg/whatsapp/whatsapp.go index 949c6a6..5fc2fcd 100644 --- a/src/pkg/whatsapp/whatsapp.go +++ b/src/pkg/whatsapp/whatsapp.go @@ -458,11 +458,14 @@ func ExtractMedia(storageLocation string, mediaFile whatsmeow.DownloadableMessag extractedMedia.Caption = media.GetCaption() } - extensions, err := mime.ExtensionsByType(extractedMedia.MimeType) - if err != nil { - return extractedMedia, err + var extension string + if ext, err := mime.ExtensionsByType(extractedMedia.MimeType); err != nil && len(ext) > 0 { + extension = ext[0] + } else if parts := strings.Split(extractedMedia.MimeType, "/"); len(parts) > 1 { + extension = "." + parts[len(parts)-1] } - extractedMedia.MediaPath = fmt.Sprintf("%s/%d-%s%s", storageLocation, time.Now().Unix(), uuid.NewString(), extensions[0]) + + extractedMedia.MediaPath = fmt.Sprintf("%s/%d-%s%s", storageLocation, time.Now().Unix(), uuid.NewString(), extension) err = os.WriteFile(extractedMedia.MediaPath, data, 0600) if err != nil { return extractedMedia, err diff --git a/src/services/group.go b/src/services/group.go index 3e096cb..afe2aa1 100644 --- a/src/services/group.go +++ b/src/services/group.go @@ -73,7 +73,7 @@ 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) { +func (service groupService) ManageParticipant(ctx context.Context, request domainGroup.ParticipantRequest) (result []domainGroup.ParticipantStatus, err error) { if err = validations.ValidateParticipant(ctx, request); err != nil { return result, err } @@ -89,7 +89,7 @@ func (service groupService) AddParticipant(ctx context.Context, request domainGr return result, err } - participants, err := service.WaCli.UpdateGroupParticipants(groupJID, participantsJID, whatsmeow.ParticipantChangeAdd) + participants, err := service.WaCli.UpdateGroupParticipants(groupJID, participantsJID, request.Action) if err != nil { return result, err } @@ -105,7 +105,7 @@ func (service groupService) AddParticipant(ctx context.Context, request domainGr result = append(result, domainGroup.ParticipantStatus{ Participant: participant.JID.String(), Status: "success", - Message: "Participant added", + Message: "Action success", }) } } diff --git a/src/views/components/GroupAddParticipants.js b/src/views/components/GroupManageParticipants.js similarity index 65% rename from src/views/components/GroupAddParticipants.js rename to src/views/components/GroupManageParticipants.js index 4d272fc..059d2fa 100644 --- a/src/views/components/GroupAddParticipants.js +++ b/src/views/components/GroupManageParticipants.js @@ -1,48 +1,66 @@ export default { - name: 'AddParticipantsToGroup', + name: 'ManageGroupParticipants', data() { return { loading: false, group: '', + action: 'add', // add, remove, promote, demote participants: ['', ''], - } + }; }, computed: { group_id() { - return `${this.group}@${window.TYPEGROUP}` - } + return `${this.group}@${window.TYPEGROUP}`; + }, }, methods: { openModal() { $('#modalGroupAddParticipant').modal({ - onApprove: function () { + onApprove: function() { return false; - } + }, }).modal('show'); }, handleAddParticipant() { - this.participants.push('') + this.participants.push(''); }, handleDeleteParticipant(index) { - this.participants.splice(index, 1) + this.participants.splice(index, 1); }, async handleSubmit() { try { - let response = await this.submitApi() - showSuccessInfo(response) + let response = await this.submitApi(); + showSuccessInfo(response); $('#modalGroupAddParticipant').modal('hide'); } catch (err) { - showErrorInfo(err) + showErrorInfo(err); } }, async submitApi() { this.loading = true; try { - let response = await window.http.post(`/group/participants`, { + const payload = { group_id: this.group_id, // convert participant become list of string - participants: this.participants.filter(participant => participant !== '').map(participant => `${participant}`) - }) + participants: this.participants.filter(participant => participant !== '').map(participant => `${participant}`), + }; + + let response; + switch (this.action) { + case 'add': + response = await window.http.post(`/group/participants`, payload); + break; + case 'remove': + response = await window.http.delete(`/group/participants`, { data: payload }); + break; + case 'promote': + response = await window.http.patch(`/group/participants/promote`, payload); + break; + case 'demote': + response = await window.http.patch(`/group/participants/demote`, payload); + break; + } + this.handleReset(); return response.data.message; } catch (error) { @@ -56,6 +74,7 @@ export default { }, handleReset() { this.group = ''; + this.action = 'add'; this.participants = ['', '']; }, }, @@ -63,9 +82,9 @@ export default {
Group -
Add Participants
+
Manage Participants
- Add multiple participants + Add/Remove/Promote/Demote Participants
@@ -74,7 +93,7 @@ export default { + +
+ + +
- Create + Submit
- ` -} \ No newline at end of file + `, +}; \ No newline at end of file diff --git a/src/views/index.html b/src/views/index.html index 85140d7..cc01cc4 100644 --- a/src/views/index.html +++ b/src/views/index.html @@ -144,7 +144,7 @@

Whatsapp API Multi Device ({{ .AppVersion } import GroupList from "./components/GroupList.js"; import GroupCreate from "./components/GroupCreate.js"; import GroupJoinWithLink from "./components/GroupJoinWithLink.js"; - import GroupAddParticipants from "./components/GroupAddParticipants.js"; + import GroupAddParticipants from "./components/GroupManageParticipants.js"; import AccountAvatar from "./components/AccountAvatar.js"; import AccountUserInfo from "./components/AccountUserInfo.js"; import AccountPrivacy from "./components/AccountPrivacy.js";