Browse Source

feat: trigger when pair success

pull/33/head
Aldino Kemal 3 years ago
parent
commit
280a9b09f0
  1. 63
      src/cmd/root.go
  2. 17
      src/config/settings.go
  3. 13
      src/internal/rest/helpers/common.go
  4. 45
      src/internal/rest/helpers/websocket.go
  5. 5
      src/services/app_service.go
  6. 22
      src/utils/whatsapp.go
  7. 27
      src/views/index.html

63
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())

17
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"

13
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))
}

45
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)
}
}
}))
}

5
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
}

22
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.

27
src/views/index.html

@ -228,12 +228,15 @@
<div class="description">
<div class="ui header">Please scan to connect</div>
<p>Open Setting > Linked Devices > Link Device</p>
<div style="padding-top: 50px;">
<i>Refresh QR Code in [[ login_duration_sec ]] seconds to avoid link expiration</i>
</div>
</div>
</div>
<div class="actions">
<div class="ui positive right labeled icon button">
Done
<i class="checkmark icon"></i>
<div class="ui approve positive right labeled icon button" @click="loginApiGetQrCode">
Refresh QR Code
<i class="refresh icon"></i>
</div>
</div>
</div>
@ -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)

Loading…
Cancel
Save