From 280a9b09f08f1da4dd1044ef08542a4dfe727431 Mon Sep 17 00:00:00 2001 From: Aldino Kemal Date: Wed, 23 Nov 2022 06:30:01 +0700 Subject: [PATCH] feat: trigger when pair success --- src/cmd/root.go | 63 ++++---------------------- src/config/settings.go | 17 ++++--- src/internal/rest/helpers/common.go | 13 ++++++ src/internal/rest/helpers/websocket.go | 45 ++++++++++++++++++ src/services/app_service.go | 5 -- src/utils/whatsapp.go | 22 ++++----- src/views/index.html | 27 +++++++---- 7 files changed, 101 insertions(+), 91 deletions(-) create mode 100644 src/internal/rest/helpers/common.go diff --git a/src/cmd/root.go b/src/cmd/root.go index d4f06ae..9239cd0 100644 --- a/src/cmd/root.go +++ b/src/cmd/root.go @@ -2,7 +2,6 @@ package cmd import ( "encoding/base64" - "encoding/json" "fmt" "github.com/aldinokemal/go-whatsapp-web-multidevice/config" "github.com/aldinokemal/go-whatsapp-web-multidevice/internal/rest" @@ -16,16 +15,12 @@ import ( "github.com/gofiber/fiber/v2/middleware/cors" "github.com/gofiber/fiber/v2/middleware/logger" "github.com/gofiber/template/html" - "github.com/gofiber/websocket/v2" "github.com/markbates/pkger" _ "github.com/mattn/go-sqlite3" + "github.com/spf13/cobra" "log" - "net/http" "os" "strings" - "time" - - "github.com/spf13/cobra" ) // rootCmd represents the base command when called without any subcommands @@ -105,61 +100,19 @@ func runRest(_ *cobra.Command, _ []string) { app.Get("/", func(ctx *fiber.Ctx) error { return ctx.Render("index", fiber.Map{ - "AppHost": fmt.Sprintf("%s://%s", ctx.Protocol(), ctx.Hostname()), - "AppVersion": config.AppVersion, - "QRRefreshSeconds": config.AppRefreshQRCodeSeconds * 1000, - "BasicAuthToken": base64.StdEncoding.EncodeToString([]byte(config.AppBasicAuthCredential)), - "MaxFileSize": humanize.Bytes(uint64(config.WhatsappSettingMaxFileSize)), - "MaxVideoSize": humanize.Bytes(uint64(config.WhatsappSettingMaxVideoSize)), + "AppHost": fmt.Sprintf("%s://%s", ctx.Protocol(), ctx.Hostname()), + "AppVersion": config.AppVersion, + "BasicAuthToken": base64.StdEncoding.EncodeToString([]byte(config.AppBasicAuthCredential)), + "MaxFileSize": humanize.Bytes(uint64(config.WhatsappSettingMaxFileSize)), + "MaxVideoSize": humanize.Bytes(uint64(config.WhatsappSettingMaxVideoSize)), }) }) - app.Use("/ws", func(c *fiber.Ctx) error { - if websocket.IsWebSocketUpgrade(c) { // Returns true if the client requested upgrade to the WebSocket protocol - return c.Next() - } - return c.SendStatus(fiber.StatusUpgradeRequired) - }) + helpers.WsRegisterRoutes(app, cli) go helpers.WsRunHub() - app.Get("/ws", websocket.New(func(c *websocket.Conn) { - // When the function returns, unregister the client and close the connection - defer func() { - helpers.WsUnregister <- c - c.Close() - }() - - // Register the client - helpers.WsRegister <- c - - for { - messageType, message, err := c.ReadMessage() - if err != nil { - if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway, websocket.CloseAbnormalClosure) { - log.Println("read error:", err) - } - return // Calls the deferred function, i.e. closes the connection on error - } - - if messageType == websocket.TextMessage { - // Broadcast the received message - var messageData helpers.WsBroadcastMessage - err := json.Unmarshal(message, &messageData) - if err != nil { - log.Println("error unmarshal message:", err) - return - } - helpers.WsBroadcast <- messageData - } else { - log.Println("websocket message received of type", messageType) - } - } - })) // Set auto reconnect to whatsapp server after booting - go func() { - time.Sleep(2 * time.Second) - _, _ = http.Get(fmt.Sprintf("http://localhost:%s/app/reconnect", config.AppPort)) - }() + go helpers.SetAutoConnectAfterBooting() err = app.Listen(":" + config.AppPort) if err != nil { log.Fatalln("Failed to start: ", err.Error()) diff --git a/src/config/settings.go b/src/config/settings.go index 711ea50..e7d2209 100644 --- a/src/config/settings.go +++ b/src/config/settings.go @@ -6,15 +6,14 @@ import ( ) var ( - AppVersion = "v3.11.0" - AppPort = "3000" - AppDebug = false - AppOs = fmt.Sprintf("AldinoKemal") - AppPlatform = waProto.DeviceProps_PlatformType(1) - AppSelectedDeviceKey = "deviceID" - AppDefaultDevice = "default" - AppBasicAuthCredential string - AppRefreshQRCodeSeconds = 10 + AppVersion = "v3.11.0" + AppPort = "3000" + AppDebug = false + AppOs = fmt.Sprintf("AldinoKemal") + AppPlatform = waProto.DeviceProps_PlatformType(1) + AppSelectedDeviceKey = "deviceID" + AppDefaultDevice = "default" + AppBasicAuthCredential string PathQrCode = "statics/qrcode" PathSendItems = "statics/senditems" diff --git a/src/internal/rest/helpers/common.go b/src/internal/rest/helpers/common.go new file mode 100644 index 0000000..6de6285 --- /dev/null +++ b/src/internal/rest/helpers/common.go @@ -0,0 +1,13 @@ +package helpers + +import ( + "fmt" + "github.com/aldinokemal/go-whatsapp-web-multidevice/config" + "net/http" + "time" +) + +func SetAutoConnectAfterBooting() { + time.Sleep(2 * time.Second) + _, _ = http.Get(fmt.Sprintf("http://localhost:%s/app/reconnect", config.AppPort)) +} diff --git a/src/internal/rest/helpers/websocket.go b/src/internal/rest/helpers/websocket.go index 5aa5e65..59ddf5c 100644 --- a/src/internal/rest/helpers/websocket.go +++ b/src/internal/rest/helpers/websocket.go @@ -2,7 +2,9 @@ package helpers import ( "encoding/json" + "github.com/gofiber/fiber/v2" "github.com/gofiber/websocket/v2" + "go.mau.fi/whatsmeow" "log" ) @@ -59,3 +61,46 @@ func WsRunHub() { } } } + +func WsRegisterRoutes(app *fiber.App, cli *whatsmeow.Client) { + app.Use("/ws", func(c *fiber.Ctx) error { + if websocket.IsWebSocketUpgrade(c) { // Returns true if the client requested upgrade to the WebSocket protocol + return c.Next() + } + return c.SendStatus(fiber.StatusUpgradeRequired) + }) + + app.Get("/ws", websocket.New(func(c *websocket.Conn) { + // When the function returns, unregister the client and close the connection + defer func() { + WsUnregister <- c + _ = c.Close() + }() + + // Register the client + WsRegister <- c + + for { + messageType, message, err := c.ReadMessage() + if err != nil { + if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway, websocket.CloseAbnormalClosure) { + log.Println("read error:", err) + } + return // Calls the deferred function, i.e. closes the connection on error + } + + if messageType == websocket.TextMessage { + // Broadcast the received message + var messageData WsBroadcastMessage + err := json.Unmarshal(message, &messageData) + if err != nil { + log.Println("error unmarshal message:", err) + return + } + WsBroadcast <- messageData + } else { + log.Println("websocket message received of type", messageType) + } + } + })) +} diff --git a/src/services/app_service.go b/src/services/app_service.go index 1c80d0a..4f8f09a 100644 --- a/src/services/app_service.go +++ b/src/services/app_service.go @@ -6,7 +6,6 @@ import ( "fmt" "github.com/aldinokemal/go-whatsapp-web-multidevice/config" domainApp "github.com/aldinokemal/go-whatsapp-web-multidevice/domains/app" - "github.com/aldinokemal/go-whatsapp-web-multidevice/utils" fiberUtils "github.com/gofiber/fiber/v2/utils" "github.com/skip2/go-qrcode" "go.mau.fi/whatsmeow" @@ -82,10 +81,6 @@ func (service serviceApp) Login(_ context.Context) (response domainApp.LoginResp } response.ImagePath = <-chImage - // Set in event - utils.LoginTime = time.Now() - utils.LoginIsNotified = false - return response, nil } diff --git a/src/utils/whatsapp.go b/src/utils/whatsapp.go index 72f9dfa..dec7696 100644 --- a/src/utils/whatsapp.go +++ b/src/utils/whatsapp.go @@ -25,12 +25,10 @@ import ( ) var ( - cli *whatsmeow.Client - log waLog.Logger - historySyncID int32 - LoginTime time.Time - LoginIsNotified bool - startupTime = time.Now().Unix() + cli *whatsmeow.Client + log waLog.Logger + historySyncID int32 + startupTime = time.Now().Unix() ) func GetPlatformName(deviceID int) string { @@ -137,17 +135,15 @@ func handler(rawEvt interface{}) { log.Infof("Marked self as available") } } + case *events.PairSuccess: + helpers.WsBroadcast <- helpers.WsBroadcastMessage{ + Code: "LOGIN_SUCCESS", + Message: fmt.Sprintf("Successfully pair with %s", evt.ID.String()), + } case *events.Connected, *events.PushNameSetting: if len(cli.Store.PushName) == 0 { return } - if cli.LastSuccessfulConnect.Before(LoginTime.Add(time.Duration(config.AppRefreshQRCodeSeconds)*time.Second)) && !LoginIsNotified { - LoginIsNotified = true - helpers.WsBroadcast <- helpers.WsBroadcastMessage{ - Code: "LOGIN_SUCCESS", - Message: "Login Success", - } - } // Send presence available when connecting and when the pushname is changed. // This makes sure that outgoing messages always have the right pushname. diff --git a/src/views/index.html b/src/views/index.html index 6e021c9..1915158 100644 --- a/src/views/index.html +++ b/src/views/index.html @@ -228,12 +228,15 @@
Please scan to connect

Open Setting > Linked Devices > Link Device

+
+ Refresh QR Code in [[ login_duration_sec ]] seconds to avoid link expiration +
-
- Done - +
+ Refresh QR Code +
@@ -583,10 +586,11 @@ async loginModal() { try { await this.loginApiGetQrCode(); - $('#modalLogin').modal('show'); - this.autoUpdateQRCode = setInterval(async () => { - await this.loginApiGetQrCode(); - }, {{.QRRefreshSeconds}} ); + $('#modalLogin').modal({ + onApprove: function () { + return false; + } + }).modal('show'); } catch (err) { showErrorInfo(err) } @@ -1113,13 +1117,18 @@ if (window["WebSocket"]) { let wsType = location.protocol !== 'https:' ? 'ws://' : 'wss://'; let conn = new WebSocket(wsType + document.location.host + "/ws"); - conn.onmessage = function (evt) { + + conn.onclose = (evt) => { + console.log(evt) + }; + + conn.onmessage = (evt) => { + console.log(evt) const message = JSON.parse(evt.data) switch (message.code) { case 'LOGIN_SUCCESS': showSuccessInfo(message.message) $('#modalLogin').modal('hide'); - location.reload() break; default: console.log(message)