diff --git a/.gitignore b/.gitignore index 5c7040f..0d20448 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,6 @@ main main.exe *.jpe src/pkged.go -storages \ No newline at end of file +storages +.tool-versions + diff --git a/readme.md b/readme.md index 4052b5c..4c40c1d 100644 --- a/readme.md +++ b/readme.md @@ -103,6 +103,14 @@ You can fork or edit this source code ! to [SwaggerEditor](https://editor.swagger.io). - Furthermore you can generate HTTP Client from this API using [openapi-generator](https://openapi-generator.tech/#try) +## CURL for the api + +#### You need to encode to Base64 your user:pass [basic-auth] and pass in header + +- curl -X 'GET' 'http://127.0.0.1:3000/user/check?phone=YOUR_PHONE' -H 'accept: application/json' \ +-H 'Authorization: Basic qwertyASDFzxc=' +- curl -X 'GET' 'http://127.0.0.1:3000/user/check?phone=YOUR_PHONE' -H 'accept: application/json' + | Feature | Menu | Method | URL | |---------|------------------------------|--------|-------------------------------| | ✅ | Login with Scan QR | GET | /app/login | @@ -111,6 +119,7 @@ You can fork or edit this source code ! | ✅ | Reconnect | GET | /app/reconnect | | ✅ | Devices | GET | /app/devices | | ✅ | User Info | GET | /user/info | +| ✅ | Check User is on whatsapp | GET | /user/check | | ✅ | User Avatar | GET | /user/avatar | | ✅ | User My Groups | GET | /user/my/groups | | ✅ | User My Newsletter | GET | /user/my/newsletters | @@ -164,6 +173,7 @@ You can fork or edit this source code ! | Reaction Message |  | | Edit Message |  | | User Info |  | +| Check User |  | | User Avatar |  | | My Privacy |  | | My Group |  | diff --git a/src/domains/user/account.go b/src/domains/user/account.go index d424755..45e9959 100644 --- a/src/domains/user/account.go +++ b/src/domains/user/account.go @@ -6,6 +6,10 @@ type InfoRequest struct { Phone string `json:"phone" query:"phone"` } +type CheckRequest struct { + Phone string `json:"phone" query:"phone"` +} + type InfoResponseDataDevice struct { User string Agent uint8 @@ -21,10 +25,25 @@ type InfoResponseData struct { Devices []InfoResponseDataDevice `json:"devices"` } +type CheckResponseData struct { + Query string `json:"query"` + IsInWhatsapp bool `json:"IsInWhatsapp"` + VerifiedName string `json:"verified_name"` + JID string `json:"jid"` +} + type InfoResponse struct { Data []InfoResponseData `json:"data"` } +type CheckResponse struct { + Data []CheckResponseData `json:"data"` +} + +type UserCollection struct { + Users []CheckResponseData +} + type AvatarRequest struct { Phone string `json:"phone" query:"phone"` IsPreview bool `json:"is_preview" query:"is_preview"` diff --git a/src/domains/user/user.go b/src/domains/user/user.go index feb3b78..453f6da 100644 --- a/src/domains/user/user.go +++ b/src/domains/user/user.go @@ -6,6 +6,7 @@ import ( type IUserService interface { Info(ctx context.Context, request InfoRequest) (response InfoResponse, err error) + Check(ctx context.Context, request CheckRequest) (response CheckResponse, err error) Avatar(ctx context.Context, request AvatarRequest) (response AvatarResponse, err error) MyListGroups(ctx context.Context) (response MyListGroupsResponse, err error) MyListNewsletter(ctx context.Context) (response MyListNewsletterResponse, err error) diff --git a/src/internal/rest/user.go b/src/internal/rest/user.go index 6621bb2..93d40b4 100644 --- a/src/internal/rest/user.go +++ b/src/internal/rest/user.go @@ -14,6 +14,7 @@ type User struct { func InitRestUser(app *fiber.App, service domainUser.IUserService) User { rest := User{Service: service} app.Get("/user/info", rest.UserInfo) + app.Get("/user/check", rest.UserCheck) app.Get("/user/avatar", rest.UserAvatar) app.Get("/user/my/privacy", rest.UserMyPrivacySetting) app.Get("/user/my/groups", rest.UserMyListGroups) @@ -40,6 +41,25 @@ func (controller *User) UserInfo(c *fiber.Ctx) error { }) } +func (controller *User) UserCheck(c *fiber.Ctx) error { + var request domainUser.CheckRequest + err := c.QueryParser(&request) + utils.PanicIfNeeded(err) + + whatsapp.SanitizePhone(&request.Phone) + + response, err := controller.Service.Check(c.UserContext(), request) + utils.PanicIfNeeded(err) + + return c.JSON(utils.ResponseData{ + Status: 200, + Code: "SUCCESS", + Message: "Success get user info", + Results: response.Data[0], + }) +} + + func (controller *User) UserAvatar(c *fiber.Ctx) error { var request domainUser.AvatarRequest err := c.QueryParser(&request) diff --git a/src/services/user.go b/src/services/user.go index 19d0652..3361b47 100644 --- a/src/services/user.go +++ b/src/services/user.go @@ -66,6 +66,41 @@ func (service userService) Info(ctx context.Context, request domainUser.InfoRequ return response, nil } +func (service userService) Check(ctx context.Context, request domainUser.CheckRequest) (response domainUser.CheckResponse, err error) { + err = validations.ValidateUserCheck(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.IsOnWhatsApp([]string{request.Phone}) + if err != nil { + return response, err + } + + uc := new(domainUser.UserCollection) + for _, item := range resp { + if item.VerifiedName != nil { + var msg = domainUser.CheckResponseData{Query: item.Query, IsInWhatsapp: item.IsIn, JID: fmt.Sprintf("%s", item.JID), VerifiedName: item.VerifiedName.Details.GetVerifiedName()} + uc.Users = append(uc.Users, msg) + } else { + var msg = domainUser.CheckResponseData{Query: item.Query, IsInWhatsapp: item.IsIn, JID: fmt.Sprintf("%s", item.JID), VerifiedName: ""} + uc.Users = append(uc.Users, msg) + } + } + + response.Data = append(response.Data, uc.Users[0]) + // response := string(responseJson) + + return response, err +} + func (service userService) Avatar(ctx context.Context, request domainUser.AvatarRequest) (response domainUser.AvatarResponse, err error) { chanResp := make(chan domainUser.AvatarResponse) diff --git a/src/validations/user_validation.go b/src/validations/user_validation.go index 5f6e359..7691d27 100644 --- a/src/validations/user_validation.go +++ b/src/validations/user_validation.go @@ -18,6 +18,17 @@ func ValidateUserInfo(ctx context.Context, request domainUser.InfoRequest) error return nil } +func ValidateUserCheck(ctx context.Context, request domainUser.CheckRequest) error { + err := validation.ValidateStructWithContext(ctx, &request, + validation.Field(&request.Phone, validation.Required), + ) + + if err != nil { + return pkgError.ValidationError(err.Error()) + } + + return nil +} func ValidateUserAvatar(ctx context.Context, request domainUser.AvatarRequest) error { err := validation.ValidateStructWithContext(ctx, &request, validation.Field(&request.Phone, validation.Required), diff --git a/src/views/components/AccountUserCheck.js b/src/views/components/AccountUserCheck.js new file mode 100644 index 0000000..5c3f7b8 --- /dev/null +++ b/src/views/components/AccountUserCheck.js @@ -0,0 +1,117 @@ +import FormCheckUserRecipient from "./generic/FormCheckUserRecipient.js"; + +export default { + name: 'AccountUserCheck', + components: { + FormCheckUserRecipient + }, + data() { + return { + type: window.TYPEUSER, + phone: '', + // + is_in_whatsapp: null, + jid: null, + verified_name: null, + query: null, + code: null, + // + loading: false, + } + }, + + computed: { + phone_id() { + return this.phone + this.type; + } + }, + methods: { + async openModal() { + this.handleReset(); + $('#modalUserCheck').modal('show'); + }, + async handleSubmit() { + try { + await this.submitApi(); + showSuccessInfo("Info fetched") + } catch (err) { + showErrorInfo(err) + } + }, + async submitApi() { + this.loading = true; + try { + let response = await window.http.get(`/user/check?phone=${this.phone_id}`) + this.is_in_whatsapp = response.data.results.IsInWhatsapp; + this.jid = response.data.results.jid; + this.verified_name = response.data.results.verified_name; + this.query = response.data.results.query; + this.code = response.code; + } catch (error) { + if (error.response) { + this.verified_name = null; + this.jid = null; + throw new Error(error.response.data.message); + } + this.verified_name = null; + this.jid = null; + throw new Error(error.message); + } finally { + this.loading = false; + } + }, + handleReset() { + this.phone = ''; + this.is_in_whatsapp = null; + this.jid = null; + this.verified_name = null; + this.query = null; + this.code = null; + this.type = window.TYPEUSER; + } + }, + template: ` +