From 8bd67a27801592ea3d7e4101367326d8de0a85fb Mon Sep 17 00:00:00 2001 From: Keyur Shah Date: Sat, 20 Apr 2024 16:22:19 +0530 Subject: [PATCH] Whatsapp BUILD Completed --- .env_template | 3 +- apis/index.go | 18 +++++------- apis/qr-browser.api.go | 65 ++++++++++++++++++++++++++++++++++++++++++ env/index.go | 24 ++++++++++------ env/keys.go | 3 +- go.mod | 1 + go.sum | 2 ++ main.go | 7 +++-- qrcode-web/index.html | 62 +++++++++++++++++++++++++++++----------- utility/mime.go | 23 +++++++++++++++ whatsapp/index.go | 5 ++-- whatsapp/interfaces.go | 10 ++++++- 12 files changed, 179 insertions(+), 44 deletions(-) create mode 100644 apis/qr-browser.api.go diff --git a/.env_template b/.env_template index 57d56dc..54298c4 100644 --- a/.env_template +++ b/.env_template @@ -3,4 +3,5 @@ APP_ENV="LOCAL" # "LOCAL" || "PRODUCTION" || "CI" PORT="4000" ALLOW_LOCAL_NO_AUTH="true" -DO_NOT_AUTO_CONNECT_TO_WHATSAPP="true" \ No newline at end of file +AUTO_CONNECT_TO_WHATSAPP="true" +OPEN_BROWSER_FOR_SCAN="true" \ No newline at end of file diff --git a/apis/index.go b/apis/index.go index 79385f6..2159937 100644 --- a/apis/index.go +++ b/apis/index.go @@ -1,6 +1,7 @@ package apis import ( + "encoding/base64" "encoding/json" "fmt" "net/http" @@ -11,6 +12,7 @@ import ( "github.com/rpsoftech/whatsapp-http-api/middleware" "github.com/rpsoftech/whatsapp-http-api/utility" "github.com/rpsoftech/whatsapp-http-api/whatsapp" + "github.com/skip2/go-qrcode" ) type ( @@ -36,16 +38,6 @@ func AddApis(app fiber.Router) { } } -func QrScan(c *fiber.Ctx) error { - id := c.Params("id") - if id == "" { - return c.SendStatus(http.StatusBadRequest) - } - return c.JSON(fiber.Map{ - id: id, - }) -} - func SendMediaFile(c *fiber.Ctx) error { body := new(apiSendMessage) c.BodyParser(body) @@ -231,6 +223,7 @@ func GetQrCode(c *fiber.Ctx) error { if err != nil { return err } + connection, ok := whatsapp.ConnectionMap[number] if !ok || connection == nil { return &interfaces.RequestError{ @@ -241,9 +234,12 @@ func GetQrCode(c *fiber.Ctx) error { } } err = connection.ReturnStatusError() + if err != nil { + png, _ := qrcode.Encode(connection.QrCodeString, qrcode.High, 512) return c.JSON(fiber.Map{ - "qrCode": connection.QrCodeString, + "qrCode": base64.StdEncoding.EncodeToString(png), + "qrCodeData": connection.QrCodeString, }) } return c.JSON(fiber.Map{ diff --git a/apis/qr-browser.api.go b/apis/qr-browser.api.go new file mode 100644 index 0000000..d880800 --- /dev/null +++ b/apis/qr-browser.api.go @@ -0,0 +1,65 @@ +package apis + +import ( + "fmt" + + "github.com/gofiber/fiber/v2" +) + +const index = ` + + + + + QR Code Scanner For + + +

Scan The QR Code to Log into whatsapp web account

+ + + +` + +func OpenBrowserWithQr(c *fiber.Ctx) error { + id := c.Params("id") + // println(c.Hostname()) + c.Set("Content-Type", "text/html; charset=utf-8") + return c.Send([]byte(fmt.Sprintf(index, id))) +} diff --git a/env/index.go b/env/index.go index 97c1768..d264484 100644 --- a/env/index.go +++ b/env/index.go @@ -14,10 +14,11 @@ import ( type ( EnvInterface struct { - APP_ENV AppEnv `json:"APP_ENV" validate:"required,enum=AppEnv"` - PORT int `json:"PORT" validate:"required,port"` - ALLOW_LOCAL_NO_AUTH bool `json:"ALLOW_LOCAL_NO_AUTH" validate:"boolean"` - DO_NOT_AUTO_CONNECT_TO_WHATSAPP bool `json:"DO_NOT_AUTO_CONNECT_TO_WHATSAPP" validate:"boolean"` + APP_ENV AppEnv `json:"APP_ENV" validate:"required,enum=AppEnv"` + PORT int `json:"PORT" validate:"required,port"` + ALLOW_LOCAL_NO_AUTH bool `json:"ALLOW_LOCAL_NO_AUTH" validate:"boolean"` + AUTO_CONNECT_TO_WHATSAPP bool `json:"AUTO_CONNECT_TO_WHATSAPP" validate:"boolean"` + OPEN_BROWSER_FOR_SCAN bool `json:"OPEN_BROWSER_FOR_SCAN" validate:"boolean"` // DB_URL string `json:"DB_URL" validate:"required,url"` // DB_NAME string `json:"DB_NAME_KEY" validate:"required,min=3"` // REDIS_DB_HOST string `json:"REDIS_DB_HOST" validate:"required"` @@ -56,16 +57,21 @@ func init() { log.Fatal(err) } - do_not_auto_connect_to_whatsapp, err := strconv.ParseBool(os.Getenv(do_Not_Auto_Connect_To_Whatsapp_KEY)) + auto_connect_to_whatsapp, err := strconv.ParseBool(os.Getenv(Auto_Connect_To_Whatsapp_KEY)) + if err != nil { + log.Fatal(err) + } + open_browser_for_scan_KEY, err := strconv.ParseBool(os.Getenv(open_browser_for_scan_KEY)) if err != nil { log.Fatal(err) } Env = &EnvInterface{ - APP_ENV: appEnv, - PORT: PORT, - ALLOW_LOCAL_NO_AUTH: allow_local_no_Auth, - DO_NOT_AUTO_CONNECT_TO_WHATSAPP: do_not_auto_connect_to_whatsapp, + APP_ENV: appEnv, + PORT: PORT, + ALLOW_LOCAL_NO_AUTH: allow_local_no_Auth, + AUTO_CONNECT_TO_WHATSAPP: auto_connect_to_whatsapp, + OPEN_BROWSER_FOR_SCAN: open_browser_for_scan_KEY, } errs := validator.Validator.Validate(Env) if len(errs) > 0 { diff --git a/env/keys.go b/env/keys.go index 14c973d..d88c087 100644 --- a/env/keys.go +++ b/env/keys.go @@ -3,7 +3,8 @@ package env const app_ENV_KEY = "APP_ENV" const port_KEY = "PORT" const allow_local_no_auth_KEY = "ALLOW_LOCAL_NO_AUTH" -const do_Not_Auto_Connect_To_Whatsapp_KEY = "DO_NOT_AUTO_CONNECT_TO_WHATSAPP" +const Auto_Connect_To_Whatsapp_KEY = "AUTO_CONNECT_TO_WHATSAPP" +const open_browser_for_scan_KEY = "OPEN_BROWSER_FOR_SCAN" // const db_URL_KEY = "DB_URL" // const db_NAME_KEY = "DB_NAME" diff --git a/go.mod b/go.mod index b94fc94..81d8b52 100644 --- a/go.mod +++ b/go.mod @@ -49,6 +49,7 @@ require ( github.com/rs/zerolog v1.32.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect + github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e // indirect github.com/swaggo/swag v1.16.3 // indirect github.com/urfave/cli/v2 v2.27.1 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect diff --git a/go.sum b/go.sum index 668dba6..069793c 100644 --- a/go.sum +++ b/go.sum @@ -176,6 +176,8 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeV github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0= +github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= diff --git a/main.go b/main.go index 8d9a17e..361a697 100644 --- a/main.go +++ b/main.go @@ -40,11 +40,10 @@ func main() { env.ServerConfig = ReadConfigFileAndReturnIt(env.CurrentDirectory) whatsapp.OutPutFilePath = ReturnOutPutFilePath(env.CurrentDirectory) whatsapp.InitSqlContainer() - if !env.Env.DO_NOT_AUTO_CONNECT_TO_WHATSAPP { - + if env.Env.AUTO_CONNECT_TO_WHATSAPP { go func() { for k, v := range env.ServerConfig.Tokens { - jidString := env.ServerConfig.JID[v] + jidString := env.ServerConfig.JID[k] whatsapp.ConnectToNumber(v, jidString, k) } }() @@ -71,6 +70,8 @@ func InitFiberServer() { app.Use(logger.New()) app.Static("/swagger", "./swagger") apis.AddApis(app.Group("/v1", middleware.TokenDecrypter, middleware.AllowOnlyValidTokenMiddleWare)) + + app.Get("/scan/:id", apis.OpenBrowserWithQr) app.Use(func(c *fiber.Ctx) error { return c.Status(fiber.StatusNotFound).SendString("Sorry can't find that!") }) diff --git a/qrcode-web/index.html b/qrcode-web/index.html index b162bb7..2eaeaa1 100644 --- a/qrcode-web/index.html +++ b/qrcode-web/index.html @@ -1,21 +1,51 @@ - - - - - QR Code Scanner For - - + + + + QR Code Scanner For + +

Scan The QR Code to Log into whatsapp web account

- + - - \ No newline at end of file + + diff --git a/utility/mime.go b/utility/mime.go index 4aa8897..3fd614e 100644 --- a/utility/mime.go +++ b/utility/mime.go @@ -1,7 +1,11 @@ package utility import ( + "fmt" + "log" + "os/exec" "path/filepath" + "runtime" "strings" ) @@ -12,3 +16,22 @@ func GetMime(fileName string) string { fileExt = strings.Replace(fileExt, ".", "", 1) return mimeList[fileExt] } + +func OpenBrowser(url string) { + var err error + + switch runtime.GOOS { + case "linux": + err = exec.Command("xdg-open", url).Start() + case "windows": + err = exec.Command("rundll32", "url.dll,FileProtocolHandler", url).Start() + case "darwin": + err = exec.Command("open", url).Start() + default: + err = fmt.Errorf("unsupported platform") + } + if err != nil { + log.Fatal(err) + } + +} diff --git a/whatsapp/index.go b/whatsapp/index.go index ef0f048..47c6de8 100644 --- a/whatsapp/index.go +++ b/whatsapp/index.go @@ -56,8 +56,9 @@ func ConnectToNumber(number string, jidString string, token string) { // BaseURL: "https://web.whatsapp.com", // } // client.PairPhone() - connection := &WhatsappConnection{Client: client, Number: number, ConnectionStatus: 0, SyncFinished: false} - ConnectionMap[number] = connection + connection := &WhatsappConnection{Client: client, Number: number, ConnectionStatus: 0, SyncFinished: false, Token: token} + ConnectionMap[token] = connection client.AddEventHandler(connection.eventHandler) + connection.ConnectAndGetQRCode() } diff --git a/whatsapp/interfaces.go b/whatsapp/interfaces.go index 3543361..7700b64 100644 --- a/whatsapp/interfaces.go +++ b/whatsapp/interfaces.go @@ -60,6 +60,11 @@ func (connection *WhatsappConnection) ReturnStatusError() error { func (connection *WhatsappConnection) ConnectAndGetQRCode() { if connection.Client.Store.ID == nil { // No ID stored, new login + if env.Env.OPEN_BROWSER_FOR_SCAN { + go func(token string) { + utility.OpenBrowser(fmt.Sprintf("http://127.0.0.1:%d/scan/%s", env.Env.PORT, token)) + }(connection.Token) + } qrChan, _ := connection.Client.GetQRChannel(context.Background()) err := connection.Client.Connect() if err != nil { @@ -69,7 +74,10 @@ func (connection *WhatsappConnection) ConnectAndGetQRCode() { if evt.Event == "code" { fmt.Printf("QR code for %s\n", connection.Token) connection.QrCodeString = evt.Code - qrterminal.GenerateHalfBlock(evt.Code, qrterminal.L, os.Stdout) + // env.ServerConfig.Tokens[connection.Token] = "Something" + if !env.Env.OPEN_BROWSER_FOR_SCAN { + qrterminal.GenerateHalfBlock(evt.Code, qrterminal.L, os.Stdout) + } } else { fmt.Println("Login event:", evt.Event) }