diff --git a/docs/openapi.yaml b/docs/openapi.yaml index e94224b..155a5dd 100644 --- a/docs/openapi.yaml +++ b/docs/openapi.yaml @@ -1,7 +1,7 @@ openapi: 3.0.0 info: title: WhatsApp API MultiDevice - version: 3.5.0 + version: 3.6.0 description: This API is used for sending whatsapp via API servers: - url: http://localhost:3000 @@ -627,6 +627,40 @@ paths: application/json: schema: $ref: '#/components/schemas/ErrorInternalServer' + /group/leave: + post: + operationId: leaveGroup + tags: + - group + summary: Leave group + requestBody: + content: + multipart/form-data: + schema: + type: object + properties: + group_id: + type: string + example: '120363024512399999@g.us' + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/GenericResponse' + '400': + description: Bad Request + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + '500': + description: Internal Server Error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternalServer' components: schemas: @@ -854,7 +888,7 @@ components: description: 'HTTP Status Code' message: type: string - example: phone cannot be blank + example: field cannot be blank description: 'Detail error message' results: type: object diff --git a/readme.md b/readme.md index cd10bf9..605519b 100644 --- a/readme.md +++ b/readme.md @@ -112,6 +112,7 @@ API using [openapi-generator](https://openapi-generator.tech/#try) | ✅ | Revoke Message | POST | /message/:message_id/revoke | | ✅ | React Message | POST | /message/:message_id/react | | ✅ | Join Group With Link | POST | /group/join-with-link | +| ✅ | Leave Group | POST | /group/leave | ``` ✅ = Available @@ -120,7 +121,7 @@ API using [openapi-generator](https://openapi-generator.tech/#try) ### App User Interface -1. Homepage ![Homepage](https://i.ibb.co/Gn32yhJ/homepage.png) +1. Homepage ![Homepage](https://i.ibb.co/vPpnVdg/homepage.png) 2. Login ![Login](https://i.ibb.co/jkcB15R/login.png) 3. Send Message ![Send Message](https://i.ibb.co/rc3NXMX/send-message.png) 4. Send Image ![Send Image](https://i.ibb.co/BcFL3SD/send-image.png) @@ -133,7 +134,7 @@ API using [openapi-generator](https://openapi-generator.tech/#try) 11. User Info ![User Info](https://i.ibb.co/3zjX6Cz/user-info.png) 12. User Avatar ![User Avatar](https://i.ibb.co/ZmJZ4ZW/search-avatar.png) 13. My Privacy ![My Privacy](https://i.ibb.co/Cw1sMQz/my-privacy.png) -14. My Group ![My Group](https://i.ibb.co/B6rW8Sh/list-group.png) +14. My Group ![My Group](https://i.ibb.co/WB268Xy/list-group.png) 15. Auto Reply ![Auto Reply](https://i.ibb.co/D4rTytX/IMG-20220517-162500.jpg) 16. Basic Auth Prompt ![Basic Auth](https://i.ibb.co/PDjQ92W/Screenshot-2022-11-06-at-14-06-29.png) diff --git a/src/config/settings.go b/src/config/settings.go index db687c0..d5a66f4 100644 --- a/src/config/settings.go +++ b/src/config/settings.go @@ -6,7 +6,7 @@ import ( ) var ( - AppVersion = "v4.6.2" + AppVersion = "v4.7.0" AppPort = "3000" AppDebug = false AppOs = fmt.Sprintf("AldinoKemal") diff --git a/src/domains/group/group.go b/src/domains/group/group.go index ffe5d40..33a6c9b 100644 --- a/src/domains/group/group.go +++ b/src/domains/group/group.go @@ -3,13 +3,14 @@ package group import "context" type IGroupService interface { - JoinGroupWithLink(ctx context.Context, request JoinGroupWithLinkRequest) (response JoinGroupWithLinkResponse, err error) + JoinGroupWithLink(ctx context.Context, request JoinGroupWithLinkRequest) (groupID string, err error) + LeaveGroup(ctx context.Context, request LeaveGroupRequest) (err error) } type JoinGroupWithLinkRequest struct { Link string `json:"link" form:"link"` } -type JoinGroupWithLinkResponse struct { - JID string `json:"jid"` +type LeaveGroupRequest struct { + GroupID string `json:"group_id" form:"group_id"` } diff --git a/src/go.mod b/src/go.mod index 1ec1090..2ce2a82 100644 --- a/src/go.mod +++ b/src/go.mod @@ -16,9 +16,9 @@ require ( github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e github.com/spf13/cobra v1.7.0 github.com/stretchr/testify v1.8.2 - github.com/valyala/fasthttp v1.46.0 + github.com/valyala/fasthttp v1.47.0 go.mau.fi/libsignal v0.1.0 - go.mau.fi/whatsmeow v0.0.0-20230421200254-eb71a6b59083 + go.mau.fi/whatsmeow v0.0.0-20230427180258-7f679583b39b google.golang.org/protobuf v1.30.0 ) @@ -27,7 +27,7 @@ require ( github.com/andybalholm/brotli v1.0.5 // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/fasthttp/websocket v1.5.2 // indirect + github.com/fasthttp/websocket v1.5.3 // indirect github.com/gobuffalo/here v0.6.7 // indirect github.com/gorilla/websocket v1.5.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect @@ -45,7 +45,7 @@ require ( github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/tcplisten v1.0.0 // indirect golang.org/x/crypto v0.8.0 // indirect - golang.org/x/sys v0.7.0 // indirect + golang.org/x/sys v0.8.0 // indirect golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/src/go.sum b/src/go.sum index b7a2b41..883a3a3 100644 --- a/src/go.sum +++ b/src/go.sum @@ -120,8 +120,8 @@ github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go. github.com/envoyproxy/go-control-plane v0.10.1/go.mod h1:AY7fTTXNdv/aJ2O5jwpxAPOWUZ7hQAEvzN5Pf27BkQQ= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v0.6.2/go.mod h1:2t7qjJNvHPx8IjnBOzl9E9/baC+qXE/TeeyBRzgJDws= -github.com/fasthttp/websocket v1.5.2 h1:KdCb0EpLpdJpfE3IPA5YLK/aYBO3dhZcvwxz6tXe2LQ= -github.com/fasthttp/websocket v1.5.2/go.mod h1:S0KC1VBlx1SaXGXq7yi1wKz4jMub58qEnHQG9oHuqBw= +github.com/fasthttp/websocket v1.5.3 h1:TPpQuLwJYfd4LJPXvHDYPMFWbLjsT91n3GpWtCQtdek= +github.com/fasthttp/websocket v1.5.3/go.mod h1:46gg/UBmTU1kUaTcwQXpUxtRwG2PvIZYeA8oL6vF3Fs= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= @@ -407,8 +407,8 @@ github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqri github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.45.0/go.mod h1:k2zXd82h/7UZc3VOdJ2WaUqt1uZ/XpXAfE9i+HBC3lA= -github.com/valyala/fasthttp v1.46.0 h1:6ZRhrFg8zBXTRYY6vdzbFhqsBd7FVv123pV2m9V87U4= -github.com/valyala/fasthttp v1.46.0/go.mod h1:k2zXd82h/7UZc3VOdJ2WaUqt1uZ/XpXAfE9i+HBC3lA= +github.com/valyala/fasthttp v1.47.0 h1:y7moDoxYzMooFpT5aHgNgVOQDrS3qlkfiP9mDtGGK9c= +github.com/valyala/fasthttp v1.47.0/go.mod h1:k2zXd82h/7UZc3VOdJ2WaUqt1uZ/XpXAfE9i+HBC3lA= github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8= github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= github.com/yosssi/ace v0.0.5/go.mod h1:ALfIzm2vT7t5ZE7uoIZqF3TQ7SAOyupFZnkrF5id+K0= @@ -424,8 +424,8 @@ go.etcd.io/etcd/client/pkg/v3 v3.5.1/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3 go.etcd.io/etcd/client/v2 v2.305.1/go.mod h1:pMEacxZW7o8pg4CrFE7pquyCJJzZvkvdD2RibOCCCGs= go.mau.fi/libsignal v0.1.0 h1:vAKI/nJ5tMhdzke4cTK1fb0idJzz1JuEIpmjprueC+c= go.mau.fi/libsignal v0.1.0/go.mod h1:R8ovrTezxtUNzCQE5PH30StOQWWeBskBsWE55vMfY9I= -go.mau.fi/whatsmeow v0.0.0-20230421200254-eb71a6b59083 h1:9m92f4MviAPv/PQgLZ7AO0E15goh/4B8uzvS3kyDpeg= -go.mau.fi/whatsmeow v0.0.0-20230421200254-eb71a6b59083/go.mod h1:+ObGpFE6cbbY4hKc1FmQH9MVfqaemmlXGXSnwDvCOyE= +go.mau.fi/whatsmeow v0.0.0-20230427180258-7f679583b39b h1:VSSc37LfKMt7HYeu9NibbSRwELFN5wc/hreGyY+z+o4= +go.mau.fi/whatsmeow v0.0.0-20230427180258-7f679583b39b/go.mod h1:+ObGpFE6cbbY4hKc1FmQH9MVfqaemmlXGXSnwDvCOyE= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -641,8 +641,9 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= diff --git a/src/internal/rest/group.go b/src/internal/rest/group.go index 1583bfa..1d7f2d9 100644 --- a/src/internal/rest/group.go +++ b/src/internal/rest/group.go @@ -13,6 +13,7 @@ type Group struct { func InitRestGroup(app *fiber.App, service domainGroup.IGroupService) Group { rest := Group{Service: service} app.Post("/group/join-with-link", rest.JoinGroupWithLink) + app.Post("/group/leave", rest.LeaveGroup) return rest } @@ -28,6 +29,23 @@ func (controller *Group) JoinGroupWithLink(c *fiber.Ctx) error { Status: 200, Code: "SUCCESS", Message: "Success joined group", - Results: response, + Results: map[string]string{ + "group_id": response, + }, + }) +} + +func (controller *Group) LeaveGroup(c *fiber.Ctx) error { + var request domainGroup.LeaveGroupRequest + err := c.BodyParser(&request) + utils.PanicIfNeeded(err) + + err = controller.Service.LeaveGroup(c.UserContext(), request) + utils.PanicIfNeeded(err) + + return c.JSON(utils.ResponseData{ + Status: 200, + Code: "SUCCESS", + Message: "Success leave group", }) } diff --git a/src/pkg/whatsapp/whatsapp.go b/src/pkg/whatsapp/whatsapp.go index f372f53..92c776c 100644 --- a/src/pkg/whatsapp/whatsapp.go +++ b/src/pkg/whatsapp/whatsapp.go @@ -98,9 +98,9 @@ func ParseJID(arg string) (types.JID, error) { } } -func ValidateJidWithLogin(waCli *whatsmeow.Client, phone string) (types.JID, error) { +func ValidateJidWithLogin(waCli *whatsmeow.Client, jid string) (types.JID, error) { MustLogin(waCli) - return ParseJID(phone) + return ParseJID(jid) } func InitWaDB() *sqlstore.Container { diff --git a/src/services/group.go b/src/services/group.go index f5db6aa..ba57f68 100644 --- a/src/services/group.go +++ b/src/services/group.go @@ -4,6 +4,7 @@ import ( "context" domainGroup "github.com/aldinokemal/go-whatsapp-web-multidevice/domains/group" "github.com/aldinokemal/go-whatsapp-web-multidevice/pkg/whatsapp" + "github.com/aldinokemal/go-whatsapp-web-multidevice/validations" "go.mau.fi/whatsmeow" ) @@ -17,13 +18,28 @@ func NewGroupService(waCli *whatsmeow.Client) domainGroup.IGroupService { } } -func (service groupService) JoinGroupWithLink(_ context.Context, request domainGroup.JoinGroupWithLinkRequest) (response domainGroup.JoinGroupWithLinkResponse, err error) { +func (service groupService) JoinGroupWithLink(ctx context.Context, request domainGroup.JoinGroupWithLinkRequest) (groupID string, err error) { + if err = validations.ValidateJoinGroupWithLink(ctx, request); err != nil { + return groupID, err + } whatsapp.MustLogin(service.WaCli) jid, err := service.WaCli.JoinGroupWithLink(request.Link) if err != nil { return } - response.JID = jid.String() - return response, nil + return jid.String(), nil +} + +func (service groupService) LeaveGroup(ctx context.Context, request domainGroup.LeaveGroupRequest) (err error) { + if err = validations.ValidateLeaveGroup(ctx, request); err != nil { + return err + } + + JID, err := whatsapp.ValidateJidWithLogin(service.WaCli, request.GroupID) + if err != nil { + return err + } + + return service.WaCli.LeaveGroup(JID) } diff --git a/src/validations/group_validation.go b/src/validations/group_validation.go new file mode 100644 index 0000000..35d35b6 --- /dev/null +++ b/src/validations/group_validation.go @@ -0,0 +1,32 @@ +package validations + +import ( + "context" + domainGroup "github.com/aldinokemal/go-whatsapp-web-multidevice/domains/group" + pkgError "github.com/aldinokemal/go-whatsapp-web-multidevice/pkg/error" + validation "github.com/go-ozzo/ozzo-validation/v4" +) + +func ValidateJoinGroupWithLink(ctx context.Context, request domainGroup.JoinGroupWithLinkRequest) error { + err := validation.ValidateStructWithContext(ctx, &request, + validation.Field(&request.Link, validation.Required), + ) + + if err != nil { + return pkgError.ValidationError(err.Error()) + } + + return nil +} + +func ValidateLeaveGroup(ctx context.Context, request domainGroup.LeaveGroupRequest) error { + err := validation.ValidateStructWithContext(ctx, &request, + validation.Field(&request.GroupID, validation.Required), + ) + + if err != nil { + return pkgError.ValidationError(err.Error()) + } + + return nil +} diff --git a/src/views/index.html b/src/views/index.html index a0bb810..600378c 100644 --- a/src/views/index.html +++ b/src/views/index.html @@ -15,7 +15,7 @@ - Whatsapp Web Multi + Whatsapp API Multi Device {{ .AppVersion }}