summaryrefslogtreecommitdiffstats
path: root/bridge/whatsapp/helpers.go
diff options
context:
space:
mode:
Diffstat (limited to 'bridge/whatsapp/helpers.go')
-rw-r--r--bridge/whatsapp/helpers.go163
1 files changed, 110 insertions, 53 deletions
diff --git a/bridge/whatsapp/helpers.go b/bridge/whatsapp/helpers.go
index b32372c5..e424387d 100644
--- a/bridge/whatsapp/helpers.go
+++ b/bridge/whatsapp/helpers.go
@@ -1,12 +1,15 @@
package bwhatsapp
import (
+ "encoding/gob"
+ "encoding/json"
+ "errors"
"fmt"
+ "os"
"strings"
- "go.mau.fi/whatsmeow/store"
- "go.mau.fi/whatsmeow/store/sqlstore"
- "go.mau.fi/whatsmeow/types"
+ qrcodeTerminal "github.com/Baozisoftware/qrcode-terminal-go"
+ "github.com/Rhymen/go-whatsapp"
)
type ProfilePicInfo struct {
@@ -15,71 +18,141 @@ type ProfilePicInfo struct {
Status int16 `json:"status"`
}
-func (b *Bwhatsapp) getSenderName(senderJid types.JID) string {
- if sender, exists := b.contacts[senderJid]; exists {
- if sender.FullName != "" {
- return sender.FullName
- }
- // if user is not in phone contacts
- // it is the most obvious scenario unless you sync your phone contacts with some remote updated source
- // users can change it in their WhatsApp settings -> profile -> click on Avatar
- if sender.PushName != "" {
- return sender.PushName
- }
+func qrFromTerminal(invert bool) chan string {
+ qr := make(chan string)
+
+ go func() {
+ terminal := qrcodeTerminal.New()
- if sender.FirstName != "" {
- return sender.FirstName
+ if invert {
+ terminal = qrcodeTerminal.New2(qrcodeTerminal.ConsoleColors.BrightWhite, qrcodeTerminal.ConsoleColors.BrightBlack, qrcodeTerminal.QRCodeRecoveryLevels.Medium)
}
+
+ terminal.Get(<-qr).Print()
+ }()
+
+ return qr
+}
+
+func (b *Bwhatsapp) readSession() (whatsapp.Session, error) {
+ session := whatsapp.Session{}
+ sessionFile := b.Config.GetString(sessionFile)
+
+ if sessionFile == "" {
+ return session, errors.New("if you won't set SessionFile then you will need to scan QR code on every restart")
}
- // try to reload this contact
- if _, err := b.wc.Store.Contacts.GetAllContacts(); err != nil {
- b.Log.Errorf("error on update of contacts: %v", err)
+ file, err := os.Open(sessionFile)
+ if err != nil {
+ return session, err
}
- allcontacts, err := b.wc.Store.Contacts.GetAllContacts()
+ defer file.Close()
+
+ decoder := gob.NewDecoder(file)
+
+ return session, decoder.Decode(&session)
+}
+
+func (b *Bwhatsapp) writeSession(session whatsapp.Session) error {
+ sessionFile := b.Config.GetString(sessionFile)
+
+ if sessionFile == "" {
+ // we already sent a warning while starting the bridge, so let's be quiet here
+ return nil
+ }
+
+ file, err := os.Create(sessionFile)
if err != nil {
- b.Log.Errorf("error on update of contacts: %v", err)
+ return err
+ }
+
+ defer file.Close()
+
+ encoder := gob.NewEncoder(file)
+
+ return encoder.Encode(session)
+}
+
+func (b *Bwhatsapp) restoreSession() (*whatsapp.Session, error) {
+ session, err := b.readSession()
+ if err != nil {
+ b.Log.Warn(err.Error())
}
- if len(allcontacts) > 0 {
- b.contacts = allcontacts
+ b.Log.Debugln("Restoring WhatsApp session..")
+
+ session, err = b.conn.RestoreWithSession(session)
+ if err != nil {
+ // restore session connection timed out (I couldn't get over it without logging in again)
+ return nil, errors.New("failed to restore session: " + err.Error())
}
- if sender, exists := b.contacts[senderJid]; exists {
- if sender.FullName != "" {
- return sender.FullName
+ b.Log.Debugln("Session restored successfully!")
+
+ return &session, nil
+}
+
+func (b *Bwhatsapp) getSenderName(senderJid string) string {
+ if sender, exists := b.users[senderJid]; exists {
+ if sender.Name != "" {
+ return sender.Name
}
// if user is not in phone contacts
// it is the most obvious scenario unless you sync your phone contacts with some remote updated source
// users can change it in their WhatsApp settings -> profile -> click on Avatar
- if sender.PushName != "" {
- return sender.PushName
+ if sender.Notify != "" {
+ return sender.Notify
}
- if sender.FirstName != "" {
- return sender.FirstName
+ if sender.Short != "" {
+ return sender.Short
}
}
- return "Someone"
+ // try to reload this contact
+ _, err := b.conn.Contacts()
+ if err != nil {
+ b.Log.Errorf("error on update of contacts: %v", err)
+ }
+
+ if contact, exists := b.conn.Store.Contacts[senderJid]; exists {
+ // Add it to the user map
+ b.users[senderJid] = contact
+
+ if contact.Name != "" {
+ return contact.Name
+ }
+ // if user is not in phone contacts
+ // same as above
+ return contact.Notify
+ }
+
+ return ""
}
-func (b *Bwhatsapp) getSenderNotify(senderJid types.JID) string {
- if sender, exists := b.contacts[senderJid]; exists {
- return sender.PushName
+func (b *Bwhatsapp) getSenderNotify(senderJid string) string {
+ if sender, exists := b.users[senderJid]; exists {
+ return sender.Notify
}
return ""
}
-func (b *Bwhatsapp) GetProfilePicThumb(jid string) (*types.ProfilePictureInfo, error) {
- pjid, _ := types.ParseJID(jid)
- info, err := b.wc.GetProfilePictureInfo(pjid, true)
+func (b *Bwhatsapp) GetProfilePicThumb(jid string) (*ProfilePicInfo, error) {
+ data, err := b.conn.GetProfilePicThumb(jid)
if err != nil {
return nil, fmt.Errorf("failed to get avatar: %v", err)
}
+ content := <-data
+ info := &ProfilePicInfo{}
+
+ err = json.Unmarshal([]byte(content), info)
+ if err != nil {
+ return info, fmt.Errorf("failed to unmarshal avatar info: %v", err)
+ }
+
return info, nil
}
@@ -88,19 +161,3 @@ func isGroupJid(identifier string) bool {
strings.HasSuffix(identifier, "@temp") ||
strings.HasSuffix(identifier, "@broadcast")
}
-
-func (b *Bwhatsapp) getDevice() (*store.Device, error) {
- device := &store.Device{}
-
- storeContainer, err := sqlstore.New("sqlite", "file:"+b.Config.GetString("sessionfile")+".db?_foreign_keys=on&_pragma=busy_timeout=10000", nil)
- if err != nil {
- return device, fmt.Errorf("failed to connect to database: %v", err)
- }
-
- device, err = storeContainer.GetFirstDevice()
- if err != nil {
- return device, fmt.Errorf("failed to get device: %v", err)
- }
-
- return device, nil
-}