Browse Source

refactor to support multi whatsapp datastore drivers

pull/4/head
Dimas Restu H 4 years ago
parent
commit
8793f2eddd
  1. 6
      .env.default
  2. 6
      .env.development
  3. 6
      .env.production
  4. 14
      internal/startup.go
  5. 2
      internal/whatsapp/whatsapp.go
  6. 5
      pkg/whatsapp/drivers.go
  7. 96
      pkg/whatsapp/whatsapp.go

6
.env.default

@ -21,3 +21,9 @@
# AUTH_JWT_SECRET=secret
# AUTH_JWT_EXPIRED_HOUR=24
# -----------------------------------
# WhatsApp Configuration
# -----------------------------------
# WHATSAPP_DB_TYPE=sqlite3
# WHATSAPP_DB_URI=file:dbs/WhatsApp.db?_foreign_keys=on

6
.env.development

@ -21,3 +21,9 @@ AUTH_BASIC_PASSWORD=83e4060e-78e1-4fe5-9977-aeeccd46a2b8
AUTH_JWT_SECRET=9e4eb4cf-be25-4a29-bba3-fefb5a30f6ab
AUTH_JWT_EXPIRED_HOUR=24
# -----------------------------------
# WhatsApp Configuration
# -----------------------------------
WHATSAPP_DB_TYPE=sqlite3
WHATSAPP_DB_URI=file:dbs/WhatsApp.db?_foreign_keys=on

6
.env.production

@ -21,3 +21,9 @@ AUTH_BASIC_PASSWORD=83e4060e-78e1-4fe5-9977-aeeccd46a2b8
AUTH_JWT_SECRET=9e4eb4cf-be25-4a29-bba3-fefb5a30f6ab
AUTH_JWT_EXPIRED_HOUR=24
# -----------------------------------
# WhatsApp Configuration
# -----------------------------------
WHATSAPP_DB_TYPE=sqlite3
WHATSAPP_DB_URI=file:dbs/WhatsApp.db?_foreign_keys=on

14
internal/startup.go

@ -1,10 +1,6 @@
package internal
import (
"path"
"path/filepath"
"strings"
"github.com/dimaskiddo/go-whatsapp-multidevice-rest/pkg/log"
pkgWhatsApp "github.com/dimaskiddo/go-whatsapp-multidevice-rest/pkg/whatsapp"
)
@ -12,18 +8,18 @@ import (
func Startup() {
log.Print(nil).Info("Running Startup Tasks")
dbs, err := filepath.Glob("./dbs/*.db")
devices, err := pkgWhatsApp.WhatsAppDatastore.GetAllDevices()
if err != nil {
log.Print(nil).Error("Error to Get Existing SQLite Database Files")
log.Print(nil).Error("Failed to Load WhatsApp Client Devices from Database")
}
for _, db := range dbs {
jid := strings.TrimSuffix(filepath.Base(db), path.Ext(db))
for _, device := range devices {
jid := pkgWhatsApp.WhatsAppDecomposeJID(device.ID.String())
maskJID := jid[0:len(jid)-4] + "xxxx"
log.Print(nil).Info("Restoring WhatsApp Client for " + maskJID)
err := pkgWhatsApp.WhatsAppInitClient(jid)
err := pkgWhatsApp.WhatsAppInitClient(device, jid)
if err != nil {
log.Print(nil).Error(err.Error())
}

2
internal/whatsapp/whatsapp.go

@ -125,7 +125,7 @@ func Login(c echo.Context) error {
}
// Initialize WhatsApp Client
err = pkgWhatsApp.WhatsAppInitClient(jid)
err = pkgWhatsApp.WhatsAppInitClient(nil, jid)
if err != nil {
return router.ResponseInternalError(c, err.Error())
}

5
pkg/whatsapp/drivers.go

@ -0,0 +1,5 @@
package whatsapp
import (
_ "github.com/mattn/go-sqlite3"
)

96
pkg/whatsapp/whatsapp.go

@ -4,10 +4,8 @@ import (
"context"
"encoding/base64"
"errors"
"fmt"
"strings"
_ "github.com/mattn/go-sqlite3"
qrCode "github.com/skip2/go-qrcode"
"google.golang.org/protobuf/proto"
@ -16,66 +14,53 @@ import (
"go.mau.fi/whatsmeow/store"
"go.mau.fi/whatsmeow/store/sqlstore"
"go.mau.fi/whatsmeow/types"
"github.com/dimaskiddo/go-whatsapp-multidevice-rest/pkg/env"
"github.com/dimaskiddo/go-whatsapp-multidevice-rest/pkg/log"
)
var WhatsAppDatastore *sqlstore.Container
var WhatsAppClient = make(map[string]*whatsmeow.Client)
func WhatsAppDB(dbType string) (*sqlstore.Container, error) {
var dbName, dbURI string
func init() {
WhatsAppInitDB()
}
switch dbType {
case "sqlite3":
// Prepare SQLite Database and Connection URI
dbName = "dbs/WhatsApp.db"
dbURI = fmt.Sprintf("file:%s?_foreign_keys=on", dbName)
func WhatsAppInitDB() {
var err error
default:
return nil, errors.New("Unknown WhstaApp Client Database Type")
dbType, err := env.GetEnvString("WHATSAPP_DB_TYPE")
if err != nil {
log.Print(nil).Fatal("Error Parse Environment Variable for WhatsApp Client Datastore Type")
}
// Create and Connect to Database
datastore, err := sqlstore.New(dbType, dbURI, nil)
dbURI, err := env.GetEnvString("WHATSAPP_DB_URI")
if err != nil {
return nil, errors.New("Failed to Connect WhatsApp Client Database")
log.Print(nil).Fatal("Error Parse Environment Variable for WhatsApp Client Datastore URI")
}
return datastore, nil
datastore, err := sqlstore.New(dbType, dbURI, nil)
if err != nil {
log.Print(nil).Fatal("Error Connect WhatsApp Client Datastore")
}
func WhatsAppInitDB(jid string) (*whatsmeow.Client, error) {
// Connect to WhatsApp Client Datastore
datastore, err := WhatsAppDB("sqlite3")
if err != nil {
return nil, err
WhatsAppDatastore = datastore
}
// Get WhatsApp Device Based on JID from Datastore
device, err := datastore.GetDevice(WhatsAppComposeJID(jid))
if err != nil {
return nil, errors.New("Failed to Load WhatsApp Client Device from Database")
func WhatsAppInitClient(device *store.Device, jid string) error {
if WhatsAppClient[jid] == nil {
if device == nil {
// Initialize New WhatsApp Client Device in Datastore
device = WhatsAppDatastore.NewDevice()
}
// Set Client Properties
store.CompanionProps.Os = proto.String("Go WhatsApp Multi-Device REST")
store.CompanionProps.PlatformType = waproto.CompanionProps_DESKTOP.Enum()
// Create New Client Connection
client := whatsmeow.NewClient(device, nil)
// Return Client Connection
return client, nil
}
func WhatsAppInitClient(jid string) error {
if WhatsAppClient[jid] == nil {
// Initialize New WhatsApp Client
client, err := WhatsAppInitDB(jid)
if err != nil {
return err
}
// Set Created WhatsApp Client to Map
WhatsAppClient[jid] = client
// And Save it to The Map
WhatsAppClient[jid] = whatsmeow.NewClient(device, nil)
}
return nil
@ -176,7 +161,7 @@ func WhatsAppLogout(jid string) error {
// Force Disconnect
WhatsAppClient[jid].Disconnect()
// Manually Delete Device from Database Store
// Manually Delete Device from Datastore Store
err = WhatsAppClient[jid].Store.Delete()
if err != nil {
return err
@ -209,6 +194,23 @@ func WhatsAppClientIsOK(jid string) error {
}
func WhatsAppComposeJID(jid string) types.JID {
// Decompose JID First Before Recomposing
jid = WhatsAppDecomposeJID(jid)
// Check if JID Contains '-' Symbol
if strings.ContainsRune(jid, '-') {
// Check if the JID is a Group ID
if len(strings.SplitN(jid, "-", 2)) == 2 {
// Return JID as Group Server (@g.us)
return types.NewJID(jid, types.GroupServer)
}
}
// Return JID as Default User Server (@s.whatsapp.net)
return types.NewJID(jid, types.DefaultUserServer)
}
func WhatsAppDecomposeJID(jid string) string {
// Check if JID Contains '@' Symbol
if strings.ContainsRune(jid, '@') {
// Split JID Based on '@' Symbol
@ -223,17 +225,7 @@ func WhatsAppComposeJID(jid string) types.JID {
jid = jid[1:]
}
// Check if JID Contains '-' Symbol
if strings.ContainsRune(jid, '-') {
// Check if the JID is a Group ID
if len(strings.SplitN(jid, "-", 2)) == 2 {
// Return JID as Group Server (@g.us)
return types.NewJID(jid, types.GroupServer)
}
}
// Return JID as Default User Server (@s.whatsapp.net)
return types.NewJID(jid, types.DefaultUserServer)
return jid
}
func WhatsAppSendText(jid string, rjid string, message string) error {

Loading…
Cancel
Save