diff --git a/api/src/go.mod b/api/src/go.mod index bcd9104..1c14950 100644 --- a/api/src/go.mod +++ b/api/src/go.mod @@ -6,9 +6,9 @@ toolchain go1.23.1 require ( github.com/chai2010/webp v1.1.1 - github.com/gin-contrib/cors v1.7.2 github.com/gin-gonic/gin v1.10.0 github.com/go-redis/redis/v8 v8.11.5 + github.com/google/uuid v1.6.0 github.com/jackc/pgx/v4 v4.18.2 github.com/joho/godotenv v1.5.1 github.com/mattn/go-sqlite3 v1.14.23 @@ -18,15 +18,15 @@ require ( github.com/uptrace/bun/dialect/pgdialect v1.2.3 github.com/uptrace/bun/driver/pgdriver v1.2.3 github.com/ztrue/tracerr v0.4.0 - go.mau.fi/whatsmeow v0.0.0-20240927134544-69ba055bef0f - google.golang.org/protobuf v1.34.2 + go.mau.fi/whatsmeow v0.0.0-20241011190419-de8326a9d38d + google.golang.org/protobuf v1.35.1 ) require ( filippo.io/edwards25519 v1.1.0 // indirect - github.com/bytedance/sonic v1.11.9 // indirect - github.com/bytedance/sonic/loader v0.1.1 // indirect - github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/bytedance/sonic v1.12.3 // indirect + github.com/bytedance/sonic/loader v0.2.0 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cloudwego/base64x v0.1.4 // indirect github.com/cloudwego/iasm v0.2.0 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect @@ -37,7 +37,6 @@ require ( github.com/go-playground/validator/v10 v10.22.0 // indirect github.com/goccy/go-json v0.10.3 // indirect github.com/google/go-cmp v0.6.0 // indirect - github.com/google/uuid v1.6.0 // indirect github.com/gorilla/websocket v1.5.3 // indirect github.com/jackc/chunkreader/v2 v2.0.1 // indirect github.com/jackc/pgconn v1.14.3 // indirect @@ -49,6 +48,7 @@ require ( github.com/jinzhu/inflection v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/cpuid/v2 v2.2.8 // indirect + github.com/kr/pretty v0.3.0 // indirect github.com/leodido/go-urn v1.4.0 // indirect github.com/lib/pq v1.10.9 // indirect github.com/mattn/go-colorable v0.1.13 // indirect @@ -57,6 +57,7 @@ require ( github.com/modern-go/reflect2 v1.0.2 // indirect github.com/pelletier/go-toml/v2 v2.2.2 // indirect github.com/puzpuzpuz/xsync/v3 v3.4.0 // indirect + github.com/rogpeppe/go-internal v1.8.0 // indirect github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/ugorji/go/codec v1.2.12 // indirect @@ -69,6 +70,7 @@ require ( golang.org/x/net v0.29.0 // indirect golang.org/x/sys v0.25.0 // indirect golang.org/x/text v0.18.0 // indirect + gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/yaml.v3 v3.0.1 // indirect mellium.im/sasl v0.3.1 // indirect ) diff --git a/api/src/helpers/whatsapp.go b/api/src/helpers/whatsapp.go index c1607e3..386f06b 100644 --- a/api/src/helpers/whatsapp.go +++ b/api/src/helpers/whatsapp.go @@ -15,6 +15,7 @@ import ( "github.com/skip2/go-qrcode" "github.com/ztrue/tracerr" "go.mau.fi/whatsmeow" + waStore "go.mau.fi/whatsmeow/store" "go.mau.fi/whatsmeow/store/sqlstore" "go.mau.fi/whatsmeow/types" waLog "go.mau.fi/whatsmeow/util/log" @@ -41,22 +42,13 @@ type DeviceResponse struct { Timestamp time.Time `json:"timestamp"` } -// ContactsResponse represents the contact information associated with a device. -type ContactsResponse struct { - Name string `json:"name"` - Number string `json:"number"` - ProfilePicture string `json:"profile_picture"` -} - // DeviceInfoResponse is the detailed response structure for device information. type DeviceInfoResponse struct { - DeviceID int `json:"device_id"` - ProfilePicture string `json:"profile_picture"` - Webhook string `json:"webhook"` - PhoneNumber string `json:"phone_number"` - PushName string `json:"push_name"` - BusinessName string `json:"business_name"` - ContactsResponse []ContactsResponse `json:"contacts"` + DeviceID int `json:"device_id"` + Webhook string `json:"webhook"` + PhoneNumber string `json:"phone_number"` + PushName string `json:"push_name"` + BusinessName string `json:"business_name"` } // connectToDatabase establishes a connection to the PostgreSQL database and returns a WhatsMeow container. @@ -78,24 +70,30 @@ func connectToDatabase() (*sqlstore.Container, error) { return container, nil } -// GetWhatsAppClientByJID retrieves a WhatsApp client by its JID (WhatsApp ID). -func GetWhatsAppClientByJID(whatsappID string) (*whatsmeow.Client, error) { +// GetDeviceStoreByJID retrieves the device store (store.Device) by its JID (WhatsApp ID). +func GetDeviceStoreByJID(whatsappID string) (*waStore.Device, error) { dbMutex.Lock() defer dbMutex.Unlock() - container, err := connectToDatabase() + container, err := connectToDatabase() // Conexão com o banco de dados if err != nil { return nil, err } jid, _ := types.ParseJID(whatsappID) - deviceStore, err := container.GetDevice(jid) + deviceStore, err := container.GetDevice(jid) // Supondo que retorna *store.Device if err != nil { return nil, tracerr.Wrap(fmt.Errorf("%w: %v", ErrDeviceNotFound, err)) } - client := whatsmeow.NewClient(deviceStore, wmLog) + return deviceStore, nil +} + +// GetWhatsAppClientByDeviceStore retrieves a WhatsApp client using the store.Device. +func GetWhatsAppClientByDeviceStore(deviceStore *waStore.Device) (*whatsmeow.Client, error) { + client := whatsmeow.NewClient(deviceStore, wmLog) // Passa o store.Device + if client.Store.ID == nil { return nil, tracerr.Wrap(fmt.Errorf("%w: %v", ErrClientConnection, client.Store.ID)) } @@ -106,6 +104,24 @@ func GetWhatsAppClientByJID(whatsappID string) (*whatsmeow.Client, error) { return nil, tracerr.Wrap(fmt.Errorf("%w: %v", ErrClientConnection, err)) } } + + return client, nil +} + +// GetWhatsAppClientByJID retrieves a WhatsApp client by its JID (WhatsApp ID). +func GetWhatsAppClientByJID(whatsappID string) (*whatsmeow.Client, error) { + // Obter o device store + deviceStore, err := GetDeviceStoreByJID(whatsappID) + if err != nil { + return nil, err + } + + // Obter o client usando o device store + client, err := GetWhatsAppClientByDeviceStore(deviceStore) + if err != nil { + return nil, err + } + return client, nil } @@ -230,51 +246,6 @@ func GenerateQRCode(qrCode string) (string, error) { func GetClientInfo(deviceID int, client *whatsmeow.Client) DeviceInfoResponse { clientJID := types.NewJID(client.Store.ID.User, types.DefaultUserServer) - // Get the profile picture of the client. - picInfo, _ := client.GetProfilePictureInfo(clientJID, nil) - var picURL string - if picInfo != nil { - picURL = picInfo.URL - } - - // Get all contacts of the client. - contacts, _ := client.Store.Contacts.GetAllContacts() - var contactsResponse []ContactsResponse - - var wg sync.WaitGroup - var mu sync.Mutex // Protects concurrent access to contactsResponse - - // Function to process each contact and add it to the response. - processContact := func(key types.JID, contact types.ContactInfo) { - defer wg.Done() - - contactName := contact.PushName - if contactName == "" { - contactName = contact.BusinessName - } - - picContact, _ := client.GetProfilePictureInfo(key, nil) - var contactProfileURL string - if picContact != nil { - contactProfileURL = picContact.URL - } - - mu.Lock() - contactsResponse = append(contactsResponse, ContactsResponse{ - Name: contactName, - Number: key.User, - ProfilePicture: contactProfileURL, - }) - mu.Unlock() - } - - for key, contact := range contacts { - wg.Add(1) - go processContact(key, contact) - } - - wg.Wait() - // Retrieve the active webhook URL for the device. var webhookURL string if webhook, err := GetWebhookActiveByDeviceID(deviceID); err == nil { @@ -283,12 +254,10 @@ func GetClientInfo(deviceID int, client *whatsmeow.Client) DeviceInfoResponse { // Return device information response. return DeviceInfoResponse{ - DeviceID: deviceID, - ProfilePicture: picURL, - Webhook: webhookURL, - PhoneNumber: clientJID.User, - PushName: client.Store.PushName, - BusinessName: client.Store.BusinessName, - ContactsResponse: contactsResponse, + DeviceID: deviceID, + Webhook: webhookURL, + PhoneNumber: clientJID.User, + PushName: client.Store.PushName, + BusinessName: client.Store.BusinessName, } }