diff --git a/src/cmd/root.go b/src/cmd/root.go index cbef10a..d4f06ae 100644 --- a/src/cmd/root.go +++ b/src/cmd/root.go @@ -2,9 +2,11 @@ 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" + "github.com/aldinokemal/go-whatsapp-web-multidevice/internal/rest/helpers" "github.com/aldinokemal/go-whatsapp-web-multidevice/middleware" "github.com/aldinokemal/go-whatsapp-web-multidevice/services" "github.com/aldinokemal/go-whatsapp-web-multidevice/utils" @@ -14,6 +16,7 @@ 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" "log" @@ -43,7 +46,7 @@ func init() { rootCmd.PersistentFlags().StringVarP(&config.WhatsappAutoReplyWebhook, "webhook", "w", config.WhatsappAutoReplyMessage, `auto reply when received message --webhook | example: --webhook="https://yourcallback.com/callback"`) } -func runRest(cmd *cobra.Command, args []string) { +func runRest(_ *cobra.Command, _ []string) { if config.AppDebug { config.WhatsappLogLevel = "DEBUG" } @@ -102,14 +105,56 @@ func runRest(cmd *cobra.Command, args []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, - "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, + "QRRefreshSeconds": config.AppRefreshQRCodeSeconds * 1000, + "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) + }) + 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) diff --git a/src/config/settings.go b/src/config/settings.go index e7d2209..711ea50 100644 --- a/src/config/settings.go +++ b/src/config/settings.go @@ -6,14 +6,15 @@ 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 + 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 PathQrCode = "statics/qrcode" PathSendItems = "statics/senditems" diff --git a/src/go.mod b/src/go.mod index da090fc..a7a051c 100644 --- a/src/go.mod +++ b/src/go.mod @@ -7,6 +7,7 @@ require ( github.com/go-ozzo/ozzo-validation/v4 v4.3.0 github.com/gofiber/fiber/v2 v2.40.0 github.com/gofiber/template v1.7.2 + github.com/gofiber/websocket/v2 v2.1.1 github.com/h2non/bimg v1.1.9 github.com/markbates/pkger v0.17.1 github.com/mattn/go-sqlite3 v1.14.16 @@ -23,6 +24,7 @@ require ( github.com/andybalholm/brotli v1.0.4 // indirect github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d // indirect github.com/davecgh/go-spew v1.1.1 // indirect + github.com/fasthttp/websocket v1.5.0 // indirect github.com/gobuffalo/here v0.6.7 // indirect github.com/gorilla/websocket v1.5.0 // indirect github.com/inconshreveable/mousetrap v1.0.1 // indirect @@ -32,6 +34,7 @@ require ( github.com/mattn/go-runewidth v0.0.14 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rivo/uniseg v0.4.2 // indirect + github.com/savsgio/gotils v0.0.0-20211223103454-d0aaa54c5899 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/tcplisten v1.0.0 // indirect diff --git a/src/go.sum b/src/go.sum index 1ade34f..b934040 100644 --- a/src/go.sum +++ b/src/go.sum @@ -120,6 +120,8 @@ github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go. github.com/envoyproxy/go-control-plane v0.10.1/go.mod h1:AY7fTTXNdv/aJ2O5jwpxAPOWUZ7hQAEvzN5Pf27BkQQ= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v0.6.2/go.mod h1:2t7qjJNvHPx8IjnBOzl9E9/baC+qXE/TeeyBRzgJDws= +github.com/fasthttp/websocket v1.5.0 h1:B4zbe3xXyvIdnqjOZrafVFklCUq5ZLo/TqCt5JA1wLE= +github.com/fasthttp/websocket v1.5.0/go.mod h1:n0BlOQvJdPbTuBkZT0O5+jk/sp/1/VCzquR1BehI2F4= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= @@ -145,6 +147,8 @@ github.com/gofiber/fiber/v2 v2.40.0 h1:fdU7w5hT6PLL7jiWIhtQ+S/k5WEFYoUZidptlPu8G github.com/gofiber/fiber/v2 v2.40.0/go.mod h1:Gko04sLksnHbzLSRBFWPFdzM9Ws9pRxvvIaohJK1dsk= github.com/gofiber/template v1.7.2 h1:sCHY5WcvmLtR7t8ihXCs5HRdYv4W9EzgBIMbUl4a5zw= github.com/gofiber/template v1.7.2/go.mod h1:uk/mUKTXJMBMoETvo/5CA/QlTFERHMooOm0pJPGDGVA= +github.com/gofiber/websocket/v2 v2.1.1 h1:Q88s88UL8B+elZTT/QB+ocDb1REhdMEmnysI0C9zzqs= +github.com/gofiber/websocket/v2 v2.1.1/go.mod h1:F0ES7DhlFrNyHtC2UGey2KYI+zdqIURRMbSF0C4qdGQ= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -215,6 +219,7 @@ github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= @@ -269,6 +274,7 @@ github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/X github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.14.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.15.0/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= github.com/klauspost/compress v1.15.12 h1:YClS/PImqYbn+UILDnqxQCZ3RehC9N318SU3kElDUEM= @@ -354,6 +360,8 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/sagikazarmark/crypt v0.3.0/go.mod h1:uD/D+6UF4SrIR1uGEv7bBNkNqLGqUr43MRiaGWX1Nig= +github.com/savsgio/gotils v0.0.0-20211223103454-d0aaa54c5899 h1:Orn7s+r1raRTBKLSc9DmbktTT04sL+vkzsbRD2Q8rOI= +github.com/savsgio/gotils v0.0.0-20211223103454-d0aaa54c5899/go.mod h1:oejLrk1Y/5zOF+c/aHtXqn3TFlzzbAgPWg8zBiAHDas= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= @@ -386,6 +394,7 @@ github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69 github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasthttp v1.33.0/go.mod h1:KJRK/MXx0J+yd0c5hlR+s1tIHD72sniU8ZJjl97LIw4= github.com/valyala/fasthttp v1.40.0/go.mod h1:t/G+3rLek+CyY9bnIE+YlMRddxVAAGjhxndDB4i4C0I= github.com/valyala/fasthttp v1.41.0 h1:zeR0Z1my1wDHTRiamBCXVglQdbUwgb9uWG3k1HQz6jY= github.com/valyala/fasthttp v1.41.0/go.mod h1:f6VbjjoI3z1NDOZOv17o6RvtRSWxC77seBFc2uWtgiY= @@ -428,6 +437,7 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/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.0.0-20220112180741-5e0467b6c7ce/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20221012134737-56aed061732a/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU= @@ -514,6 +524,7 @@ golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220111093109-d55c255bac03/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220906165146-f3363e06e74c/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= @@ -614,6 +625,7 @@ golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220111092808-5a964db01320/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/src/internal/rest/helpers/websocket.go b/src/internal/rest/helpers/websocket.go new file mode 100644 index 0000000..5aa5e65 --- /dev/null +++ b/src/internal/rest/helpers/websocket.go @@ -0,0 +1,61 @@ +package helpers + +import ( + "encoding/json" + "github.com/gofiber/websocket/v2" + "log" +) + +type client struct{} // Add more data to this type if needed +type WsBroadcastMessage struct { + Code string `json:"code"` + Message string `json:"message"` +} + +var WsClients = make(map[*websocket.Conn]client) // Note: although large maps with pointer-like types (e.g. strings) as keys are slow, using pointers themselves as keys is acceptable and fast +var WsRegister = make(chan *websocket.Conn) +var WsBroadcast = make(chan WsBroadcastMessage) +var WsUnregister = make(chan *websocket.Conn) + +func WsRunHub() { + for { + select { + case connection := <-WsRegister: + WsClients[connection] = client{} + log.Println("connection registered") + + case message := <-WsBroadcast: + log.Println("message received:", message) + marshalMessage, err := json.Marshal(message) + if err != nil { + log.Println("write error:", err) + return + } + + // Send the message to all clients + for connection := range WsClients { + if err := connection.WriteMessage(websocket.TextMessage, marshalMessage); err != nil { + log.Println("write error:", err) + + err := connection.WriteMessage(websocket.CloseMessage, []byte{}) + if err != nil { + log.Println("write message close error:", err) + return + } + err = connection.Close() + if err != nil { + log.Println("close error:", err) + return + } + delete(WsClients, connection) + } + } + + case connection := <-WsUnregister: + // Remove the client from the hub + delete(WsClients, connection) + + log.Println("connection unregistered") + } + } +} diff --git a/src/services/app_service.go b/src/services/app_service.go index 4f8f09a..1c80d0a 100644 --- a/src/services/app_service.go +++ b/src/services/app_service.go @@ -6,6 +6,7 @@ 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" @@ -81,6 +82,10 @@ 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 a64ab55..72f9dfa 100644 --- a/src/utils/whatsapp.go +++ b/src/utils/whatsapp.go @@ -6,6 +6,7 @@ import ( "encoding/json" "fmt" "github.com/aldinokemal/go-whatsapp-web-multidevice/config" + "github.com/aldinokemal/go-whatsapp-web-multidevice/internal/rest/helpers" "go.mau.fi/whatsmeow" "go.mau.fi/whatsmeow/appstate" waProto "go.mau.fi/whatsmeow/binary/proto" @@ -24,10 +25,12 @@ import ( ) var ( - cli *whatsmeow.Client - log waLog.Logger - historySyncID int32 - startupTime = time.Now().Unix() + cli *whatsmeow.Client + log waLog.Logger + historySyncID int32 + LoginTime time.Time + LoginIsNotified bool + startupTime = time.Now().Unix() ) func GetPlatformName(deviceID int) string { @@ -138,6 +141,14 @@ func handler(rawEvt interface{}) { 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. err := cli.SendPresence(types.PresenceAvailable) diff --git a/src/views/index.html b/src/views/index.html index 2d06550..e06c816 100644 --- a/src/views/index.html +++ b/src/views/index.html @@ -576,6 +576,7 @@ return { login_link: '', login_duration_sec: 0, + autoUpdateQRCode: null, } }, methods: { @@ -583,6 +584,9 @@ try { await this.loginApiGetQrCode(); $('#modalLogin').modal('show'); + this.autoUpdateQRCode = setInterval(async () => { + await this.loginApiGetQrCode(); + }, {{.QRRefreshSeconds}} ); } catch (err) { showErrorInfo(err) } @@ -1101,7 +1105,31 @@ data() { return { app_host: {{ .AppHost }}, - app_name: 'Whatsapp API Multi Device ({{ .AppVersion }})' + app_name: 'Whatsapp API Multi Device ({{ .AppVersion }})', + is_logged_in: false, + } + }, + mounted() { + if (window["WebSocket"]) { + let wsType = location.protocol !== 'https:' ? 'ws://' : 'wss://'; + let conn = new WebSocket(wsType + document.location.host + "/ws"); + conn.onclose = function (evt) { + console.log(evt) + }; + conn.onmessage = function (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) + } + }; + } else { + console.log('Your browser does not support WebSockets'); } }, methods: {