Browse Source

Ajustes para a versão 4.21.0

pull/201/head
Iago Cotta 1 year ago
parent
commit
db75233b4a
  1. 4
      .gitignore
  2. 347
      docs/openapi.yaml
  3. 8
      readme.md
  4. 2
      src/cmd/root.go
  5. 2
      src/config/settings.go
  6. 6
      src/domains/message/message.go
  7. 11
      src/domains/newsletter/newsletter.go
  8. 4
      src/domains/user/account.go
  9. 1
      src/domains/user/user.go
  10. 22
      src/go.mod
  11. 25
      src/go.sum
  12. 20
      src/internal/rest/message.go
  13. 32
      src/internal/rest/newsletter.go
  14. 13
      src/internal/rest/user.go
  15. 32
      src/pkg/whatsapp/whatsapp.go
  16. 27
      src/services/message.go
  17. 32
      src/services/newsletter.go
  18. 20
      src/services/send.go
  19. 14
      src/services/user.go
  20. 14
      src/validations/message_validation.go
  21. 20
      src/validations/newsletter_validation.go
  22. 26
      src/views/components/AccountAvatar.js
  23. 24
      src/views/components/AccountUserInfo.js
  24. 2
      src/views/components/GroupManageParticipants.js
  25. 27
      src/views/components/MessageDelete.js
  26. 27
      src/views/components/MessageReact.js
  27. 27
      src/views/components/MessageRevoke.js
  28. 27
      src/views/components/MessageUpdate.js
  29. 117
      src/views/components/NewsletterList.js
  30. 26
      src/views/components/SendAudio.js
  31. 27
      src/views/components/SendContact.js
  32. 27
      src/views/components/SendFile.js
  33. 27
      src/views/components/SendImage.js
  34. 27
      src/views/components/SendLocation.js
  35. 26
      src/views/components/SendMessage.js
  36. 29
      src/views/components/SendPoll.js
  37. 27
      src/views/components/SendVideo.js
  38. 52
      src/views/components/generic/FormRecipient.js
  39. 19
      src/views/index.html

4
.gitignore

@ -7,4 +7,6 @@ main
main.exe main.exe
*.jpe *.jpe
src/pkged.go src/pkged.go
storages
storages
.png
*.exe

347
docs/openapi.yaml

@ -1,7 +1,7 @@
openapi: 3.0.0 openapi: 3.0.0
info: info:
title: WhatsApp API MultiDevice title: WhatsApp API MultiDevice
version: 4.2.0
version: 4.4.0
description: This API is used for sending whatsapp via API description: This API is used for sending whatsapp via API
servers: servers:
- url: http://localhost:3000 - url: http://localhost:3000
@ -16,6 +16,8 @@ tags:
description: Message manipulation (revoke/react/update). description: Message manipulation (revoke/react/update).
- name: group - name: group
description: Group setting description: Group setting
- name: newsletter
description: newsletter setting
paths: paths:
/app/login: /app/login:
get: get:
@ -212,6 +214,31 @@ paths:
- user - user
summary: User My List Groups summary: User My List Groups
responses: responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/UserGroupResponse'
'500':
description: Internal Server Error
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorInternalServer'
/user/my/newsletters:
get:
operationId: userMyNewsletter
tags:
- user
summary: User My List Groups
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/NewsletterResponse'
'500': '500':
description: Internal Server Error description: Internal Server Error
content: content:
@ -808,6 +835,50 @@ paths:
application/json: application/json:
schema: schema:
$ref: '#/components/schemas/ErrorInternalServer' $ref: '#/components/schemas/ErrorInternalServer'
/message/{message_id}/read:
post:
operationId: readMessage
tags:
- message
summary: Mark as read message
parameters:
- in: path
name: message_id
schema:
type: string
required: true
description: Message ID
requestBody:
content:
application/json:
schema:
type: object
properties:
phone:
type: string
example: '62819273192397132@s.whatsapp.net'
description: Phone number with country code
required:
- phone
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/SendResponse'
'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'
/group: /group:
post: post:
operationId: createGroup operationId: createGroup
@ -1042,6 +1113,40 @@ paths:
application/json: application/json:
schema: schema:
$ref: '#/components/schemas/ErrorInternalServer' $ref: '#/components/schemas/ErrorInternalServer'
/newsletter/unfollow:
post:
operationId: unfollowNewsletter
tags:
- newsletter
summary: Unfollow newsletter
requestBody:
content:
application/json:
schema:
type: object
properties:
newsletter_id:
type: string
example: '120363024512399999@newsletter'
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: components:
schemas: schemas:
@ -1341,4 +1446,242 @@ components:
results: results:
type: object type: object
example: null example: null
description: 'additional data'
description: 'additional data'
NewsletterResponse:
type: object
properties:
code:
type: string
example: "SUCCESS"
message:
type: string
example: "Success get list newsletter"
results:
type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/Newsletter'
Newsletter:
type: object
properties:
id:
type: string
example: "120363144038483540@newsletter"
state:
type: object
properties:
type:
type: string
example: "active"
thread_metadata:
type: object
properties:
creation_time:
type: string
example: "1688746895"
invite:
type: string
example: "0029Va4K0PZ5a245NkngBA2M"
name:
type: object
properties:
text:
type: string
example: "WhatsApp"
id:
type: string
example: "1688746895480511"
update_time:
type: string
example: "1688746895480511"
description:
type: object
properties:
text:
type: string
example: "WhatsApp’s official channel. Follow for our latest feature launches, updates, exclusive drops and more."
id:
type: string
example: "1689653839450668"
update_time:
type: string
example: "1689653839450668"
subscribers_count:
type: string
example: "0"
verification:
type: string
example: "verified"
picture:
type: object
properties:
url:
type: string
example: ""
id:
type: string
example: "1707950960975554"
type:
type: string
example: "IMAGE"
direct_path:
type: string
example: "/v/t61.24694-24/416962407_970228831134395_8869146381947923973_n.jpg?ccb=11-4&oh=01_Q5AaIIvOIeu3l0HCZWILrmr-dGR_vXFqnhUeytw0-ojPc4hL&oe=670D95B1&_nc_sid=5e03e0&_nc_cat=110"
preview:
type: object
properties:
url:
type: string
example: ""
id:
type: string
example: "1707950960975554"
type:
type: string
example: "PREVIEW"
direct_path:
type: string
example: "/v/t61.24694-24/416962407_970228831134395_8869146381947923973_n.jpg?stp=dst-jpg_s192x192&ccb=11-4&oh=01_Q5AaIHO-DQklqm3q3awF7xwji_WAn9DkgZASQA0B2Ct0qbSa&oe=670D95B1&_nc_sid=5e03e0&_nc_cat=110"
settings:
type: object
properties:
reaction_codes:
type: object
properties:
value:
type: string
example: "ALL"
viewer_metadata:
type: object
properties:
mute:
type: string
example: "off"
role:
type: string
example: "subscriber"
GroupResponse:
type: object
properties:
code:
type: string
example: "SUCCESS"
message:
type: string
example: "Success get list groups"
results:
type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/Group'
Group:
type: object
properties:
JID:
type: string
example: "120363347168689807@g.us"
OwnerJID:
type: string
example: "6288228744537@s.whatsapp.net"
Name:
type: string
example: "Example Group"
NameSetAt:
type: string
format: date-time
example: "2024-10-11T21:27:29+07:00"
NameSetBy:
type: string
example: "6288228744537@s.whatsapp.net"
Topic:
type: string
example: ""
TopicID:
type: string
example: ""
TopicSetAt:
type: string
format: date-time
example: "0001-01-01T00:00:00Z"
TopicSetBy:
type: string
example: ""
TopicDeleted:
type: boolean
example: false
IsLocked:
type: boolean
example: false
IsAnnounce:
type: boolean
example: false
AnnounceVersionID:
type: string
example: "1728656849439709"
IsEphemeral:
type: boolean
example: false
DisappearingTimer:
type: integer
example: 0
IsIncognito:
type: boolean
example: false
IsParent:
type: boolean
example: false
DefaultMembershipApprovalMode:
type: string
example: ""
LinkedParentJID:
type: string
example: ""
IsDefaultSubGroup:
type: boolean
example: false
IsJoinApprovalRequired:
type: boolean
example: false
GroupCreated:
type: string
format: date-time
example: "2024-10-11T21:27:29+07:00"
ParticipantVersionID:
type: string
example: "1728656849439790"
Participants:
type: array
items:
$ref: '#/components/schemas/Participant'
MemberAddMode:
type: string
example: "admin_add"
Participant:
type: object
properties:
JID:
type: string
example: "6288228744537@s.whatsapp.net"
LID:
type: string
example: "20036609675500@lid"
IsAdmin:
type: boolean
example: true
IsSuperAdmin:
type: boolean
example: true
DisplayName:
type: string
example: ""
Error:
type: integer
example: 0
AddRequest:
type: string
example: null

8
readme.md

@ -112,7 +112,8 @@ You can fork or edit this source code !
| ✅ | Devices | GET | /app/devices | | ✅ | Devices | GET | /app/devices |
| ✅ | User Info | GET | /user/info | | ✅ | User Info | GET | /user/info |
| ✅ | User Avatar | GET | /user/avatar | | ✅ | User Avatar | GET | /user/avatar |
| ✅ | User My Group List | GET | /user/my/groups |
| ✅ | User My Groups | GET | /user/my/groups |
| ✅ | User My Newsletter | GET | /user/my/newsletters |
| ✅ | User My Privacy Setting | GET | /user/my/privacy | | ✅ | User My Privacy Setting | GET | /user/my/privacy |
| ✅ | Send Message | POST | /send/message | | ✅ | Send Message | POST | /send/message |
| ✅ | Send Image | POST | /send/image | | ✅ | Send Image | POST | /send/image |
@ -127,6 +128,7 @@ You can fork or edit this source code !
| ✅ | React Message | POST | /message/:message_id/reaction | | ✅ | React Message | POST | /message/:message_id/reaction |
| ✅ | Delete Message | POST | /message/:message_id/delete | | ✅ | Delete Message | POST | /message/:message_id/delete |
| ✅ | Edit Message | POST | /message/:message_id/update | | ✅ | Edit Message | POST | /message/:message_id/update |
| ✅ | Read Message (DM) | POST | /message/:message_id/read |
| ❌ | Star message | POST | /message/:message_id/star | | ❌ | Star message | POST | /message/:message_id/star |
| ✅ | Join Group With Link | POST | /group/join-with-link | | ✅ | Join Group With Link | POST | /group/join-with-link |
| ✅ | Leave Group | POST | /group/leave | | ✅ | Leave Group | POST | /group/leave |
@ -135,6 +137,7 @@ You can fork or edit this source code !
| ✅ | Remove Participant in Group | POST | /group/participants/remove | | ✅ | Remove Participant in Group | POST | /group/participants/remove |
| ✅ | Promote Participant in Group | POST | /group/participants/promote | | ✅ | Promote Participant in Group | POST | /group/participants/promote |
| ✅ | Demote Participant in Group | POST | /group/participants/demote | | ✅ | Demote Participant in Group | POST | /group/participants/demote |
| ✅ | Unfollow Newsletter | POST | /newsletter/unfollow |
``` ```
✅ = Available ✅ = Available
@ -145,7 +148,7 @@ You can fork or edit this source code !
| Description | Image | | Description | Image |
|--------------------|------------------------------------------------------------------------------------------| |--------------------|------------------------------------------------------------------------------------------|
| Homepage | ![Homepage](https://i.ibb.co.com/L0B1LVb/homepage-v4-16.png) |
| Homepage | ![Homepage](https://i.ibb.co.com/Sy0dHZp/homepage-v4-20.png) |
| Login | ![Login](https://i.ibb.co.com/jkcB15R/login.png?v=1) | | Login | ![Login](https://i.ibb.co.com/jkcB15R/login.png?v=1) |
| Login With Code | ![Login With Code](https://i.ibb.co.com/rdJGvGw/paircode.png) | | Login With Code | ![Login With Code](https://i.ibb.co.com/rdJGvGw/paircode.png) |
| Send Message | ![Send Message](https://i.ibb.co.com/rc3NXMX/send-message.png?v1) | | Send Message | ![Send Message](https://i.ibb.co.com/rc3NXMX/send-message.png?v1) |
@ -167,6 +170,7 @@ You can fork or edit this source code !
| Auto Reply | ![Auto Reply](https://i.ibb.co.com/D4rTytX/IMG-20220517-162500.jpg) | | Auto Reply | ![Auto Reply](https://i.ibb.co.com/D4rTytX/IMG-20220517-162500.jpg) |
| Basic Auth Prompt | ![Basic Auth Prompt](https://i.ibb.co.com/PDjQ92W/Screenshot-2022-11-06-at-14-06-29.png) | | Basic Auth Prompt | ![Basic Auth Prompt](https://i.ibb.co.com/PDjQ92W/Screenshot-2022-11-06-at-14-06-29.png) |
| Manage Participant | ![Manage Participant](https://i.ibb.co.com/ynrN7cr/manage-participant.png) | | Manage Participant | ![Manage Participant](https://i.ibb.co.com/ynrN7cr/manage-participant.png) |
| My Newsletter | ![List Newsletter](https://i.ibb.co.com/WDg50jJ/image.png) |
### Mac OS NOTE ### Mac OS NOTE

2
src/cmd/root.go

@ -113,6 +113,7 @@ func runRest(_ *cobra.Command, _ []string) {
userService := services.NewUserService(cli) userService := services.NewUserService(cli)
messageService := services.NewMessageService(cli) messageService := services.NewMessageService(cli)
groupService := services.NewGroupService(cli) groupService := services.NewGroupService(cli)
newsletterService := services.NewNewsletterService(cli)
// Rest // Rest
rest.InitRestApp(app, appService) rest.InitRestApp(app, appService)
@ -120,6 +121,7 @@ func runRest(_ *cobra.Command, _ []string) {
rest.InitRestUser(app, userService) rest.InitRestUser(app, userService)
rest.InitRestMessage(app, messageService) rest.InitRestMessage(app, messageService)
rest.InitRestGroup(app, groupService) rest.InitRestGroup(app, groupService)
rest.InitRestNewsletter(app, newsletterService)
app.Get("/", func(c *fiber.Ctx) error { app.Get("/", func(c *fiber.Ctx) error {
return c.Render("views/index", fiber.Map{ return c.Render("views/index", fiber.Map{

2
src/config/settings.go

@ -7,7 +7,7 @@ import (
) )
var ( var (
AppVersion = "v4.18.0"
AppVersion = "v4.21.0"
AppPort = "3000" AppPort = "3000"
AppDebug = false AppDebug = false
AppOs = "AldinoKemal" AppOs = "AldinoKemal"

6
src/domains/message/message.go

@ -3,6 +3,7 @@ package message
import "context" import "context"
type IMessageService interface { type IMessageService interface {
MarkAsRead(ctx context.Context, request MarkAsReadRequest) (response GenericResponse, err error)
ReactMessage(ctx context.Context, request ReactionRequest) (response GenericResponse, err error) ReactMessage(ctx context.Context, request ReactionRequest) (response GenericResponse, err error)
RevokeMessage(ctx context.Context, request RevokeRequest) (response GenericResponse, err error) RevokeMessage(ctx context.Context, request RevokeRequest) (response GenericResponse, err error)
UpdateMessage(ctx context.Context, request UpdateMessageRequest) (response GenericResponse, err error) UpdateMessage(ctx context.Context, request UpdateMessageRequest) (response GenericResponse, err error)
@ -35,3 +36,8 @@ type UpdateMessageRequest struct {
Message string `json:"message" form:"message"` Message string `json:"message" form:"message"`
Phone string `json:"phone" form:"phone"` Phone string `json:"phone" form:"phone"`
} }
type MarkAsReadRequest struct {
MessageID string `json:"message_id" uri:"message_id"`
Phone string `json:"phone" form:"phone"`
}

11
src/domains/newsletter/newsletter.go

@ -0,0 +1,11 @@
package newsletter
import "context"
type INewsletterService interface {
Unfollow(ctx context.Context, request UnfollowRequest) (err error)
}
type UnfollowRequest struct {
NewsletterID string `json:"newsletter_id" form:"newsletter_id"`
}

4
src/domains/user/account.go

@ -48,3 +48,7 @@ type MyPrivacySettingResponse struct {
type MyListGroupsResponse struct { type MyListGroupsResponse struct {
Data []types.GroupInfo `json:"data"` Data []types.GroupInfo `json:"data"`
} }
type MyListNewsletterResponse struct {
Data []types.NewsletterMetadata `json:"data"`
}

1
src/domains/user/user.go

@ -8,5 +8,6 @@ type IUserService interface {
Info(ctx context.Context, request InfoRequest) (response InfoResponse, err error) Info(ctx context.Context, request InfoRequest) (response InfoResponse, err error)
Avatar(ctx context.Context, request AvatarRequest) (response AvatarResponse, err error) Avatar(ctx context.Context, request AvatarRequest) (response AvatarResponse, err error)
MyListGroups(ctx context.Context) (response MyListGroupsResponse, 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) MyPrivacySetting(ctx context.Context) (response MyPrivacySettingResponse, err error)
} }

22
src/go.mod

@ -13,20 +13,20 @@ require (
github.com/gofiber/template/html/v2 v2.1.2 github.com/gofiber/template/html/v2 v2.1.2
github.com/gofiber/websocket/v2 v2.2.1 github.com/gofiber/websocket/v2 v2.2.1
github.com/google/uuid v1.6.0 github.com/google/uuid v1.6.0
github.com/mattn/go-sqlite3 v1.14.23
github.com/mattn/go-sqlite3 v1.14.24
github.com/sirupsen/logrus v1.9.3 github.com/sirupsen/logrus v1.9.3
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
github.com/spf13/cobra v1.8.1 github.com/spf13/cobra v1.8.1
github.com/stretchr/testify v1.9.0 github.com/stretchr/testify v1.9.0
github.com/valyala/fasthttp v1.56.0
github.com/valyala/fasthttp v1.57.0
go.mau.fi/libsignal v0.1.1 go.mau.fi/libsignal v0.1.1
go.mau.fi/whatsmeow v0.0.0-20240927134544-69ba055bef0f
google.golang.org/protobuf v1.34.2
go.mau.fi/whatsmeow v0.0.0-20241027175758-cd900353e4a7
google.golang.org/protobuf v1.35.1
) )
require ( require (
filippo.io/edwards25519 v1.1.0 // indirect filippo.io/edwards25519 v1.1.0 // indirect
github.com/andybalholm/brotli v1.1.0 // indirect
github.com/andybalholm/brotli v1.1.1 // indirect
github.com/andybalholm/cascadia v1.3.2 // indirect github.com/andybalholm/cascadia v1.3.2 // indirect
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect
@ -35,7 +35,7 @@ require (
github.com/gofiber/utils v1.1.0 // indirect github.com/gofiber/utils v1.1.0 // indirect
github.com/gorilla/websocket v1.5.3 // indirect github.com/gorilla/websocket v1.5.3 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/klauspost/compress v1.17.10 // indirect
github.com/klauspost/compress v1.17.11 // indirect
github.com/kr/pretty v0.1.0 // indirect github.com/kr/pretty v0.1.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-isatty v0.0.20 // indirect
@ -47,11 +47,11 @@ require (
github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/pflag v1.0.5 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/tcplisten v1.0.0 // indirect github.com/valyala/tcplisten v1.0.0 // indirect
go.mau.fi/util v0.8.0 // indirect
golang.org/x/crypto v0.27.0 // indirect
golang.org/x/image v0.20.0 // indirect
golang.org/x/net v0.29.0 // indirect
golang.org/x/sys v0.25.0 // indirect
go.mau.fi/util v0.8.1 // indirect
golang.org/x/crypto v0.28.0 // indirect
golang.org/x/image v0.21.0 // indirect
golang.org/x/net v0.30.0 // indirect
golang.org/x/sys v0.26.0 // indirect
golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f // indirect golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f // indirect
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect

25
src/go.sum

@ -6,6 +6,8 @@ github.com/PuerkitoBio/goquery v1.10.0 h1:6fiXdLuUvYs2OJSvNRqlNPoBm6YABE226xrbav
github.com/PuerkitoBio/goquery v1.10.0/go.mod h1:TjZZl68Q3eGHNBA8CWaxAN7rOU1EbDz3CWuolcO5Yu4= github.com/PuerkitoBio/goquery v1.10.0/go.mod h1:TjZZl68Q3eGHNBA8CWaxAN7rOU1EbDz3CWuolcO5Yu4=
github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M= github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY= github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
github.com/andybalholm/brotli v1.1.1 h1:PR2pgnyFznKEugtsUo0xLdDop5SKXd5Qf5ysW+7XdTA=
github.com/andybalholm/brotli v1.1.1/go.mod h1:05ib4cKhjx3OQYUY22hTVd34Bc8upXjOLL2rKwwZBoA=
github.com/andybalholm/cascadia v1.3.2 h1:3Xi6Dw5lHF15JtdcmAHD3i1+T8plmv7BQ/nsViSLyss= github.com/andybalholm/cascadia v1.3.2 h1:3Xi6Dw5lHF15JtdcmAHD3i1+T8plmv7BQ/nsViSLyss=
github.com/andybalholm/cascadia v1.3.2/go.mod h1:7gtRlve5FxPPgIgX36uWBX58OdBsSS6lUvCFb+h7KvU= github.com/andybalholm/cascadia v1.3.2/go.mod h1:7gtRlve5FxPPgIgX36uWBX58OdBsSS6lUvCFb+h7KvU=
github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg=
@ -47,6 +49,8 @@ github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
github.com/klauspost/compress v1.17.10 h1:oXAz+Vh0PMUvJczoi+flxpnBEPxoER1IaAnU/NMPtT0= github.com/klauspost/compress v1.17.10 h1:oXAz+Vh0PMUvJczoi+flxpnBEPxoER1IaAnU/NMPtT0=
github.com/klauspost/compress v1.17.10/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= github.com/klauspost/compress v1.17.10/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc=
github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
@ -64,6 +68,8 @@ github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/mattn/go-sqlite3 v1.14.23 h1:gbShiuAP1W5j9UOksQ06aiiqPMxYecovVGwmTxWtuw0= github.com/mattn/go-sqlite3 v1.14.23 h1:gbShiuAP1W5j9UOksQ06aiiqPMxYecovVGwmTxWtuw0=
github.com/mattn/go-sqlite3 v1.14.23/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/mattn/go-sqlite3 v1.14.23/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM=
github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
@ -95,8 +101,11 @@ github.com/valyala/fasthttp v1.55.0 h1:Zkefzgt6a7+bVKHnu/YaYSOPfNYNisSVBo/unVCf8
github.com/valyala/fasthttp v1.55.0/go.mod h1:NkY9JtkrpPKmgwV3HTaS2HWaJss9RSIsRVfcxxoHiOM= github.com/valyala/fasthttp v1.55.0/go.mod h1:NkY9JtkrpPKmgwV3HTaS2HWaJss9RSIsRVfcxxoHiOM=
github.com/valyala/fasthttp v1.56.0 h1:bEZdJev/6LCBlpdORfrLu/WOZXXxvrUQSiyniuaoW8U= github.com/valyala/fasthttp v1.56.0 h1:bEZdJev/6LCBlpdORfrLu/WOZXXxvrUQSiyniuaoW8U=
github.com/valyala/fasthttp v1.56.0/go.mod h1:sReBt3XZVnudxuLOx4J/fMrJVorWRiWY2koQKgABiVI= github.com/valyala/fasthttp v1.56.0/go.mod h1:sReBt3XZVnudxuLOx4J/fMrJVorWRiWY2koQKgABiVI=
github.com/valyala/fasthttp v1.57.0 h1:Xw8SjWGEP/+wAAgyy5XTvgrWlOD1+TxbbvNADYCm1Tg=
github.com/valyala/fasthttp v1.57.0/go.mod h1:h6ZBaPRlzpZ6O3H5t2gEk1Qi33+TmLvfwgLLp0t9CpE=
github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8= 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/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.mau.fi/libsignal v0.1.1 h1:m/0PGBh4QKP/I1MQ44ti4C0fMbLMuHb95cmDw01FIpI= go.mau.fi/libsignal v0.1.1 h1:m/0PGBh4QKP/I1MQ44ti4C0fMbLMuHb95cmDw01FIpI=
go.mau.fi/libsignal v0.1.1/go.mod h1:QLs89F/OA3ThdSL2Wz2p+o+fi8uuQUz0e1BRa6ExdBw= go.mau.fi/libsignal v0.1.1/go.mod h1:QLs89F/OA3ThdSL2Wz2p+o+fi8uuQUz0e1BRa6ExdBw=
@ -104,23 +113,33 @@ go.mau.fi/util v0.7.0 h1:l31z+ivrSQw+cv/9eFebEqtQW2zhxivGypn+JT0h/ws=
go.mau.fi/util v0.7.0/go.mod h1:bWYreIoTULL/UiRbZdfddPh7uWDFW5yX4YCv5FB0eE0= go.mau.fi/util v0.7.0/go.mod h1:bWYreIoTULL/UiRbZdfddPh7uWDFW5yX4YCv5FB0eE0=
go.mau.fi/util v0.8.0 h1:MiSny8jgQq4XtCLAT64gDJhZVhqiDeMVIEBDFVw+M0g= go.mau.fi/util v0.8.0 h1:MiSny8jgQq4XtCLAT64gDJhZVhqiDeMVIEBDFVw+M0g=
go.mau.fi/util v0.8.0/go.mod h1:1Ixb8HWoVbl3rT6nAX6nV4iMkzn7KU/KXwE0Rn5RmsQ= go.mau.fi/util v0.8.0/go.mod h1:1Ixb8HWoVbl3rT6nAX6nV4iMkzn7KU/KXwE0Rn5RmsQ=
go.mau.fi/util v0.8.1 h1:Ga43cz6esQBYqcjZ/onRoVnYWoUwjWbsxVeJg2jOTSo=
go.mau.fi/util v0.8.1/go.mod h1:T1u/rD2rzidVrBLyaUdPpZiJdP/rsyi+aTzn0D+Q6wc=
go.mau.fi/whatsmeow v0.0.0-20240821142752-3d63c6fcc1a7 h1:Aa4uov0rM0SQQ7Fc/TZZpmQEGksie2SVTv/UuCJwViI= go.mau.fi/whatsmeow v0.0.0-20240821142752-3d63c6fcc1a7 h1:Aa4uov0rM0SQQ7Fc/TZZpmQEGksie2SVTv/UuCJwViI=
go.mau.fi/whatsmeow v0.0.0-20240821142752-3d63c6fcc1a7/go.mod h1:BhHKalSq0qNtSCuGIUIvoJyU5KbT4a7k8DQ5yw1Ssk4= go.mau.fi/whatsmeow v0.0.0-20240821142752-3d63c6fcc1a7/go.mod h1:BhHKalSq0qNtSCuGIUIvoJyU5KbT4a7k8DQ5yw1Ssk4=
go.mau.fi/whatsmeow v0.0.0-20240911102933-bb3364aa3986 h1:7X+3826qoRBHPCtxY89tqMcYEsi9+OuWE6hHZfRc0qI= go.mau.fi/whatsmeow v0.0.0-20240911102933-bb3364aa3986 h1:7X+3826qoRBHPCtxY89tqMcYEsi9+OuWE6hHZfRc0qI=
go.mau.fi/whatsmeow v0.0.0-20240911102933-bb3364aa3986/go.mod h1:BhHKalSq0qNtSCuGIUIvoJyU5KbT4a7k8DQ5yw1Ssk4= go.mau.fi/whatsmeow v0.0.0-20240911102933-bb3364aa3986/go.mod h1:BhHKalSq0qNtSCuGIUIvoJyU5KbT4a7k8DQ5yw1Ssk4=
go.mau.fi/whatsmeow v0.0.0-20240927134544-69ba055bef0f h1:+gT0NSk50HaAagtyj6J/a/QiNN34FJU+Vm1QyppV8Ec= go.mau.fi/whatsmeow v0.0.0-20240927134544-69ba055bef0f h1:+gT0NSk50HaAagtyj6J/a/QiNN34FJU+Vm1QyppV8Ec=
go.mau.fi/whatsmeow v0.0.0-20240927134544-69ba055bef0f/go.mod h1:UvaXcdb8y5Mryj2LSXAMw7u4/exnWJIXn8Gvpmf6ndI= go.mau.fi/whatsmeow v0.0.0-20240927134544-69ba055bef0f/go.mod h1:UvaXcdb8y5Mryj2LSXAMw7u4/exnWJIXn8Gvpmf6ndI=
go.mau.fi/whatsmeow v0.0.0-20241009112614-70d73b690a8d h1:0OV2Ula2IGaoHVfvv7ns+Gn3xGT0SHn5yDecJBB8FQY=
go.mau.fi/whatsmeow v0.0.0-20241009112614-70d73b690a8d/go.mod h1:UvaXcdb8y5Mryj2LSXAMw7u4/exnWJIXn8Gvpmf6ndI=
go.mau.fi/whatsmeow v0.0.0-20241027175758-cd900353e4a7 h1:0qujZcpt0G1QFCrTgrXvnVg6yQU1IG1VbmHRHkWV0iY=
go.mau.fi/whatsmeow v0.0.0-20241027175758-cd900353e4a7/go.mod h1:UvaXcdb8y5Mryj2LSXAMw7u4/exnWJIXn8Gvpmf6ndI=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A=
golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw=
golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U=
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.19.0 h1:D9FX4QWkLfkeqaC62SonffIIuYdOk/UE2XKUBgRIBIQ= golang.org/x/image v0.19.0 h1:D9FX4QWkLfkeqaC62SonffIIuYdOk/UE2XKUBgRIBIQ=
golang.org/x/image v0.19.0/go.mod h1:y0zrRqlQRWQ5PXaYCOMLTW2fpsxZ8Qh9I/ohnInJEys= golang.org/x/image v0.19.0/go.mod h1:y0zrRqlQRWQ5PXaYCOMLTW2fpsxZ8Qh9I/ohnInJEys=
golang.org/x/image v0.20.0 h1:7cVCUjQwfL18gyBJOmYvptfSHS8Fb3YUDtfLIZ7Nbpw= golang.org/x/image v0.20.0 h1:7cVCUjQwfL18gyBJOmYvptfSHS8Fb3YUDtfLIZ7Nbpw=
golang.org/x/image v0.20.0/go.mod h1:0a88To4CYVBAHp5FXJm8o7QbUl37Vd85ply1vyD8auM= golang.org/x/image v0.20.0/go.mod h1:0a88To4CYVBAHp5FXJm8o7QbUl37Vd85ply1vyD8auM=
golang.org/x/image v0.21.0 h1:c5qV36ajHpdj4Qi0GnE0jUc/yuo33OLFaa0d+crTD5s=
golang.org/x/image v0.21.0/go.mod h1:vUbsLavqK/W303ZroQQVKQ+Af3Yl6Uz1Ppu5J/cLz78=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@ -132,6 +151,8 @@ golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo=
golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0=
golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -150,6 +171,8 @@ golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 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.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
@ -168,6 +191,8 @@ golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f h1:uF6paiQQebLeSXkrTqHqz
golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA=
google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

20
src/internal/rest/message.go

@ -18,6 +18,7 @@ func InitRestMessage(app *fiber.App, service domainMessage.IMessageService) Mess
app.Post("/message/:message_id/revoke", rest.RevokeMessage) app.Post("/message/:message_id/revoke", rest.RevokeMessage)
app.Post("/message/:message_id/delete", rest.DeleteMessage) app.Post("/message/:message_id/delete", rest.DeleteMessage)
app.Post("/message/:message_id/update", rest.UpdateMessage) app.Post("/message/:message_id/update", rest.UpdateMessage)
app.Post("/message/:message_id/read", rest.MarkAsRead)
return rest return rest
} }
@ -96,3 +97,22 @@ func (controller *Message) ReactMessage(c *fiber.Ctx) error {
Results: response, Results: response,
}) })
} }
func (controller *Message) MarkAsRead(c *fiber.Ctx) error {
var request message.MarkAsReadRequest
err := c.BodyParser(&request)
utils.PanicIfNeeded(err)
request.MessageID = c.Params("message_id")
whatsapp.SanitizePhone(&request.Phone)
response, err := controller.Service.MarkAsRead(c.UserContext(), request)
utils.PanicIfNeeded(err)
return c.JSON(utils.ResponseData{
Status: 200,
Code: "SUCCESS",
Message: response.Status,
Results: response,
})
}

32
src/internal/rest/newsletter.go

@ -0,0 +1,32 @@
package rest
import (
domainNewsletter "github.com/aldinokemal/go-whatsapp-web-multidevice/domains/newsletter"
"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",
})
}

13
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/avatar", rest.UserAvatar)
app.Get("/user/my/privacy", rest.UserMyPrivacySetting) app.Get("/user/my/privacy", rest.UserMyPrivacySetting)
app.Get("/user/my/groups", rest.UserMyListGroups) app.Get("/user/my/groups", rest.UserMyListGroups)
app.Get("/user/my/newsletters", rest.UserMyListNewsletter)
return rest return rest
} }
@ -80,3 +81,15 @@ func (controller *User) UserMyListGroups(c *fiber.Ctx) error {
Results: response, 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,
})
}

32
src/pkg/whatsapp/whatsapp.go

@ -107,17 +107,19 @@ func ParseJID(arg string) (types.JID, error) {
} }
if !strings.ContainsRune(arg, '@') { if !strings.ContainsRune(arg, '@') {
return types.NewJID(arg, types.DefaultUserServer), nil 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 { func IsOnWhatsapp(waCli *whatsmeow.Client, jid string) bool {
@ -461,12 +463,12 @@ func ExtractMedia(storageLocation string, mediaFile whatsmeow.DownloadableMessag
logrus.Info("Skip download because data is nil") logrus.Info("Skip download because data is nil")
return extractedMedia, nil return extractedMedia, nil
} }
data, err := cli.Download(mediaFile) data, err := cli.Download(mediaFile)
if err != nil { if err != nil {
return extractedMedia, err return extractedMedia, err
} }
switch media := mediaFile.(type) { switch media := mediaFile.(type) {
case *waE2E.ImageMessage: case *waE2E.ImageMessage:
extractedMedia.MimeType = media.GetMimetype() extractedMedia.MimeType = media.GetMimetype()
@ -482,19 +484,19 @@ func ExtractMedia(storageLocation string, mediaFile whatsmeow.DownloadableMessag
extractedMedia.MimeType = media.GetMimetype() extractedMedia.MimeType = media.GetMimetype()
extractedMedia.Caption = media.GetCaption() extractedMedia.Caption = media.GetCaption()
} }
var extension string var extension string
if ext, err := mime.ExtensionsByType(extractedMedia.MimeType); err != nil && len(ext) > 0 { if ext, err := mime.ExtensionsByType(extractedMedia.MimeType); err != nil && len(ext) > 0 {
extension = ext[0] extension = ext[0]
} else if parts := strings.Split(extractedMedia.MimeType, "/"); len(parts) > 1 { } else if parts := strings.Split(extractedMedia.MimeType, "/"); len(parts) > 1 {
extension = "." + parts[len(parts)-1] extension = "." + parts[len(parts)-1]
} }
extractedMedia.MediaPath = fmt.Sprintf("%s/%d-%s%s", storageLocation, time.Now().Unix(), uuid.NewString(), extension) extractedMedia.MediaPath = fmt.Sprintf("%s/%d-%s%s", storageLocation, time.Now().Unix(), uuid.NewString(), extension)
err = os.WriteFile(extractedMedia.MediaPath, data, 0600) err = os.WriteFile(extractedMedia.MediaPath, data, 0600)
if err != nil { if err != nil {
return extractedMedia, err return extractedMedia, err
} }
}
}
return extractedMedia, nil return extractedMedia, nil
} }

27
src/services/message.go

@ -7,6 +7,7 @@ import (
domainMessage "github.com/aldinokemal/go-whatsapp-web-multidevice/domains/message" domainMessage "github.com/aldinokemal/go-whatsapp-web-multidevice/domains/message"
"github.com/aldinokemal/go-whatsapp-web-multidevice/pkg/whatsapp" "github.com/aldinokemal/go-whatsapp-web-multidevice/pkg/whatsapp"
"github.com/aldinokemal/go-whatsapp-web-multidevice/validations" "github.com/aldinokemal/go-whatsapp-web-multidevice/validations"
"github.com/sirupsen/logrus"
"go.mau.fi/whatsmeow" "go.mau.fi/whatsmeow"
"go.mau.fi/whatsmeow/appstate" "go.mau.fi/whatsmeow/appstate"
"go.mau.fi/whatsmeow/proto/waCommon" "go.mau.fi/whatsmeow/proto/waCommon"
@ -27,6 +28,32 @@ func NewMessageService(waCli *whatsmeow.Client) domainMessage.IMessageService {
} }
} }
func (service serviceMessage) MarkAsRead(ctx context.Context, request domainMessage.MarkAsReadRequest) (response domainMessage.GenericResponse, err error) {
if err = validations.ValidateMarkAsRead(ctx, request); err != nil {
return response, err
}
dataWaRecipient, err := whatsapp.ValidateJidWithLogin(service.WaCli, request.Phone)
if err != nil {
return response, err
}
ids := []types.MessageID{request.MessageID}
if err = service.WaCli.MarkRead(ids, time.Now(), dataWaRecipient, *service.WaCli.Store.ID); err != nil {
return response, err
}
logrus.Info(map[string]interface{}{
"phone": request.Phone,
"message_id": request.MessageID,
"chat": dataWaRecipient.String(),
"sender": service.WaCli.Store.ID.String(),
})
response.MessageID = request.MessageID
response.Status = fmt.Sprintf("Mark as read success %s", request.MessageID)
return response, nil
}
func (service serviceMessage) ReactMessage(ctx context.Context, request message.ReactionRequest) (response message.GenericResponse, err error) { func (service serviceMessage) ReactMessage(ctx context.Context, request message.ReactionRequest) (response message.GenericResponse, err error) {
if err = validations.ValidateReactMessage(ctx, request); err != nil { if err = validations.ValidateReactMessage(ctx, request); err != nil {
return response, err return response, err

32
src/services/newsletter.go

@ -0,0 +1,32 @@
package services
import (
"context"
domainNewsletter "github.com/aldinokemal/go-whatsapp-web-multidevice/domains/newsletter"
"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)
}

20
src/services/send.go

@ -17,6 +17,7 @@ import (
"github.com/valyala/fasthttp" "github.com/valyala/fasthttp"
"go.mau.fi/whatsmeow" "go.mau.fi/whatsmeow"
"go.mau.fi/whatsmeow/proto/waE2E" "go.mau.fi/whatsmeow/proto/waE2E"
"go.mau.fi/whatsmeow/types"
"google.golang.org/protobuf/proto" "google.golang.org/protobuf/proto"
"net/http" "net/http"
"os" "os"
@ -157,7 +158,7 @@ func (service serviceSend) SendImage(ctx context.Context, request domainSend.Ima
if err != nil { if err != nil {
return response, err return response, err
} }
uploadedImage, err := service.WaCli.Upload(context.Background(), dataWaImage, whatsmeow.MediaImage)
uploadedImage, err := service.uploadMedia(ctx, whatsmeow.MediaImage, dataWaImage, dataWaRecipient)
if err != nil { if err != nil {
fmt.Printf("failed to upload file: %v", err) fmt.Printf("failed to upload file: %v", err)
return response, err return response, err
@ -209,7 +210,7 @@ func (service serviceSend) SendFile(ctx context.Context, request domainSend.File
fileMimeType := http.DetectContentType(fileBytes) fileMimeType := http.DetectContentType(fileBytes)
// Send to WA server // Send to WA server
uploadedFile, err := service.WaCli.Upload(context.Background(), fileBytes, whatsmeow.MediaDocument)
uploadedFile, err := service.uploadMedia(ctx, whatsmeow.MediaDocument, fileBytes, dataWaRecipient)
if err != nil { if err != nil {
fmt.Printf("Failed to upload file: %v", err) fmt.Printf("Failed to upload file: %v", err)
return response, err return response, err
@ -311,7 +312,7 @@ func (service serviceSend) SendVideo(ctx context.Context, request domainSend.Vid
if err != nil { if err != nil {
return response, err return response, err
} }
uploaded, err := service.WaCli.Upload(context.Background(), dataWaVideo, whatsmeow.MediaVideo)
uploaded, err := service.uploadMedia(ctx, whatsmeow.MediaVideo, dataWaVideo, dataWaRecipient)
if err != nil { if err != nil {
return response, pkgError.InternalServerError(fmt.Sprintf("Failed to upload file: %v", err)) return response, pkgError.InternalServerError(fmt.Sprintf("Failed to upload file: %v", err))
} }
@ -448,7 +449,7 @@ func (service serviceSend) SendAudio(ctx context.Context, request domainSend.Aud
autioBytes := helpers.MultipartFormFileHeaderToBytes(request.Audio) autioBytes := helpers.MultipartFormFileHeaderToBytes(request.Audio)
audioMimeType := http.DetectContentType(autioBytes) audioMimeType := http.DetectContentType(autioBytes)
audioUploaded, err := service.WaCli.Upload(ctx, autioBytes, whatsmeow.MediaAudio)
audioUploaded, err := service.uploadMedia(ctx, whatsmeow.MediaAudio, autioBytes, dataWaRecipient)
if err != nil { if err != nil {
err = pkgError.WaUploadMediaError(fmt.Sprintf("Failed to upload audio: %v", err)) err = pkgError.WaUploadMediaError(fmt.Sprintf("Failed to upload audio: %v", err))
return response, err return response, err
@ -496,7 +497,7 @@ func (service serviceSend) SendPoll(ctx context.Context, request domainSend.Poll
return response, nil return response, nil
} }
func (service serviceSend) getMentionFromText(ctx context.Context, messages string) (result []string) {
func (service serviceSend) getMentionFromText(_ context.Context, messages string) (result []string) {
mentions := utils.ContainsMention(messages) mentions := utils.ContainsMention(messages)
for _, mention := range mentions { for _, mention := range mentions {
// Get JID from phone number // Get JID from phone number
@ -507,3 +508,12 @@ func (service serviceSend) getMentionFromText(ctx context.Context, messages stri
return result return result
} }
func (service serviceSend) uploadMedia(ctx context.Context, mediaType whatsmeow.MediaType, media []byte, recipient types.JID) (uploaded whatsmeow.UploadResponse, err error) {
if recipient.Server == types.NewsletterServer {
uploaded, err = service.WaCli.UploadNewsletter(ctx, media, mediaType)
} else {
uploaded, err = service.WaCli.Upload(ctx, media, mediaType)
}
return uploaded, err
}

14
src/services/user.go

@ -127,6 +127,20 @@ func (service userService) MyListGroups(_ context.Context) (response domainUser.
return response, nil 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) { func (service userService) MyPrivacySetting(_ context.Context) (response domainUser.MyPrivacySettingResponse, err error) {
whatsapp.MustLogin(service.WaCli) whatsapp.MustLogin(service.WaCli)

14
src/validations/message_validation.go

@ -8,6 +8,20 @@ import (
validation "github.com/go-ozzo/ozzo-validation/v4" validation "github.com/go-ozzo/ozzo-validation/v4"
) )
func ValidateMarkAsRead(ctx context.Context, request domainMessage.MarkAsReadRequest) error {
err := validation.ValidateStructWithContext(ctx, &request,
validation.Field(&request.MessageID, validation.Required),
validation.Field(&request.Phone, validation.Required),
)
if err != nil {
return pkgError.ValidationError(err.Error())
}
return nil
}
func ValidateRevokeMessage(ctx context.Context, request domainMessage.RevokeRequest) error { func ValidateRevokeMessage(ctx context.Context, request domainMessage.RevokeRequest) error {
err := validation.ValidateStructWithContext(ctx, &request, err := validation.ValidateStructWithContext(ctx, &request,
validation.Field(&request.Phone, validation.Required), validation.Field(&request.Phone, validation.Required),

20
src/validations/newsletter_validation.go

@ -0,0 +1,20 @@
package validations
import (
"context"
domainNewsletter "github.com/aldinokemal/go-whatsapp-web-multidevice/domains/newsletter"
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
}

26
src/views/components/AccountAvatar.js

@ -1,10 +1,14 @@
import { NumberFormatLocale } from './funcoes.js'
import { NumberFormatLocale } from './funcoes.js';
import FormRecipient from "./generic/FormRecipient.js";
export default { export default {
name: 'AccountAvatar', name: 'AccountAvatar',
components: {
FormRecipient
},
data() { data() {
return { return {
type: 'user',
type: window.TYPEUSER,
phone: '', phone: '',
image: null, image: null,
loading: false, loading: false,
@ -14,7 +18,7 @@ export default {
}, },
computed: { computed: {
phone_id() { phone_id() {
return this.type === 'user' ? `${NumberFormatLocale(this.phone)}@${window.TYPEUSER}` : `${NumberFormatLocale(this.phone)}@${window.TYPEGROUP}`
return NumberFormatLocale(this.phone) + this.type;
} }
}, },
methods: { methods: {
@ -47,7 +51,7 @@ export default {
handleReset() { handleReset() {
this.phone = ''; this.phone = '';
this.image = null; this.image = null;
this.type = 'user';
this.type = window.TYPEUSER;
} }
}, },
template: ` template: `
@ -68,19 +72,7 @@ export default {
</div> </div>
<div class="content"> <div class="content">
<form class="ui form"> <form class="ui form">
<div class="field">
<label>Type</label>
<select name="type" v-model="type" aria-label="type">
<option value="group">Group Message</option>
<option value="user">Private Message</option>
</select>
</div>
<div class="field">
<label>Phone</label>
<input v-model="phone" type="text" placeholder="6289..."
aria-label="phone">
<input :value="phone_id" disabled aria-label="whatsapp_id">
</div>
<FormRecipient v-model:type="type" v-model:phone="phone"/>
<div class="field"> <div class="field">
<label>Preview</label> <label>Preview</label>

24
src/views/components/AccountUserInfo.js

@ -1,10 +1,13 @@
import { NumberFormatLocale } from './funcoes.js'
import FormRecipient from "./generic/FormRecipient.js";
export default { export default {
name: 'AccountUserInfo', name: 'AccountUserInfo',
components: {
FormRecipient
},
data() { data() {
return { return {
type: 'user',
type: window.TYPEUSER,
phone: '', phone: '',
// //
name: null, name: null,
@ -17,7 +20,7 @@ export default {
computed: { computed: {
phone_id() { phone_id() {
return this.type === 'user' ? `${NumberFormatLocale(this.phone)}@${window.TYPEUSER}` : `${NumberFormatLocale(this.phone)}@${window.TYPEGROUP}`
return this.phone + this.type;
} }
}, },
methods: { methods: {
@ -54,7 +57,7 @@ export default {
this.name = null; this.name = null;
this.status = null; this.status = null;
this.devices = []; this.devices = [];
this.type = 'user';
this.type = window.TYPEUSER;
} }
}, },
template: ` template: `
@ -76,18 +79,7 @@ export default {
</div> </div>
<div class="content"> <div class="content">
<form class="ui form"> <form class="ui form">
<div class="field">
<label>Type</label>
<select name="type" v-model="type" aria-label="type">
<option value="user">Private Message</option>
</select>
</div>
<div class="field">
<label>Phone</label>
<input v-model="phone" type="text" placeholder="6289..."
aria-label="phone">
<input :value="phone_id" disabled aria-label="whatsapp_id">
</div>
<FormRecipient v-model:type="type" v-model:phone="phone"/>
<button type="button" class="ui primary button" :class="{'loading': loading}" <button type="button" class="ui primary button" :class="{'loading': loading}"
@click="handleSubmit"> @click="handleSubmit">

2
src/views/components/GroupManageParticipants.js

@ -10,7 +10,7 @@ export default {
}, },
computed: { computed: {
group_id() { group_id() {
return `${this.group}@${window.TYPEGROUP}`;
return `${this.group}${window.TYPEGROUP}`;
}, },
}, },
methods: { methods: {

27
src/views/components/MessageDelete.js

@ -1,10 +1,14 @@
import { NumberFormatLocale } from './funcoes.js'
import { NumberFormatLocale } from './funcoes.js';
import FormRecipient from "./generic/FormRecipient.js";
export default { export default {
name: 'DeleteMessage', name: 'DeleteMessage',
components: {
FormRecipient
},
data() { data() {
return { return {
type: 'user',
type: window.TYPEUSER,
phone: '', phone: '',
message_id: '', message_id: '',
loading: false, loading: false,
@ -12,7 +16,7 @@ export default {
}, },
computed: { computed: {
phone_id() { phone_id() {
return this.type === 'user' ? `${NumberFormatLocale(this.phone)}@${window.TYPEUSER}` : `${NumberFormatLocale(this.phone)}@${window.TYPEGROUP}`
return NumberFormatLocale(this.phone) + this.type;
} }
}, },
methods: { methods: {
@ -50,7 +54,7 @@ export default {
} }
}, },
handleReset() { handleReset() {
this.type = 'user';
this.type = window.TYPEUSER;
this.phone = ''; this.phone = '';
this.message_id = ''; this.message_id = '';
this.new_message = ''; this.new_message = '';
@ -76,19 +80,8 @@ export default {
</div> </div>
<div class="content"> <div class="content">
<form class="ui form"> <form class="ui form">
<div class="field">
<label>Type</label>
<select name="type" v-model="type" aria-label="type">
<option value="group">Group Message</option>
<option value="user">Private Message</option>
</select>
</div>
<div class="field">
<label>Phone / Group ID</label>
<input v-model="phone" type="text" placeholder="6289..."
aria-label="phone">
<input :value="phone_id" disabled aria-label="whatsapp_id">
</div>
<FormRecipient v-model:type="type" v-model:phone="phone"/>
<div class="field"> <div class="field">
<label>Message ID</label> <label>Message ID</label>
<input v-model="message_id" type="text" placeholder="Please enter your message id" <input v-model="message_id" type="text" placeholder="Please enter your message id"

27
src/views/components/MessageReact.js

@ -1,10 +1,14 @@
import { NumberFormatLocale } from './funcoes.js'
import { NumberFormatLocale } from './funcoes.js';
import FormRecipient from "./generic/FormRecipient.js";
export default { export default {
name: 'ReactMessage', name: 'ReactMessage',
components: {
FormRecipient
},
data() { data() {
return { return {
type: 'user',
type: window.TYPEUSER,
phone: '', phone: '',
message_id: '', message_id: '',
emoji: '', emoji: '',
@ -13,7 +17,7 @@ export default {
}, },
computed: { computed: {
phone_id() { phone_id() {
return this.type === 'user' ? `${NumberFormatLocale(this.phone)}@${window.TYPEUSER}` : `${NumberFormatLocale(this.phone)}@${window.TYPEGROUP}`
return NumberFormatLocale(this.phone) + this.type;
} }
}, },
methods: { methods: {
@ -53,7 +57,7 @@ export default {
this.phone = ''; this.phone = '';
this.message_id = ''; this.message_id = '';
this.emoji = ''; this.emoji = '';
this.type = 'user';
this.type = window.TYPEUSER;
}, },
}, },
template: ` template: `
@ -76,19 +80,8 @@ export default {
</div> </div>
<div class="content"> <div class="content">
<form class="ui form"> <form class="ui form">
<div class="field">
<label>Type</label>
<select name="type" v-model="type" aria-label="type">
<option value="group">Group Message</option>
<option value="user">Private Message</option>
</select>
</div>
<div class="field">
<label>Phone / Group ID</label>
<input v-model="phone" type="text" placeholder="6289..."
aria-label="phone">
<input :value="phone_id" disabled aria-label="whatsapp_id">
</div>
<FormRecipient v-model:type="type" v-model:phone="phone"/>
<div class="field"> <div class="field">
<label>Message ID</label> <label>Message ID</label>
<input v-model="message_id" type="text" placeholder="Please enter your message id" <input v-model="message_id" type="text" placeholder="Please enter your message id"

27
src/views/components/MessageRevoke.js

@ -1,10 +1,14 @@
import { NumberFormatLocale } from './funcoes.js'
import { NumberFormatLocale } from './funcoes.js';
import FormRecipient from "./generic/FormRecipient.js";
export default { export default {
name: 'Message', name: 'Message',
components: {
FormRecipient
},
data() { data() {
return { return {
type: 'user',
type: window.TYPEUSER,
phone: '', phone: '',
message_id: '', message_id: '',
loading: false, loading: false,
@ -12,7 +16,7 @@ export default {
}, },
computed: { computed: {
phone_id() { phone_id() {
return this.type === 'user' ? `${NumberFormatLocale(this.phone)}@${window.TYPEUSER}` : `${NumberFormatLocale(this.phone)}@${window.TYPEGROUP}`
return NumberFormatLocale(this.phone) + this.type;
} }
}, },
methods: { methods: {
@ -51,7 +55,7 @@ export default {
handleReset() { handleReset() {
this.phone = ''; this.phone = '';
this.message_id = ''; this.message_id = '';
this.type = 'user';
this.type = window.TYPEUSER;
}, },
}, },
template: ` template: `
@ -73,19 +77,8 @@ export default {
</div> </div>
<div class="content"> <div class="content">
<form class="ui form"> <form class="ui form">
<div class="field">
<label>Type</label>
<select name="type" v-model="type" aria-label="type">
<option value="group">Group Message</option>
<option value="user">Private Message</option>
</select>
</div>
<div class="field">
<label>Phone / Group ID</label>
<input v-model="phone" type="text" placeholder="6289..."
aria-label="phone">
<input :value="phone_id" disabled aria-label="whatsapp_id">
</div>
<FormRecipient v-model:type="type" v-model:phone="phone"/>
<div class="field"> <div class="field">
<label> Message ID</label> <label> Message ID</label>
<input v-model="message_id" type="text" placeholder="Please enter your message id" <input v-model="message_id" type="text" placeholder="Please enter your message id"

27
src/views/components/MessageUpdate.js

@ -1,10 +1,14 @@
import { NumberFormatLocale } from './funcoes.js'
import { NumberFormatLocale } from './funcoes.js';
import FormRecipient from "./generic/FormRecipient.js";
export default { export default {
name: 'UpdateMessage', name: 'UpdateMessage',
components: {
FormRecipient
},
data() { data() {
return { return {
type: 'user',
type: window.TYPEUSER,
phone: '', phone: '',
message_id: '', message_id: '',
new_message: '', new_message: '',
@ -13,7 +17,7 @@ export default {
}, },
computed: { computed: {
phone_id() { phone_id() {
return this.type === 'user' ? `${NumberFormatLocale(this.phone)}@${window.TYPEUSER}` : `${NumberFormatLocale(this.phone)}@${window.TYPEGROUP}`
return NumberFormatLocale(this.phone) + this.type;
} }
}, },
methods: { methods: {
@ -51,7 +55,7 @@ export default {
} }
}, },
handleReset() { handleReset() {
this.type = 'user';
this.type = window.TYPEUSER;
this.phone = ''; this.phone = '';
this.message_id = ''; this.message_id = '';
this.new_message = ''; this.new_message = '';
@ -77,19 +81,8 @@ export default {
</div> </div>
<div class="content"> <div class="content">
<form class="ui form"> <form class="ui form">
<div class="field">
<label>Type</label>
<select name="type" v-model="type" aria-label="type">
<option value="group">Group Message</option>
<option value="user">Private Message</option>
</select>
</div>
<div class="field">
<label>Phone / Group ID</label>
<input v-model="phone" type="text" placeholder="6289..."
aria-label="phone">
<input :value="phone_id" disabled aria-label="whatsapp_id">
</div>
<FormRecipient v-model:type="type" v-model:phone="phone"/>
<div class="field"> <div class="field">
<label>Message ID</label> <label>Message ID</label>
<input v-model="message_id" type="text" placeholder="Please enter your message id" <input v-model="message_id" type="text" placeholder="Please enter your message id"

117
src/views/components/NewsletterList.js

@ -0,0 +1,117 @@
export default {
name: 'ListNewsletter',
data() {
return {
newsletters: []
}
},
methods: {
async openModal() {
try {
this.dtClear()
await this.submitApi();
$('#modalNewsletterList').modal('show');
this.dtRebuild()
showSuccessInfo("Newsletters fetched")
} catch (err) {
showErrorInfo(err)
}
},
dtClear() {
$('#account_newsletters_table').DataTable().destroy();
},
dtRebuild() {
$('#account_newsletters_table').DataTable({
"pageLength": 100,
"reloadData": true,
}).draw();
},
async handleUnfollowNewsletter(newsletter_id) {
try {
const ok = confirm("Are you sure to leave this newsletter?");
if (!ok) return;
await this.unfollowNewsletterApi(newsletter_id);
this.dtClear()
await this.submitApi();
this.dtRebuild()
showSuccessInfo("Success unfollow newsletter")
} catch (err) {
showErrorInfo(err)
}
},
async unfollowNewsletterApi(newsletter_id) {
try {
let payload = {
newsletter_id: newsletter_id
};
await window.http.post(`/newsletter/unfollow`, payload)
} catch (error) {
if (error.response) {
throw new Error(error.response.data.message);
}
throw new Error(error.message);
}
},
async submitApi() {
try {
let response = await window.http.get(`/user/my/newsletters`)
this.newsletters = response.data.results.data;
} catch (error) {
if (error.response) {
throw new Error(error.response.data.message);
}
throw new Error(error.message);
}
},
formatDate: function (value) {
if (!value) return ''
if (isNaN(value)) return 'Invalid date';
return moment.unix(value).format('LLL');
}
},
template: `
<div class="green card" @click="openModal" style="cursor: pointer">
<div class="content">
<a class="ui green right ribbon label">Newsletter</a>
<div class="header">List Newsletters</div>
<div class="description">
Display all your newsletters
</div>
</div>
</div>
<!-- Modal AccountNewsletter -->
<div class="ui small modal" id="modalNewsletterList">
<i class="close icon"></i>
<div class="header">
My Newsletter List
</div>
<div class="content">
<table class="ui celled table" id="account_newsletters_table">
<thead>
<tr>
<th>Newsletter ID</th>
<th>Name</th>
<th>Role</th>
<th>Created At</th>
<th>Action</th>
</tr>
</thead>
<tbody v-if="newsletters != null">
<tr v-for="n in newsletters">
<td>{{ n.id.split('@')[0] }}</td>
<td>{{ n.thread_metadata?.name?.text || 'N/A' }}</td>
<td>{{ n.viewer_metadata?.role || 'N/A' }}</td>
<td>{{ formatDate(n.thread_metadata?.creation_time) }}</td>
<td>
<button class="ui red tiny button" @click="handleUnfollowNewsletter(n.id)">Unfollow</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
`
}

26
src/views/components/SendAudio.js

@ -1,17 +1,21 @@
import { NumberFormatLocale } from './funcoes.js'
import { NumberFormatLocale } from './funcoes.js';
import FormRecipient from "./generic/FormRecipient.js";
export default { export default {
name: 'Send', name: 'Send',
components: {
FormRecipient
},
data() { data() {
return { return {
phone: '', phone: '',
type: 'user',
type: window.TYPEUSER,
loading: false, loading: false,
} }
}, },
computed: { computed: {
phone_id() { phone_id() {
return this.type === 'user' ? `${NumberFormatLocale(this.phone)}@${window.TYPEUSER}` : `${NumberFormatLocale(this.phone)}@${window.TYPEGROUP}`
return NumberFormatLocale(this.phone) + this.type;
} }
}, },
methods: { methods: {
@ -51,7 +55,7 @@ export default {
}, },
handleReset() { handleReset() {
this.phone = ''; this.phone = '';
this.type = 'user';
this.type = window.TYPEUSER;
$("#file_audio").val(''); $("#file_audio").val('');
}, },
}, },
@ -74,19 +78,7 @@ export default {
</div> </div>
<div class="content"> <div class="content">
<form class="ui form"> <form class="ui form">
<div class="field">
<label>Type</label>
<select name="type" v-model="type" aria-label="type">
<option value="group">Group Message</option>
<option value="user">Private Message</option>
</select>
</div>
<div class="field">
<label>Phone / Group ID</label>
<input v-model="phone" type="text" placeholder="6289..."
aria-label="phone">
<input :value="phone_id" disabled aria-label="whatsapp_id">
</div>
<FormRecipient v-model:type="type" v-model:phone="phone"/>
<div class="field" style="padding-bottom: 30px"> <div class="field" style="padding-bottom: 30px">
<label>Audio</label> <label>Audio</label>
<input type="file" style="display: none" accept="audio/*" id="file_audio"/> <input type="file" style="display: none" accept="audio/*" id="file_audio"/>

27
src/views/components/SendContact.js

@ -1,10 +1,14 @@
import { NumberFormatLocale } from './funcoes.js'
import { NumberFormatLocale } from './funcoes.js';
import FormRecipient from "./generic/FormRecipient.js";
export default { export default {
name: 'SendContact', name: 'SendContact',
components: {
FormRecipient
},
data() { data() {
return { return {
type: 'user',
type: window.TYPEUSER,
phone: '', phone: '',
card_name: '', card_name: '',
card_phone: '', card_phone: '',
@ -13,7 +17,7 @@ export default {
}, },
computed: { computed: {
phone_id() { phone_id() {
return this.type === 'user' ? `${NumberFormatLocale(this.phone)}@${window.TYPEUSER}` : `${NumberFormatLocale(this.phone)}@${window.TYPEGROUP}`
return NumberFormatLocale(this.phone) + this.type;
} }
}, },
methods: { methods: {
@ -60,7 +64,7 @@ export default {
this.phone = ''; this.phone = '';
this.card_name = ''; this.card_name = '';
this.card_phone = ''; this.card_phone = '';
this.type = 'user';
this.type = window.TYPEUSER;
}, },
}, },
template: ` template: `
@ -82,19 +86,8 @@ export default {
</div> </div>
<div class="content"> <div class="content">
<form class="ui form"> <form class="ui form">
<div class="field">
<label>Type</label>
<select name="type" v-model="type" aria-label="type">
<option value="group">Group Message</option>
<option value="user">Private Message</option>
</select>
</div>
<div class="field">
<label>Phone / Group ID</label>
<input v-model="phone" type="text" placeholder="6289..."
aria-label="phone">
<input :value="phone_id" disabled aria-label="whatsapp_id">
</div>
<FormRecipient v-model:type="type" v-model:phone="phone"/>
<div class="field"> <div class="field">
<label>Contact Name</label> <label>Contact Name</label>
<input v-model="card_name" type="text" placeholder="Please enter contact name" <input v-model="card_name" type="text" placeholder="Please enter contact name"

27
src/views/components/SendFile.js

@ -1,7 +1,11 @@
import { NumberFormatLocale } from './funcoes.js'
import { NumberFormatLocale } from './funcoes.js';
import FormRecipient from "./generic/FormRecipient.js";
export default { export default {
name: 'SendFile', name: 'SendFile',
components: {
FormRecipient
},
props: { props: {
maxFileSize: { maxFileSize: {
type: String, type: String,
@ -11,14 +15,14 @@ export default {
data() { data() {
return { return {
caption: '', caption: '',
type: 'user',
type: window.TYPEUSER,
phone: '', phone: '',
loading: false, loading: false,
} }
}, },
computed: { computed: {
phone_id() { phone_id() {
return this.type === 'user' ? `${NumberFormatLocale(this.phone)}@${window.TYPEUSER}` : `${NumberFormatLocale(this.phone)}@${window.TYPEGROUP}`
return NumberFormatLocale(this.phone) + this.type;
} }
}, },
methods: { methods: {
@ -60,7 +64,7 @@ export default {
handleReset() { handleReset() {
this.caption = ''; this.caption = '';
this.phone = ''; this.phone = '';
this.type = 'user';
this.type = window.TYPEUSER;
$("#file_file").val(''); $("#file_file").val('');
}, },
}, },
@ -84,19 +88,8 @@ export default {
</div> </div>
<div class="content"> <div class="content">
<form class="ui form"> <form class="ui form">
<div class="field">
<label>Type</label>
<select name="type" v-model="type" aria-label="type">
<option value="group">Group Message</option>
<option value="user">Private Message</option>
</select>
</div>
<div class="field">
<label>Phone / Group ID</label>
<input v-model="phone" type="text" placeholder="6289..."
aria-label="phone">
<input :value="phone_id" disabled aria-label="whatsapp_id">
</div>
<FormRecipient v-model:type="type" v-model:phone="phone"/>
<div class="field"> <div class="field">
<label>Caption</label> <label>Caption</label>
<textarea v-model="caption" placeholder="Type some caption (optional)..." <textarea v-model="caption" placeholder="Type some caption (optional)..."

27
src/views/components/SendImage.js

@ -1,21 +1,25 @@
import { NumberFormatLocale } from './funcoes.js'
import { NumberFormatLocale } from './funcoes.js';
import FormRecipient from "./generic/FormRecipient.js";
export default { export default {
name: 'SendImage', name: 'SendImage',
components: {
FormRecipient
},
data() { data() {
return { return {
phone: '', phone: '',
view_once: false, view_once: false,
compress: false, compress: false,
caption: '', caption: '',
type: 'user',
type: window.TYPEUSER,
loading: false, loading: false,
selected_file: null selected_file: null
} }
}, },
computed: { computed: {
phone_id() { phone_id() {
return this.type === 'user' ? `${NumberFormatLocale(this.phone)}@${window.TYPEUSER}` : `${NumberFormatLocale(this.phone)}@${window.TYPEGROUP}`
return NumberFormatLocale(this.phone) + this.type;
} }
}, },
methods: { methods: {
@ -62,7 +66,7 @@ export default {
this.compress = false; this.compress = false;
this.phone = ''; this.phone = '';
this.caption = ''; this.caption = '';
this.type = 'user';
this.type = window.TYPEUSER;
$("#file_image").val(''); $("#file_image").val('');
}, },
}, },
@ -87,19 +91,8 @@ export default {
</div> </div>
<div class="content"> <div class="content">
<form class="ui form"> <form class="ui form">
<div class="field">
<label>Type</label>
<select name="type" v-model="type" aria-label="type">
<option value="group">Group Message</option>
<option value="user">Private Message</option>
</select>
</div>
<div class="field">
<label>Phone / Group ID</label>
<input v-model="phone" type="text" placeholder="6289..."
aria-label="phone">
<input :value="phone_id" disabled aria-label="whatsapp_id">
</div>
<FormRecipient v-model:type="type" v-model:phone="phone"/>
<div class="field"> <div class="field">
<label>Caption</label> <label>Caption</label>
<textarea v-model="caption" type="text" placeholder="Hello this is image caption" <textarea v-model="caption" type="text" placeholder="Hello this is image caption"

27
src/views/components/SendLocation.js

@ -1,10 +1,14 @@
import { NumberFormatLocale } from './funcoes.js'
import { NumberFormatLocale } from './funcoes.js';
import FormRecipient from "./generic/FormRecipient.js";
export default { export default {
name: 'SendLocation', name: 'SendLocation',
components: {
FormRecipient
},
data() { data() {
return { return {
type: 'user',
type: window.TYPEUSER,
phone: '', phone: '',
latitude: '', latitude: '',
longitude: '', longitude: '',
@ -13,7 +17,7 @@ export default {
}, },
computed: { computed: {
phone_id() { phone_id() {
return this.type === 'user' ? `${NumberFormatLocale(this.phone)}@${window.TYPEUSER}` : `${NumberFormatLocale(this.phone)}@${window.TYPEGROUP}`
return NumberFormatLocale(this.phone) + this.type;
} }
}, },
methods: { methods: {
@ -58,7 +62,7 @@ export default {
this.phone = ''; this.phone = '';
this.latitude = ''; this.latitude = '';
this.longitude = ''; this.longitude = '';
this.type = 'user';
this.type = window.TYPEUSER;
}, },
}, },
template: ` template: `
@ -80,19 +84,8 @@ export default {
</div> </div>
<div class="content"> <div class="content">
<form class="ui form"> <form class="ui form">
<div class="field">
<label>Type</label>
<select name="type" v-model="type" aria-label="type">
<option value="group">Group Message</option>
<option value="user">Private Message</option>
</select>
</div>
<div class="field">
<label>Phone / Group ID</label>
<input v-model="phone" type="text" placeholder="6289..."
aria-label="phone">
<input :value="phone_id" disabled aria-label="whatsapp_id">
</div>
<FormRecipient v-model:type="type" v-model:phone="phone"/>
<div class="field"> <div class="field">
<label>Location Latitude</label> <label>Location Latitude</label>
<input v-model="latitude" type="text" placeholder="Please enter latitude" <input v-model="latitude" type="text" placeholder="Please enter latitude"

26
src/views/components/SendMessage.js

@ -1,10 +1,14 @@
import { NumberFormatLocale } from './funcoes.js'
import { NumberFormatLocale } from './funcoes.js';
import FormRecipient from "./generic/FormRecipient.js";
export default { export default {
name: 'SendMessage', name: 'SendMessage',
components: {
FormRecipient
},
data() { data() {
return { return {
type: 'user',
type: window.TYPEUSER,
phone: '', phone: '',
text: '', text: '',
reply_message_id: '', reply_message_id: '',
@ -13,7 +17,7 @@ export default {
}, },
computed: { computed: {
phone_id() { phone_id() {
return this.type === 'user' ? `${NumberFormatLocale(this.phone)}@${window.TYPEUSER}` : `${NumberFormatLocale(this.phone)}@${window.TYPEGROUP}`
return NumberFormatLocale(this.phone) + this.type;
} }
}, },
methods: { methods: {
@ -59,7 +63,7 @@ export default {
handleReset() { handleReset() {
this.phone = ''; this.phone = '';
this.text = ''; this.text = '';
this.type = 'user';
this.type = window.TYPEUSER;
this.reply_message_id = ''; this.reply_message_id = '';
}, },
}, },
@ -82,19 +86,7 @@ export default {
</div> </div>
<div class="content"> <div class="content">
<form class="ui form"> <form class="ui form">
<div class="field">
<label>Type</label>
<select name="type" v-model="type" aria-label="type">
<option value="group">Group Message</option>
<option value="user">Private Message</option>
</select>
</div>
<div class="field">
<label>Phone / Group ID</label>
<input v-model="phone" type="text" placeholder="6289..."
aria-label="phone">
<input :value="phone_id" disabled aria-label="whatsapp_id">
</div>
<FormRecipient v-model:type="type" v-model:phone="phone"/>
<div class="field"> <div class="field">
<label>Reply Message ID</label> <label>Reply Message ID</label>
<input v-model="reply_message_id" type="text" <input v-model="reply_message_id" type="text"

29
src/views/components/SendPoll.js

@ -1,12 +1,16 @@
import { NumberFormatLocale } from './funcoes.js'
import { NumberFormatLocale } from './funcoes.js';
// export Vue Component // export Vue Component
import FormRecipient from "./generic/FormRecipient.js";
export default { export default {
name: 'SendPoll', name: 'SendPoll',
components: {
FormRecipient
},
data() { data() {
return { return {
phone: '', phone: '',
type: 'user',
type: window.TYPEUSER,
loading: false, loading: false,
question: '', question: '',
options: ['', ''], options: ['', ''],
@ -15,7 +19,7 @@ export default {
}, },
computed: { computed: {
phone_id() { phone_id() {
return this.type === 'user' ? `${NumberFormatLocale(this.phone)}@${window.TYPEUSER}` : `${NumberFormatLocale(this.phone)}@${window.TYPEGROUP}`
return NumberFormatLocale(this.phone) + this.type;
} }
}, },
methods: { methods: {
@ -58,7 +62,7 @@ export default {
}, },
handleReset() { handleReset() {
this.phone = ''; this.phone = '';
this.type = 'user';
this.type = window.TYPEUSER;
this.question = ''; this.question = '';
this.options = ['', '']; this.options = ['', ''];
this.max_vote = 1; this.max_vote = 1;
@ -89,19 +93,8 @@ export default {
</div> </div>
<div class="content"> <div class="content">
<form class="ui form"> <form class="ui form">
<div class="field">
<label>Type</label>
<select name="type" v-model="type" aria-label="type">
<option value="group">Group Message</option>
<option value="user">Private Message</option>
</select>
</div>
<div class="field">
<label>Phone / Group ID</label>
<input v-model="phone" type="text" placeholder="6289..."
aria-label="phone">
<input :value="phone_id" disabled aria-label="whatsapp_id">
</div>
<FormRecipient v-model:type="type" v-model:phone="phone"/>
<div class="field"> <div class="field">
<label>Question</label> <label>Question</label>
<input v-model="question" type="text" placeholder="Please enter question" <input v-model="question" type="text" placeholder="Please enter question"

27
src/views/components/SendVideo.js

@ -1,7 +1,11 @@
import { NumberFormatLocale } from './funcoes.js'
import { NumberFormatLocale } from './funcoes.js';
import FormRecipient from "./generic/FormRecipient.js";
export default { export default {
name: 'SendVideo', name: 'SendVideo',
components: {
FormRecipient
},
// define props // define props
props: { props: {
maxVideoSize: { maxVideoSize: {
@ -14,14 +18,14 @@ export default {
caption: '', caption: '',
view_once: false, view_once: false,
compress: false, compress: false,
type: 'user',
type: window.TYPEUSER,
phone: '', phone: '',
loading: false, loading: false,
} }
}, },
computed: { computed: {
phone_id() { phone_id() {
return this.type === 'user' ? `${NumberFormatLocale(this.phone)}@${window.TYPEUSER}` : `${NumberFormatLocale(this.phone)}@${window.TYPEGROUP}`
return NumberFormatLocale(this.phone) + this.type;
} }
}, },
methods: { methods: {
@ -67,7 +71,7 @@ export default {
this.view_once = false; this.view_once = false;
this.compress = false; this.compress = false;
this.phone = ''; this.phone = '';
this.type = 'user';
this.type = window.TYPEUSER;
$("#file_video").val(''); $("#file_video").val('');
}, },
}, },
@ -93,19 +97,8 @@ export default {
</div> </div>
<div class="content"> <div class="content">
<form class="ui form"> <form class="ui form">
<div class="field">
<label>Type</label>
<select name="type" v-model="type" aria-label="type">
<option value="group">Group Message</option>
<option value="user">Private Message</option>
</select>
</div>
<div class="field">
<label>Phone / Group ID</label>
<input v-model="phone" type="text" placeholder="6289..."
aria-label="phone">
<input :value="phone_id" disabled aria-label="whatsapp_id">
</div>
<FormRecipient v-model:type="type" v-model:phone="phone"/>
<div class="field"> <div class="field">
<label>Caption</label> <label>Caption</label>
<textarea v-model="caption" placeholder="Type some caption (optional)..." <textarea v-model="caption" placeholder="Type some caption (optional)..."

52
src/views/components/generic/FormRecipient.js

@ -0,0 +1,52 @@
export default {
name: 'FormRecipient',
props: {
type: {
type: String,
required: true
},
phone: {
type: String,
required: true
},
},
data() {
return {
recipientTypes: []
};
},
computed: {
phone_id() {
return this.phone + this.type;
}
},
mounted() {
this.recipientTypes = [
{ value: window.TYPEUSER, text: 'Private Message' },
{ value: window.TYPEGROUP, text: 'Group Message' },
{ value: window.TYPENEWSLETTER, text: 'Newsletter' }
];
},
methods: {
updateType(event) {
this.$emit('update:type', event.target.value);
},
updatePhone(event) {
this.$emit('update:phone', event.target.value);
}
},
template: `
<div class="field">
<label>Type</label>
<select name="type" @change="updateType" class="ui dropdown">
<option v-for="type in recipientTypes" :value="type.value">{{ type.text }}</option>
</select>
</div>
<div class="field">
<label>Phone / Group ID</label>
<input :value="phone" aria-label="wa identifier" @input="updatePhone">
<input :value="phone_id" disabled aria-label="whatsapp_id">
</div>
`
}

19
src/views/index.html

@ -86,6 +86,14 @@
<group-add-participants></group-add-participants> <group-add-participants></group-add-participants>
</div> </div>
<div class="ui horizontal divider">
Newsletter
</div>
<div class="ui three column doubling grid cards">
<newsletter-list></newsletter-list>
</div>
<div class="ui horizontal divider"> <div class="ui horizontal divider">
Account Account
</div> </div>
@ -98,8 +106,9 @@
</div> </div>
<script> <script>
window.TYPEGROUP = "g.us";
window.TYPEUSER = "s.whatsapp.net";
window.TYPEGROUP = "@g.us";
window.TYPEUSER = "@s.whatsapp.net";
window.TYPENEWSLETTER = "@newsletter";
window.showErrorInfo = (message) => { window.showErrorInfo = (message) => {
$('body').toast({ $('body').toast({
position: 'bottom right', position: 'bottom right',
@ -120,7 +129,7 @@
} }
window.http = axios.create({ window.http = axios.create({
baseURL: {{ .AppHost }}
baseURL: `${window.location.protocol}//${window.location.hostname}${window.location.port ? ':' + window.location.port : ''}`
}); });
{{ if isEnableBasicAuth .BasicAuthToken }} {{ if isEnableBasicAuth .BasicAuthToken }}
window.http.defaults.headers.common['Authorization'] = {{ .BasicAuthToken }}; window.http.defaults.headers.common['Authorization'] = {{ .BasicAuthToken }};
@ -150,6 +159,7 @@
import AccountAvatar from "./components/AccountAvatar.js"; import AccountAvatar from "./components/AccountAvatar.js";
import AccountUserInfo from "./components/AccountUserInfo.js"; import AccountUserInfo from "./components/AccountUserInfo.js";
import AccountPrivacy from "./components/AccountPrivacy.js"; import AccountPrivacy from "./components/AccountPrivacy.js";
import NewsletterList from "./components/NewsletterList.js";
const showErrorInfo = (message) => { const showErrorInfo = (message) => {
$('body').toast({ $('body').toast({
@ -176,6 +186,7 @@
SendMessage, SendImage, SendFile, SendVideo, SendContact, SendLocation, SendAudio, SendPoll, SendMessage, SendImage, SendFile, SendVideo, SendContact, SendLocation, SendAudio, SendPoll,
MessageDelete, MessageUpdate, MessageReact, MessageRevoke, MessageDelete, MessageUpdate, MessageReact, MessageRevoke,
GroupList, GroupCreate, GroupJoinWithLink, GroupAddParticipants, GroupList, GroupCreate, GroupJoinWithLink, GroupAddParticipants,
NewsletterList,
AccountAvatar, AccountUserInfo, AccountPrivacy AccountAvatar, AccountUserInfo, AccountPrivacy
}, },
delimiters: ['[[', ']]'], delimiters: ['[[', ']]'],
@ -226,4 +237,4 @@
}).mount('#app') }).mount('#app')
</script> </script>
</body> </body>
</html>
</html>
Loading…
Cancel
Save