Updated the app following WhatsApp connexion changes

This commit is contained in:
2022-05-15 23:31:38 +02:00
parent 902c3babc2
commit d7c163cf4e

View File

@@ -1,21 +1,24 @@
package main package main
import ( import (
"context"
"database/sql" "database/sql"
"encoding/gob"
"encoding/hex"
"flag" "flag"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"math/rand"
"os" "os"
"os/signal" "os/signal"
"strings" "strings"
"time" "time"
_ "github.com/go-sql-driver/mysql" _ "github.com/go-sql-driver/mysql"
qrcodeTerminal "github.com/Baozisoftware/qrcode-terminal-go" "github.com/mdp/qrterminal/v3"
"github.com/Rhymen/go-whatsapp" _ "github.com/mattn/go-sqlite3"
"github.com/Rhymen/go-whatsapp/binary/proto" "google.golang.org/protobuf/proto"
"go.mau.fi/whatsmeow"
"go.mau.fi/whatsmeow/types"
"go.mau.fi/whatsmeow/store/sqlstore"
waProto "go.mau.fi/whatsmeow/binary/proto"
waLog "go.mau.fi/whatsmeow/util/log"
) )
type parameters struct { type parameters struct {
@@ -37,122 +40,93 @@ func loadParameters() (parameters) {
return *param return *param
} }
func login(wac *whatsapp.Conn, sessionFile string) error { func connect(param parameters) (*whatsmeow.Client, error) {
// Load saved session dbLog := waLog.Stdout("Database", "ERROR", true)
session, err := readSession(sessionFile) container, err := sqlstore.New("sqlite3", "file:" + param.whatsappSessionFile + "?_foreign_keys=on", dbLog)
if err == nil { if err != nil {
// Restore session return nil, err
session, err = wac.RestoreWithSession(session) }
deviceStore, err := container.GetFirstDevice()
if err != nil {
return nil, err
}
clientLog := waLog.Stdout("Client", "ERROR", true)
client := whatsmeow.NewClient(deviceStore, clientLog)
if client.Store.ID == nil {
// No ID stored, new login
qrChan, _ := client.GetQRChannel(context.Background())
err = client.Connect()
if err != nil { if err != nil {
return fmt.Errorf("restoring failed: %v", err) return nil, err
}
for evt := range qrChan {
if evt.Event == "code" {
qrterminal.GenerateHalfBlock(evt.Code, qrterminal.L, os.Stdout)
fmt.Println("QR code:", evt.Code)
} else {
fmt.Println("Login event:", evt.Event)
}
} }
} else { } else {
// No saved session -> regular login // Already logged in, just connect
qr := make(chan string) err = client.Connect()
go func() {
terminal := qrcodeTerminal.New()
terminal.Get(<-qr).Print()
}()
session, err = wac.Login(qr)
if err != nil { if err != nil {
return fmt.Errorf("error during login: %v", err) return nil, err
} }
} }
// Save session return client, nil
err = writeSession(session, sessionFile)
if err != nil {
return fmt.Errorf("error saving session: %v", err)
}
return nil
} }
func readSession(sessionFile string) (whatsapp.Session, error) { func sendMessage(client *whatsmeow.Client, group string, message string, title string, thumbnail []byte) error {
session := whatsapp.Session{} jid, err := types.ParseJID(group)
file, err := os.Open(sessionFile)
if err != nil { if err != nil {
return session, err return fmt.Errorf("Incorrect group identifier '%s': %v", group, err)
} }
defer file.Close()
decoder := gob.NewDecoder(file)
err = decoder.Decode(&session)
if err != nil {
return session, err
}
return session, nil
}
func writeSession(session whatsapp.Session, sessionFile string) error { msg := &waProto.Message{ExtendedTextMessage: &waProto.ExtendedTextMessage{
file, err := os.Create(sessionFile) Text: proto.String(message),
if err != nil { Description: proto.String(title),
return err JpegThumbnail: thumbnail,
} }}
defer file.Close() ts, err := client.SendMessage(jid, "", msg)
encoder := gob.NewEncoder(file)
err = encoder.Encode(session)
if err != nil {
return err
}
return nil
}
func sendMessage(wac *whatsapp.Conn, group string, message string, title string, thumbnail []byte) error {
ts := uint64(time.Now().Unix())
status := proto.WebMessageInfo_PENDING
b := make([]byte, 10)
rand.Read(b)
id := strings.ToUpper(hex.EncodeToString(b))
fromMe := true
msg := &proto.WebMessageInfo{
Key: &proto.MessageKey{
FromMe: &fromMe,
Id: &id,
RemoteJid: &group,
},
MessageTimestamp: &ts,
Message: &proto.Message{
ExtendedTextMessage: &proto.ExtendedTextMessage{
Title: &title,
Text: &message,
JpegThumbnail: thumbnail,
},
},
Status: &status,
}
msgId, err := wac.Send(msg)
if err != nil { if err != nil {
return fmt.Errorf("Error sending message with title '%s': %v", title, err) return fmt.Errorf("Error sending message with title '%s': %v", title, err)
} }
fmt.Fprintf(os.Stdout, "Message with title '%s' and id '%d' sent\n", title, msgId) fmt.Fprintf(os.Stdout, "Message with title '%s' sent (timestamp: %s)\n", title, ts)
return nil return nil
} }
func testConnexions(param parameters) error { func testConnexions(param parameters) error {
// Create new WhatsApp connection and connect // Create new WhatsApp connection and connect
wac, err := whatsapp.NewConn(20 * time.Second) client, err := connect(param)
if err != nil { if err != nil {
return fmt.Errorf("Error creating connection to WhatsApp: %v", err) return fmt.Errorf("Error connecting to WhatsApp: %v", err)
}
wac.SetClientVersion(2, 3147, 10)
err = login(wac, param.whatsappSessionFile)
if err != nil {
return fmt.Errorf("Error logging in WhatsApp: %v", err)
} }
<-time.After(3 * time.Second) <-time.After(3 * time.Second)
defer wac.Disconnect() defer client.Disconnect()
// Prints the available groups if none provided // Prints the available groups if none provided
if param.whatsappGroup == "" { if param.whatsappGroup == "" {
fmt.Fprintf(os.Stdout, "No WhatsApp group provided, showing all available groups\n") fmt.Fprintf(os.Stdout, "No WhatsApp group provided, showing all available groups\n")
for _, chatNode := range wac.Store.Chats { groups, err := client.GetJoinedGroups()
fmt.Fprintf(os.Stdout, "%s | %s\n", chatNode.Jid, chatNode.Name) if err != nil {
return fmt.Errorf("Error getting groups list: %v", err)
}
for _, groupInfo := range groups {
fmt.Fprintf(os.Stdout, "%s | %s\n", groupInfo.JID, groupInfo.GroupName)
} }
return fmt.Errorf("No WhatsApp group provided") return fmt.Errorf("No WhatsApp group provided")
} else { } else {
_, exists := wac.Store.Chats[param.whatsappGroup] jid, err := types.ParseJID(param.whatsappGroup)
if (!exists) { if err != nil {
return fmt.Errorf("Incorrect group identifier '%s': %v", param.whatsappGroup, err)
}
_, err = client.GetGroupInfo(jid)
if err != nil {
return fmt.Errorf("Unknown WhatsApp group %s", param.whatsappGroup) return fmt.Errorf("Unknown WhatsApp group %s", param.whatsappGroup)
} }
} }
@@ -180,21 +154,12 @@ func testConnexions(param parameters) error {
func runLoop(param parameters) error { func runLoop(param parameters) error {
// Create new WhatsApp connection and connect // Create new WhatsApp connection and connect
wac, err := whatsapp.NewConn(20 * time.Second) client, err := connect(param)
if err != nil { if err != nil {
return fmt.Errorf("Error creating connection to WhatsApp: %v", err) return fmt.Errorf("Error creating connection to WhatsApp: %v", err)
} }
wac.SetClientVersion(2, 3147, 10)
err = login(wac, param.whatsappSessionFile)
if err != nil {
time.Sleep(30 * time.Second)
err = login(wac, param.whatsappSessionFile)
if err != nil {
return fmt.Errorf("Error logging in WhatsApp: %v", err)
}
}
<-time.After(3 * time.Second) <-time.After(3 * time.Second)
defer wac.Disconnect() defer client.Disconnect()
// Connect to MySQL and execute the first query // Connect to MySQL and execute the first query
db, err := sql.Open("mysql", param.mysqlURL + "?parseTime=true") db, err := sql.Open("mysql", param.mysqlURL + "?parseTime=true")
@@ -240,7 +205,7 @@ func runLoop(param parameters) error {
} }
// Send the message // Send the message
sendMessage(wac, param.whatsappGroup, fmt.Sprintf("Il y a %d an(s) : %s", time.Now().Year()-albumDate.Year(), url), albumName, thumbnail) sendMessage(client, param.whatsappGroup, fmt.Sprintf("Il y a %d an(s) : %s", time.Now().Year()-albumDate.Year(), url), albumName, thumbnail)
if err != nil { if err != nil {
fmt.Fprintf(os.Stderr, "Error sending message to WhatsApp for album '%s': %v\n", albumName, err) fmt.Fprintf(os.Stderr, "Error sending message to WhatsApp for album '%s': %v\n", albumName, err)
continue continue
@@ -283,7 +248,7 @@ func runLoop(param parameters) error {
} }
// Send the message // Send the message
sendMessage(wac, param.whatsappGroup, fmt.Sprintf("Nouvel album : %s", url), albumName, thumbnail) sendMessage(client, param.whatsappGroup, fmt.Sprintf("Nouvel album : %s", url), albumName, thumbnail)
if err != nil { if err != nil {
fmt.Fprintf(os.Stderr, "Error sending message to WhatsApp for album '%s': %v\n", albumName, err) fmt.Fprintf(os.Stderr, "Error sending message to WhatsApp for album '%s': %v\n", albumName, err)
continue continue