package cmd import ( "fmt" "log" "net/http" "strings" "github.com/aldinokemal/go-whatsapp-web-multidevice/config" "github.com/aldinokemal/go-whatsapp-web-multidevice/ui/rest" "github.com/aldinokemal/go-whatsapp-web-multidevice/ui/rest/helpers" "github.com/aldinokemal/go-whatsapp-web-multidevice/ui/rest/middleware" "github.com/aldinokemal/go-whatsapp-web-multidevice/ui/websocket" "github.com/dustin/go-humanize" "github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2/middleware/basicauth" "github.com/gofiber/fiber/v2/middleware/cors" "github.com/gofiber/fiber/v2/middleware/filesystem" "github.com/gofiber/fiber/v2/middleware/logger" "github.com/gofiber/template/html/v2" "github.com/spf13/cobra" ) // rootCmd represents the base command when called without any subcommands var restCmd = &cobra.Command{ Use: "rest", Short: "Send whatsapp API over http", Long: `This application is from clone https://github.com/aldinokemal/go-whatsapp-web-multidevice`, Run: restServer, } func init() { rootCmd.AddCommand(restCmd) } func restServer(_ *cobra.Command, _ []string) { engine := html.NewFileSystem(http.FS(EmbedIndex), ".html") engine.AddFunc("isEnableBasicAuth", func(token any) bool { return token != nil }) app := fiber.New(fiber.Config{ Views: engine, BodyLimit: int(config.WhatsappSettingMaxVideoSize), }) app.Static("/statics", "./statics") app.Use("/components", filesystem.New(filesystem.Config{ Root: http.FS(EmbedViews), PathPrefix: "views/components", Browse: true, })) app.Use("/assets", filesystem.New(filesystem.Config{ Root: http.FS(EmbedViews), PathPrefix: "views/assets", Browse: true, })) app.Use(middleware.Recovery()) app.Use(middleware.BasicAuth()) if config.AppDebug { app.Use(logger.New()) } app.Use(cors.New(cors.Config{ AllowOrigins: "*", AllowHeaders: "Origin, Content-Type, Accept", })) if len(config.AppBasicAuthCredential) > 0 { account := make(map[string]string) for _, basicAuth := range config.AppBasicAuthCredential { ba := strings.Split(basicAuth, ":") if len(ba) != 2 { log.Fatalln("Basic auth is not valid, please this following format :") } account[ba[0]] = ba[1] } app.Use(basicauth.New(basicauth.Config{ Users: account, })) } // Rest rest.InitRestApp(app, appUsecase) rest.InitRestSend(app, sendUsecase) rest.InitRestUser(app, userUsecase) rest.InitRestMessage(app, messageUsecase) rest.InitRestGroup(app, groupUsecase) rest.InitRestNewsletter(app, newsletterUsecase) app.Get("/", func(c *fiber.Ctx) error { return c.Render("views/index", fiber.Map{ "AppHost": fmt.Sprintf("%s://%s", c.Protocol(), c.Hostname()), "AppVersion": config.AppVersion, "BasicAuthToken": c.UserContext().Value(middleware.AuthorizationValue("BASIC_AUTH")), "MaxFileSize": humanize.Bytes(uint64(config.WhatsappSettingMaxFileSize)), "MaxVideoSize": humanize.Bytes(uint64(config.WhatsappSettingMaxVideoSize)), }) }) websocket.RegisterRoutes(app, appUsecase) go websocket.RunHub() // Set auto reconnect to whatsapp server after booting go helpers.SetAutoConnectAfterBooting(appUsecase) // Set auto reconnect checking go helpers.SetAutoReconnectChecking(whatsappCli) // Start auto flush chat csv if config.WhatsappChatStorage { go helpers.StartAutoFlushChatStorage() } if err := app.Listen(":" + config.AppPort); err != nil { log.Fatalln("Failed to start: ", err.Error()) } }