diff --git a/src/cmd/root.go b/src/cmd/root.go index e5b0406..b93c224 100644 --- a/src/cmd/root.go +++ b/src/cmd/root.go @@ -113,6 +113,7 @@ func runRest(_ *cobra.Command, _ []string) { userService := services.NewUserService(cli) messageService := services.NewMessageService(cli) groupService := services.NewGroupService(cli) + newsletterService := services.NewNewsletterService(cli) // Rest rest.InitRestApp(app, appService) @@ -120,6 +121,7 @@ func runRest(_ *cobra.Command, _ []string) { rest.InitRestUser(app, userService) rest.InitRestMessage(app, messageService) rest.InitRestGroup(app, groupService) + rest.InitRestNewsletter(app, newsletterService) app.Get("/", func(c *fiber.Ctx) error { return c.Render("views/index", fiber.Map{ diff --git a/src/domains/newletter/newsletter.go b/src/domains/newletter/newsletter.go new file mode 100644 index 0000000..093ae75 --- /dev/null +++ b/src/domains/newletter/newsletter.go @@ -0,0 +1,11 @@ +package newletter + +import "context" + +type INewsletterService interface { + Unfollow(ctx context.Context, request UnfollowRequest) (err error) +} + +type UnfollowRequest struct { + NewsletterID string `json:"newsletter_id" form:"newsletter_id"` +} diff --git a/src/domains/user/account.go b/src/domains/user/account.go index ad23e04..d424755 100644 --- a/src/domains/user/account.go +++ b/src/domains/user/account.go @@ -48,3 +48,7 @@ type MyPrivacySettingResponse struct { type MyListGroupsResponse struct { Data []types.GroupInfo `json:"data"` } + +type MyListNewsletterResponse struct { + Data []types.NewsletterMetadata `json:"data"` +} diff --git a/src/domains/user/user.go b/src/domains/user/user.go index dabca89..feb3b78 100644 --- a/src/domains/user/user.go +++ b/src/domains/user/user.go @@ -8,5 +8,6 @@ type IUserService interface { Info(ctx context.Context, request InfoRequest) (response InfoResponse, 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) MyPrivacySetting(ctx context.Context) (response MyPrivacySettingResponse, err error) } diff --git a/src/internal/rest/newsletter.go b/src/internal/rest/newsletter.go new file mode 100644 index 0000000..bfb7507 --- /dev/null +++ b/src/internal/rest/newsletter.go @@ -0,0 +1,32 @@ +package rest + +import ( + domainNewsletter "github.com/aldinokemal/go-whatsapp-web-multidevice/domains/newletter" + "github.com/aldinokemal/go-whatsapp-web-multidevice/pkg/utils" + "github.com/gofiber/fiber/v2" +) + +type Newsletter struct { + Service domainNewsletter.INewsletterService +} + +func InitRestNewsletter(app *fiber.App, service domainNewsletter.INewsletterService) Newsletter { + rest := Newsletter{Service: service} + app.Post("/newsletter/unfollow", rest.Unfollow) + return rest +} + +func (controller *Newsletter) Unfollow(c *fiber.Ctx) error { + var request domainNewsletter.UnfollowRequest + err := c.BodyParser(&request) + utils.PanicIfNeeded(err) + + err = controller.Service.Unfollow(c.UserContext(), request) + utils.PanicIfNeeded(err) + + return c.JSON(utils.ResponseData{ + Status: 200, + Code: "SUCCESS", + Message: "Success unfollow newsletter", + }) +} diff --git a/src/internal/rest/user.go b/src/internal/rest/user.go index dd01f5a..6621bb2 100644 --- a/src/internal/rest/user.go +++ b/src/internal/rest/user.go @@ -17,6 +17,7 @@ func InitRestUser(app *fiber.App, service domainUser.IUserService) User { app.Get("/user/avatar", rest.UserAvatar) app.Get("/user/my/privacy", rest.UserMyPrivacySetting) app.Get("/user/my/groups", rest.UserMyListGroups) + app.Get("/user/my/newsletters", rest.UserMyListNewsletter) return rest } @@ -80,3 +81,15 @@ func (controller *User) UserMyListGroups(c *fiber.Ctx) error { Results: response, }) } + +func (controller *User) UserMyListNewsletter(c *fiber.Ctx) error { + response, err := controller.Service.MyListNewsletter(c.UserContext()) + utils.PanicIfNeeded(err) + + return c.JSON(utils.ResponseData{ + Status: 200, + Code: "SUCCESS", + Message: "Success get list newsletter", + Results: response, + }) +} diff --git a/src/pkg/whatsapp/whatsapp.go b/src/pkg/whatsapp/whatsapp.go index d0f4953..77e20f8 100644 --- a/src/pkg/whatsapp/whatsapp.go +++ b/src/pkg/whatsapp/whatsapp.go @@ -107,17 +107,19 @@ func ParseJID(arg string) (types.JID, error) { } if !strings.ContainsRune(arg, '@') { return types.NewJID(arg, types.DefaultUserServer), nil - } else { - recipient, err := types.ParseJID(arg) - if err != nil { - fmt.Printf("invalid JID %s: %v", arg, err) - return recipient, pkgError.ErrInvalidJID - } else if recipient.User == "" { - fmt.Printf("invalid JID %v: no server specified", arg) - return recipient, pkgError.ErrInvalidJID - } - return recipient, nil } + + recipient, err := types.ParseJID(arg) + if err != nil { + fmt.Printf("invalid JID %s: %v", arg, err) + return recipient, pkgError.ErrInvalidJID + } + + if recipient.User == "" { + fmt.Printf("invalid JID %v: no server specified", arg) + return recipient, pkgError.ErrInvalidJID + } + return recipient, nil } func IsOnWhatsapp(waCli *whatsmeow.Client, jid string) bool { diff --git a/src/services/newsletter.go b/src/services/newsletter.go new file mode 100644 index 0000000..2fb90ed --- /dev/null +++ b/src/services/newsletter.go @@ -0,0 +1,32 @@ +package services + +import ( + "context" + domainNewsletter "github.com/aldinokemal/go-whatsapp-web-multidevice/domains/newletter" + "github.com/aldinokemal/go-whatsapp-web-multidevice/pkg/whatsapp" + "github.com/aldinokemal/go-whatsapp-web-multidevice/validations" + "go.mau.fi/whatsmeow" +) + +type newsletterService struct { + WaCli *whatsmeow.Client +} + +func NewNewsletterService(waCli *whatsmeow.Client) domainNewsletter.INewsletterService { + return &newsletterService{ + WaCli: waCli, + } +} + +func (service newsletterService) Unfollow(ctx context.Context, request domainNewsletter.UnfollowRequest) (err error) { + if err = validations.ValidateUnfollowNewsletter(ctx, request); err != nil { + return err + } + + JID, err := whatsapp.ValidateJidWithLogin(service.WaCli, request.NewsletterID) + if err != nil { + return err + } + + return service.WaCli.UnfollowNewsletter(JID) +} diff --git a/src/services/user.go b/src/services/user.go index a6e7b8a..19d0652 100644 --- a/src/services/user.go +++ b/src/services/user.go @@ -127,6 +127,20 @@ func (service userService) MyListGroups(_ context.Context) (response domainUser. 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) diff --git a/src/validations/newsletter_validation.go b/src/validations/newsletter_validation.go new file mode 100644 index 0000000..da61da9 --- /dev/null +++ b/src/validations/newsletter_validation.go @@ -0,0 +1,20 @@ +package validations + +import ( + "context" + domainNewsletter "github.com/aldinokemal/go-whatsapp-web-multidevice/domains/newletter" + pkgError "github.com/aldinokemal/go-whatsapp-web-multidevice/pkg/error" + validation "github.com/go-ozzo/ozzo-validation/v4" +) + +func ValidateUnfollowNewsletter(ctx context.Context, request domainNewsletter.UnfollowRequest) error { + err := validation.ValidateStructWithContext(ctx, &request, + validation.Field(&request.NewsletterID, validation.Required), + ) + + if err != nil { + return pkgError.ValidationError(err.Error()) + } + + return nil +} diff --git a/src/views/components/AccountAvatar.js b/src/views/components/AccountAvatar.js index 2e602cb..e9ab15f 100644 --- a/src/views/components/AccountAvatar.js +++ b/src/views/components/AccountAvatar.js @@ -1,8 +1,13 @@ +import FormRecipient from "./generic/FormRecipient.js"; + export default { name: 'AccountAvatar', + components: { + FormRecipient + }, data() { return { - type: 'user', + type: window.TYPEUSER, phone: '', image: null, loading: false, @@ -12,7 +17,7 @@ export default { }, computed: { phone_id() { - return this.type === 'user' ? `${this.phone}@${window.TYPEUSER}` : `${this.phone}@${window.TYPEGROUP}` + return this.phone + this.type; } }, methods: { @@ -45,7 +50,7 @@ export default { handleReset() { this.phone = ''; this.image = null; - this.type = 'user'; + this.type = window.TYPEUSER; } }, template: ` @@ -66,19 +71,7 @@ export default {