From 3a0b2414f8a297db9cae8abf187dfe61f251b79f Mon Sep 17 00:00:00 2001 From: Aldino Kemal Date: Wed, 23 Nov 2022 06:41:43 +0700 Subject: [PATCH] feat: add websocket (#33) * feat: add auto-update Login QR Code * feat: remove unused code * feat: trigger when pair success * feat: move WebSocket to independent package * feat: simply code --- src/cmd/root.go | 23 ++-- src/go.mod | 3 + src/go.sum | 12 ++ src/internal/rest/helpers/common.go | 13 +++ .../rest/{send_controller.go => send_rest.go} | 0 .../rest/{user_controller.go => user_rest.go} | 0 src/internal/websocket/websocket.go | 105 ++++++++++++++++++ src/utils/whatsapp.go | 7 ++ src/views/index.html | 44 +++++++- 9 files changed, 189 insertions(+), 18 deletions(-) create mode 100644 src/internal/rest/helpers/common.go rename src/internal/rest/{send_controller.go => send_rest.go} (100%) rename src/internal/rest/{user_controller.go => user_rest.go} (100%) create mode 100644 src/internal/websocket/websocket.go diff --git a/src/cmd/root.go b/src/cmd/root.go index cbef10a..b7cf302 100644 --- a/src/cmd/root.go +++ b/src/cmd/root.go @@ -5,6 +5,8 @@ import ( "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/internal/websocket" "github.com/aldinokemal/go-whatsapp-web-multidevice/middleware" "github.com/aldinokemal/go-whatsapp-web-multidevice/services" "github.com/aldinokemal/go-whatsapp-web-multidevice/utils" @@ -16,13 +18,10 @@ import ( "github.com/gofiber/template/html" "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 @@ -43,7 +42,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" } @@ -110,21 +109,19 @@ func runRest(cmd *cobra.Command, args []string) { }) }) + websocket.RegisterRoutes(app) + go websocket.RunHub() + // 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)) - }() - err = app.Listen(":" + config.AppPort) - if err != nil { + go helpers.SetAutoConnectAfterBooting() + if err = app.Listen(":" + config.AppPort); err != nil { log.Fatalln("Failed to start: ", err.Error()) } } // Execute adds all child commands to the root command and sets flags appropriately. func Execute() { - err := rootCmd.Execute() - if err != nil { + if err := rootCmd.Execute(); err != nil { os.Exit(1) } } 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/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/send_controller.go b/src/internal/rest/send_rest.go similarity index 100% rename from src/internal/rest/send_controller.go rename to src/internal/rest/send_rest.go diff --git a/src/internal/rest/user_controller.go b/src/internal/rest/user_rest.go similarity index 100% rename from src/internal/rest/user_controller.go rename to src/internal/rest/user_rest.go diff --git a/src/internal/websocket/websocket.go b/src/internal/websocket/websocket.go new file mode 100644 index 0000000..bf5098f --- /dev/null +++ b/src/internal/websocket/websocket.go @@ -0,0 +1,105 @@ +package websocket + +import ( + "encoding/json" + "github.com/gofiber/fiber/v2" + "github.com/gofiber/websocket/v2" + "log" +) + +type client struct{} // Add more data to this type if needed +type BroadcastMessage struct { + Code string `json:"code"` + Message string `json:"message"` +} + +var Clients = 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 Register = make(chan *websocket.Conn) +var Broadcast = make(chan BroadcastMessage) +var Unregister = make(chan *websocket.Conn) + +func RunHub() { + for { + select { + case connection := <-Register: + Clients[connection] = client{} + log.Println("connection registered") + + case message := <-Broadcast: + 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 Clients { + 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(Clients, connection) + } + } + + case connection := <-Unregister: + // Remove the client from the hub + delete(Clients, connection) + + log.Println("connection unregistered") + } + } +} + +func RegisterRoutes(app *fiber.App) { + 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() { + Unregister <- c + _ = c.Close() + }() + + // Register the client + Register <- 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 BroadcastMessage + err := json.Unmarshal(message, &messageData) + if err != nil { + log.Println("error unmarshal message:", err) + return + } + Broadcast <- messageData + } else { + log.Println("websocket message received of type", messageType) + } + } + })) +} diff --git a/src/utils/whatsapp.go b/src/utils/whatsapp.go index a64ab55..4bba2ac 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/websocket" "go.mau.fi/whatsmeow" "go.mau.fi/whatsmeow/appstate" waProto "go.mau.fi/whatsmeow/binary/proto" @@ -134,10 +135,16 @@ func handler(rawEvt interface{}) { log.Infof("Marked self as available") } } + case *events.PairSuccess: + websocket.Broadcast <- websocket.BroadcastMessage{ + 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 } + // 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..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 +
@@ -576,13 +579,18 @@ return { login_link: '', login_duration_sec: 0, + autoUpdateQRCode: null, } }, methods: { async loginModal() { try { await this.loginApiGetQrCode(); - $('#modalLogin').modal('show'); + $('#modalLogin').modal({ + onApprove: function () { + return false; + } + }).modal('show'); } catch (err) { showErrorInfo(err) } @@ -1101,7 +1109,33 @@ 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 = (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'); + break; + default: + console.log(message) + } + }; + } else { + console.error('Your browser does not support WebSockets'); } }, methods: {