super basic

This commit is contained in:
Karmanyaah Malhotra 2021-02-21 00:58:50 -05:00
parent eafc18099d
commit 7cb9983da8
17 changed files with 965 additions and 926 deletions

View File

@ -20,13 +20,13 @@ import (
// "errors" // "errors"
"context" "context"
"fmt" "fmt"
// "math" // "math"
"sort"
"strconv" "strconv"
"strings" "strings"
"github.com/Rhymen/go-whatsapp" "github.com/Rhymen/go-whatsapp"
"maunium.net/go/maulogger/v2" "maunium.net/go/maulogger/v2"
"maunium.net/go/mautrix" "maunium.net/go/mautrix"
@ -34,9 +34,6 @@ import (
"maunium.net/go/mautrix/event" "maunium.net/go/mautrix/event"
"maunium.net/go/mautrix/format" "maunium.net/go/mautrix/format"
"maunium.net/go/mautrix/id" "maunium.net/go/mautrix/id"
// "maunium.net/go/mautrix-whatsapp/database"
"maunium.net/go/mautrix-whatsapp/whatsapp-ext"
) )
type CommandHandler struct { type CommandHandler struct {
@ -382,10 +379,10 @@ const cmdLoginHelp = `login - Authenticate this Bridge as WhatsApp Web Client`
// CommandLogin handles login command // CommandLogin handles login command
func (handler *CommandHandler) CommandLogin(ce *CommandEvent) { func (handler *CommandHandler) CommandLogin(ce *CommandEvent) {
if !ce.User.Connect(true) { // if !ce.User.Connect(true) {
ce.User.log.Debugln("Connect() returned false, assuming error was logged elsewhere and canceling login.") // ce.User.log.Debugln("Connect() returned false, assuming error was logged elsewhere and canceling login.")
return // return
} // }
ce.User.Login(ce) ce.User.Login(ce)
} }
@ -418,8 +415,13 @@ func (handler *CommandHandler) CommandLogout(ce *CommandEvent) {
// ce.User.log.Warnln("Error while disconnecting after logout:", err) // ce.User.log.Warnln("Error while disconnecting after logout:", err)
// } // }
// ce.User.Conn.RemoveHandlers() // ce.User.Conn.RemoveHandlers()
// ce.User.Conn = nil ce.User.Conn.Stop(context.TODO())
// ce.User.removeFromJIDMap() ce.User.Conn = nil
ce.User.removeFromJIDMap()
ce.User.Token = ""
ce.User.JID = ""
ce.User.Client = nil
ce.User.Update()
// // TODO this causes a foreign key violation, which should be fixed // // TODO this causes a foreign key violation, which should be fixed
// //ce.User.JID = "" // //ce.User.JID = ""
// ce.User.SetSession(nil) // ce.User.SetSession(nil)
@ -489,15 +491,16 @@ func (handler *CommandHandler) CommandDeleteSession(ce *CommandEvent) {
const cmdReconnectHelp = `reconnect - Reconnect to WhatsApp` const cmdReconnectHelp = `reconnect - Reconnect to WhatsApp`
func (handler *CommandHandler) CommandReconnect(ce *CommandEvent) { func (handler *CommandHandler) CommandReconnect(ce *CommandEvent) {
// if ce.User.Conn == nil { fmt.Println(ce.User.Conn)
// if ce.User.Session == nil { if ce.User.Conn == nil {
// ce.Reply("No existing connection and no session. Did you mean `login`?") if len(ce.User.Token) == 0 {
// } else { ce.Reply("No existing connection and no token. Did you mean `login`?")
// ce.Reply("No existing connection, creating one...") } else {
// ce.User.Connect(false) ce.Reply("No existing connection, creating one...")
// } ce.User.Connect()
// return }
// } return
}
// wasConnected := true // wasConnected := true
// sess, err := ce.User.Conn.Disconnect() // sess, err := ce.User.Conn.Disconnect()
@ -750,18 +753,18 @@ func (handler *CommandHandler) CommandDeleteAllPortals(ce *CommandEvent) {
const cmdListHelp = `list <contacts|groups> [page] [items per page] - Get a list of all contacts and groups.` const cmdListHelp = `list <contacts|groups> [page] [items per page] - Get a list of all contacts and groups.`
func formatContacts(contacts bool, input map[string]whatsapp.Contact) (result []string) { func formatContacts(contacts bool, input map[string]whatsapp.Contact) (result []string) {
for jid, contact := range input { // for jid, contact := range input {
if strings.HasSuffix(jid, whatsappExt.NewUserSuffix) != contacts { // if strings.HasSuffix(jid, whatsappExt.NewUserSuffix) != contacts {
continue // continue
} // }
//
if contacts { // if contacts {
result = append(result, fmt.Sprintf("* %s / %s - `%s`", contact.Name, contact.Notify, contact.Jid[:len(contact.Jid)-len(whatsappExt.NewUserSuffix)])) // result = append(result, fmt.Sprintf("* %s / %s - `%s`", contact.Name, contact.Notify, contact.Jid[:len(contact.Jid)-len(whatsappExt.NewUserSuffix)]))
} else { // } else {
result = append(result, fmt.Sprintf("* %s - `%s`", contact.Name, contact.Jid)) // result = append(result, fmt.Sprintf("* %s - `%s`", contact.Name, contact.Jid))
} // }
} // }
sort.Sort(sort.StringSlice(result)) // sort.Sort(sort.StringSlice(result))
return return
} }

View File

@ -17,6 +17,8 @@
package database package database
import ( import (
"strings"
_ "github.com/lib/pq" _ "github.com/lib/pq"
_ "github.com/mattn/go-sqlite3" _ "github.com/mattn/go-sqlite3"
@ -26,6 +28,7 @@ import (
"gorm.io/driver/postgres" "gorm.io/driver/postgres"
"gorm.io/driver/sqlite" "gorm.io/driver/sqlite"
"gorm.io/gorm" "gorm.io/gorm"
"gorm.io/gorm/schema"
) )
type Database struct { type Database struct {
@ -52,6 +55,9 @@ func New(dbType string, uri string, baseLog log.Logger) (*Database, error) {
print("no") print("no")
gdb, err := gorm.Open(conn, &gorm.Config{ gdb, err := gorm.Open(conn, &gorm.Config{
// Logger: baseLog, // Logger: baseLog,
NamingStrategy: schema.NamingStrategy{
NameReplacer: strings.NewReplacer("JID", "Jid", "MXID", "Mxid"),
},
}) })
if err != nil { if err != nil {
panic("failed to connect database") panic("failed to connect database")
@ -81,6 +87,7 @@ func New(dbType string, uri string, baseLog log.Logger) (*Database, error) {
} }
func (db *Database) Init() error { func (db *Database) Init() error {
println("actual upgrade")
err := db.AutoMigrate(&Portal{}) err := db.AutoMigrate(&Portal{})
if err != nil { if err != nil {
return err return err
@ -104,6 +111,14 @@ func (db *Database) Init() error {
return err return err
} }
err = db.AutoMigrate(&User{})
if err != nil {
return err
}
err = db.AutoMigrate(&UserPortal{})
if err != nil {
return err
}
return upgrades.Run(db.log.Sub("Upgrade"), db.dialect, db.DB) return upgrades.Run(db.log.Sub("Upgrade"), db.dialect, db.DB)
} }

View File

@ -46,8 +46,8 @@ func (mq *MessageQuery) GetAll(chat PortalKey) (messages []*Message) {
func (mq *MessageQuery) GetByJID(chat PortalKey, jid types.WhatsAppMessageID) *Message { func (mq *MessageQuery) GetByJID(chat PortalKey, jid types.WhatsAppMessageID) *Message {
var message Message var message Message
ans := mq.db.Where("chat_jid = ? AND chat_receiver = ? AND jid = ?", chat.JID, chat.Receiver, jid).Take(&message) ans := mq.db.Where("chat_jid = ? AND chat_receiver = ? AND jid = ?", chat.JID, chat.Receiver, jid).Limit(1).Find(&message)
if ans.Error != nil { if ans.Error != nil || ans.RowsAffected == 0 {
return nil return nil
} }
return &message return &message
@ -55,8 +55,8 @@ func (mq *MessageQuery) GetByJID(chat PortalKey, jid types.WhatsAppMessageID) *M
func (mq *MessageQuery) GetByMXID(mxid id.EventID) *Message { func (mq *MessageQuery) GetByMXID(mxid id.EventID) *Message {
var message Message var message Message
ans := mq.db.Where("mxid = ?", mxid).Take(&message) ans := mq.db.Where("mxid = ?", mxid).Limit(1).Find(&message)
if ans.Error != nil { if ans.Error != nil || ans.RowsAffected == 0 {
return nil return nil
} }
return &message return &message
@ -64,8 +64,8 @@ func (mq *MessageQuery) GetByMXID(mxid id.EventID) *Message {
func (mq *MessageQuery) GetLastInChat(chat PortalKey) *Message { func (mq *MessageQuery) GetLastInChat(chat PortalKey) *Message {
var message Message var message Message
ans := mq.db.Where("chat_jid = ? AND chat_receiver = ?", chat.JID, chat.Receiver).Order("timestamp desc").First(&message) ans := mq.db.Where("chat_jid = ? AND chat_receiver = ?", chat.JID, chat.Receiver).Order("timestamp desc").Limit(1).Find(&message)
if ans.Error != nil { if ans.Error != nil || ans.RowsAffected == 0 {
return nil return nil
} }
return &message return &message
@ -77,7 +77,7 @@ type Message struct {
log log.Logger log log.Logger
Chat PortalKey `gorm:"primaryKey;embedded;embeddedPrefix:chat_"` Chat PortalKey `gorm:"primaryKey;embedded;embeddedPrefix:chat_"`
JID types.WhatsAppMessageID `gorm:"primaryKey"` JID types.GroupMeID `gorm:"primaryKey"`
MXID id.EventID `gorm:"unique;notNull"` MXID id.EventID `gorm:"unique;notNull"`
Sender types.GroupMeID `gorm:"notNull"` Sender types.GroupMeID `gorm:"notNull"`
Timestamp uint64 `gorm:"notNull;default:0"` Timestamp uint64 `gorm:"notNull;default:0"`

View File

@ -73,7 +73,7 @@ func (pq *PortalQuery) GetAll() []*Portal {
} }
func (pq *PortalQuery) GetByJID(key PortalKey) *Portal { func (pq *PortalQuery) GetByJID(key PortalKey) *Portal {
return pq.get(pq.db.DB.Where("jit = ? AND receiver = ?", key.JID, key.Receiver)) return pq.get(pq.db.DB.Where("jid = ? AND receiver = ?", key.JID, key.Receiver))
} }
@ -97,16 +97,23 @@ func (pq *PortalQuery) getAll(db *gorm.DB) (portals []*Portal) {
if ans.Error != nil || len(portals) == 0 { if ans.Error != nil || len(portals) == 0 {
return nil return nil
} }
for _, i := range portals {
i.db = pq.db
i.log = pq.log
}
return return
} }
func (pq *PortalQuery) get(db *gorm.DB) *Portal { func (pq *PortalQuery) get(db *gorm.DB) *Portal {
var portal Portal var portal Portal
ans := db.Take(&portal) ans := db.Limit(1).Find(&portal)
if ans.Error != nil { if ans.Error != nil || db.RowsAffected == 0 {
return nil return nil
} }
portal.db = pq.db
portal.log = pq.log
return &portal return &portal
} }
@ -155,8 +162,7 @@ func (portal *Portal) Insert() {
} }
func (portal *Portal) Update() { func (portal *Portal) Update() {
ans := portal.db.Where("jid = ? AND receiver = ?", portal.Key.JID, portal.Key.Receiver).Save(&portal)
ans := portal.db.Model(&portal).Updates(portal)
print("check .model vs not") print("check .model vs not")
if ans.Error != nil { if ans.Error != nil {
@ -172,6 +178,7 @@ func (portal *Portal) Delete() {
} }
func (portal *Portal) GetUserIDs() []id.UserID { func (portal *Portal) GetUserIDs() []id.UserID {
println("HI AAAAAAAAAAAAAAAAAAAa")
rows, err := portal.db.Raw(`SELECT "user".mxid FROM "user", user_portal rows, err := portal.db.Raw(`SELECT "user".mxid FROM "user", user_portal
WHERE "user".jid=user_portal.user_jid WHERE "user".jid=user_portal.user_jid
AND user_portal.portal_jid=$1 AND user_portal.portal_jid=$1

View File

@ -53,8 +53,8 @@ func (pq *PuppetQuery) GetAll() (puppets []*Puppet) {
func (pq *PuppetQuery) Get(jid types.GroupMeID) *Puppet { func (pq *PuppetQuery) Get(jid types.GroupMeID) *Puppet {
puppet := Puppet{} puppet := Puppet{}
ans := pq.db.Where("jid = ?", jid).Take(puppet) ans := pq.db.Where("jid = ?", jid).Limit(1).Find(&puppet)
if ans.Error != nil { if ans.Error != nil || ans.RowsAffected == 0 {
return nil return nil
} }
return &puppet return &puppet
@ -62,8 +62,8 @@ func (pq *PuppetQuery) Get(jid types.GroupMeID) *Puppet {
func (pq *PuppetQuery) GetByCustomMXID(mxid id.UserID) *Puppet { func (pq *PuppetQuery) GetByCustomMXID(mxid id.UserID) *Puppet {
puppet := Puppet{} puppet := Puppet{}
ans := pq.db.Where("custom_mxid = ?", mxid).Take(puppet) ans := pq.db.Where("custom_mxid = ?", mxid).Limit(1).Find(&puppet)
if ans.Error != nil { if ans.Error != nil || ans.RowsAffected == 0 {
return nil return nil
} }
return &puppet return &puppet
@ -93,7 +93,7 @@ type Puppet struct {
Displayname string Displayname string
NameQuality int8 NameQuality int8
CustomMXID id.UserID CustomMXID id.UserID `gorm:"column:custom_mxid;"`
AccessToken string AccessToken string
NextBatch string NextBatch string
EnablePresence bool `gorm:"notNull;default:true"` EnablePresence bool `gorm:"notNull;default:true"`

View File

@ -55,7 +55,8 @@ func NewSQLStateStore(db *Database) *SQLStateStore {
func (store *SQLStateStore) IsRegistered(userID id.UserID) bool { func (store *SQLStateStore) IsRegistered(userID id.UserID) bool {
v := mxRegistered{UserID: userID.String()} v := mxRegistered{UserID: userID.String()}
ans := store.db.First(&v) var count int64
ans := store.db.Model(&mxRegistered{}).Where(&v).Count(&count)
if errors.Is(ans.Error, gorm.ErrRecordNotFound) { if errors.Is(ans.Error, gorm.ErrRecordNotFound) {
return false return false
@ -63,7 +64,7 @@ func (store *SQLStateStore) IsRegistered(userID id.UserID) bool {
if ans.Error != nil { if ans.Error != nil {
store.log.Warnfln("Failed to scan registration existence for %s: %v", userID, ans.Error) store.log.Warnfln("Failed to scan registration existence for %s: %v", userID, ans.Error)
} }
return true return count >= 1
} }
func (store *SQLStateStore) MarkRegistered(userID id.UserID) { func (store *SQLStateStore) MarkRegistered(userID id.UserID) {
@ -113,7 +114,7 @@ func (store *SQLStateStore) GetRoomMembers(roomID id.RoomID) map[id.UserID]*even
func (store *SQLStateStore) GetMembership(roomID id.RoomID, userID id.UserID) event.Membership { func (store *SQLStateStore) GetMembership(roomID id.RoomID, userID id.UserID) event.Membership {
var user mxUserProfile var user mxUserProfile
ans := store.db.Where("room_id = ? AND user_id = ?", roomID, userID).Take(&user) ans := store.db.Where("room_id = ? AND user_id = ?", roomID, userID).Limit(1).Find(&user)
membership := event.MembershipLeave membership := event.MembershipLeave
if ans.Error != nil && ans.Error != gorm.ErrRecordNotFound { if ans.Error != nil && ans.Error != gorm.ErrRecordNotFound {
store.log.Warnfln("Failed to scan membership of %s in %s: %v", userID, roomID, ans.Error) store.log.Warnfln("Failed to scan membership of %s in %s: %v", userID, roomID, ans.Error)
@ -197,8 +198,8 @@ func (store *SQLStateStore) SetMembership(roomID id.RoomID, userID id.UserID, me
print("weird thing 2 502650285") print("weird thing 2 502650285")
print(user.Membership) print(user.Membership)
ans := store.db.Select("roomID", "userID", "membership").Clauses(clause.OnConflict{ ans := store.db.Debug().Clauses(clause.OnConflict{
Columns: []clause.Column{{Name: "roomID"}, {Name: "userID"}}, Columns: []clause.Column{{Name: "room_id"}, {Name: "user_id"}},
DoUpdates: clause.AssignmentColumns([]string{"membership"}), DoUpdates: clause.AssignmentColumns([]string{"membership"}),
}).Create(&user) }).Create(&user)
@ -217,7 +218,7 @@ func (store *SQLStateStore) SetMember(roomID id.RoomID, userID id.UserID, member
AvatarURL: string(member.AvatarURL), AvatarURL: string(member.AvatarURL),
} }
ans := store.db.Clauses(clause.OnConflict{ ans := store.db.Clauses(clause.OnConflict{
Columns: []clause.Column{{Name: "roomID"}, {Name: "userID"}}, Columns: []clause.Column{{Name: "room_id"}, {Name: "user_id"}},
DoUpdates: clause.AssignmentColumns([]string{"membership"}), DoUpdates: clause.AssignmentColumns([]string{"membership"}),
}).Create(&user) }).Create(&user)

View File

@ -17,15 +17,12 @@
package database package database
import ( import (
"database/sql"
"strings" "strings"
"time"
"github.com/Rhymen/go-whatsapp"
log "maunium.net/go/maulogger/v2" log "maunium.net/go/maulogger/v2"
"maunium.net/go/mautrix-whatsapp/types" "maunium.net/go/mautrix-whatsapp/types"
whatsappExt "maunium.net/go/mautrix-whatsapp/whatsapp-ext"
"maunium.net/go/mautrix/id" "maunium.net/go/mautrix/id"
) )
@ -42,72 +39,77 @@ func (uq *UserQuery) New() *User {
} }
func (uq *UserQuery) GetAll() (users []*User) { func (uq *UserQuery) GetAll() (users []*User) {
// rows, err := uq.db.Query(`SELECT mxid, jid, management_room, last_connection, client_id, client_token, server_token, enc_key, mac_key FROM "user"`) ans := uq.db.Find(&users)
// if err != nil || rows == nil { if ans.Error != nil || len(users) == 0 {
// return nil return nil
// } }
// defer rows.Close() for _, i := range users {
// for rows.Next() { i.db = uq.db
// users = append(users, uq.New().Scan(rows)) i.log = uq.log
// } }
return return
} }
func (uq *UserQuery) GetByMXID(userID id.UserID) *User { func (uq *UserQuery) GetByMXID(userID id.UserID) *User {
// row := uq.db.QueryRow(`SELECT mxid, jid, management_room, last_connection, client_id, client_token, server_token, enc_key, mac_key FROM "user" WHERE mxid=$1`, userID) var user User
// if row == nil { ans := uq.db.Where("mxid = ?", userID).Take(&user)
// return nil user.db = uq.db
// } user.log = uq.log
// return uq.New().Scan(row) if ans.Error != nil {
return nil return nil
} }
return &user
}
func (uq *UserQuery) GetByJID(userID types.GroupMeID) *User { func (uq *UserQuery) GetByJID(userID types.GroupMeID) *User {
// row := uq.db.QueryRow(`SELECT mxid, jid, management_room, last_connection, client_id, client_token, server_token, enc_key, mac_key FROM "user" WHERE jid=$1`, stripSuffix(userID)) var user User
// if row == nil { ans := uq.db.Where("jid = ?", userID).Limit(1).Find(&user)
// return nil if ans.Error != nil || ans.RowsAffected == 0 {
// }
// return uq.New().Scan(row)
return nil return nil
} }
user.db = uq.db
user.log = uq.log
return &user
}
type User struct { type User struct {
db *Database db *Database
log log.Logger log log.Logger
MXID id.UserID MXID id.UserID `gorm:"primaryKey"`
JID types.GroupMeID JID types.GroupMeID `gorm:"unique"`
Token types.AuthToken Token types.AuthToken
ManagementRoom id.RoomID ManagementRoom id.RoomID
LastConnection uint64 LastConnection uint64 `gorm:"notNull;default:0"`
} }
func (user *User) Scan(row Scannable) *User { //func (user *User) Scan(row Scannable) *User {
var jid, clientID, clientToken, serverToken sql.NullString // var jid, clientID, clientToken, serverToken sql.NullString
var encKey, macKey []byte // var encKey, macKey []byte
err := row.Scan(&user.MXID, &jid, &user.ManagementRoom, &user.LastConnection, &clientID, &clientToken, &serverToken, &encKey, &macKey) // err := row.Scan(&user.MXID, &jid, &user.ManagementRoom, &user.LastConnection, &clientID, &clientToken, &serverToken, &encKey, &macKey)
if err != nil { // if err != nil {
if err != sql.ErrNoRows { // if err != sql.ErrNoRows {
user.log.Errorln("Database scan failed:", err) // user.log.Errorln("Database scan failed:", err)
}
return nil
}
if len(jid.String) > 0 && len(clientID.String) > 0 {
user.JID = jid.String + whatsappExt.NewUserSuffix
// user.Session = &whatsapp.Session{
// ClientId: clientID.String,
// ClientToken: clientToken.String,
// ServerToken: serverToken.String,
// EncKey: encKey,
// MacKey: macKey,
// Wid: jid.String + whatsappExt.OldUserSuffix,
// } // }
}// else { // return nil
// user.Session = nil // }
// if len(jid.String) > 0 && len(clientID.String) > 0 {
// user.JID = jid.String + whatsappExt.NewUserSuffix
// // user.Session = &whatsapp.Session{
// // ClientId: clientID.String,
// // ClientToken: clientToken.String,
// // ServerToken: serverToken.String,
// // EncKey: encKey,
// // MacKey: macKey,
// // Wid: jid.String + whatsappExt.OldUserSuffix,
// // }
// } // else {
// // user.Session = nil
// // }
// return user
//} //}
return user
}
func stripSuffix(jid types.GroupMeID) string { func stripSuffix(jid types.GroupMeID) string {
if len(jid) == 0 { if len(jid) == 0 {
@ -130,42 +132,30 @@ func (user *User) jidPtr() *string {
return nil return nil
} }
func (user *User) sessionUnptr() (sess whatsapp.Session) { //func (user *User) sessionUnptr() (sess whatsapp.Session) {
// if user.Session != nil { // // if user.Session != nil {
// sess = *user.Session // // sess = *user.Session
// // }
// return
//} //}
return
}
func (user *User) Insert() { func (user *User) Insert() {
// sess := user.sessionUnptr() ans := user.db.Create(&user)
// _, err := user.db.Exec(`INSERT INTO "user" (mxid, jid, management_room, last_connection, client_id, client_token, server_token, enc_key, mac_key) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)`, if ans.Error != nil {
// user.MXID, user.jidPtr(), user.log.Warnfln("Failed to insert %s: %v", user.MXID, ans.Error)
// user.ManagementRoom, user.LastConnection, }
// sess.ClientId, sess.ClientToken, sess.ServerToken, sess.EncKey, sess.MacKey)
// if err != nil {
// user.log.Warnfln("Failed to insert %s: %v", user.MXID, err)
// }
} }
func (user *User) UpdateLastConnection() { func (user *User) UpdateLastConnection() {
// user.LastConnection = uint64(time.Now().Unix()) user.LastConnection = uint64(time.Now().Unix())
// _, err := user.db.Exec(`UPDATE "user" SET last_connection=$1 WHERE mxid=$2`, user.Update()
// user.LastConnection, user.MXID)
// if err != nil {
// user.log.Warnfln("Failed to update last connection ts: %v", err)
// }
} }
func (user *User) Update() { func (user *User) Update() {
// sess := user.sessionUnptr() ans := user.db.Save(&user)
// _, err := user.db.Exec(`UPDATE "user" SET jid=$1, management_room=$2, last_connection=$3, client_id=$4, client_token=$5, server_token=$6, enc_key=$7, mac_key=$8 WHERE mxid=$9`, if ans.Error != nil {
// user.jidPtr(), user.ManagementRoom, user.LastConnection, user.log.Warnfln("Failed to update last connection ts: %v", ans.Error)
// sess.ClientId, sess.ClientToken, sess.ServerToken, sess.EncKey, sess.MacKey, }
// user.MXID)
// if err != nil {
// user.log.Warnfln("Failed to update %s: %v", user.MXID, err)
// }
} }
type PortalKeyWithMeta struct { type PortalKeyWithMeta struct {
@ -173,82 +163,85 @@ type PortalKeyWithMeta struct {
InCommunity bool InCommunity bool
} }
type UserPortal struct {
UserJID types.GroupMeID `gorm:"primaryKey;"`
PortalJID types.GroupMeID `gorm:"primaryKey;"`
PortalReceiver types.GroupMeID `gorm:"primaryKey;"`
InCommunity bool `gorm:"notNull;default:false;"`
User User `gorm:"foreignKey:UserJID;references:jid;constraint:OnDelete:CASCADE;"`
Portal Portal `gorm:"foreignKey:PortalJID,PortalReceiver;references:JID,Receiver;constraint:OnDelete:CASCADE;"`
}
func (user *User) SetPortalKeys(newKeys []PortalKeyWithMeta) error { func (user *User) SetPortalKeys(newKeys []PortalKeyWithMeta) error {
// tx, err := user.db.Begin() tx := user.db.Begin()
// if err != nil { ans := tx.Where("user_jid = ?", *user.jidPtr()).Delete(&UserPortal{})
// return err print("make sure all are deletede")
// } if ans.Error != nil {
// _, err = tx.Exec("DELETE FROM user_portal WHERE user_jid=$1", user.jidPtr()) _ = tx.Rollback()
// if err != nil { return ans.Error
// _ = tx.Rollback() }
// return err
// } for _, key := range newKeys {
// valueStrings := make([]string, len(newKeys)) ans = tx.Create(&UserPortal{
// values := make([]interface{}, len(newKeys)*4) UserJID: *user.jidPtr(),
// for i, key := range newKeys { PortalJID: key.JID,
// pos := i * 4 PortalReceiver: key.Receiver,
// valueStrings[i] = fmt.Sprintf("($%d, $%d, $%d, $%d)", pos+1, pos+2, pos+3, pos+4) InCommunity: key.InCommunity,
// values[pos] = user.jidPtr() })
// values[pos+1] = key.JID if ans.Error != nil {
// values[pos+2] = key.Receiver _ = tx.Rollback()
// values[pos+3] = key.InCommunity return ans.Error
// } }
// query := fmt.Sprintf("INSERT INTO user_portal (user_jid, portal_jid, portal_receiver, in_community) VALUES %s", }
// strings.Join(valueStrings, ", "))
// _, err = tx.Exec(query, values...) return tx.Commit().Error
// if err != nil {
// _ = tx.Rollback()
// return err
// }
// return tx.Commit()
return nil
} }
func (user *User) IsInPortal(key PortalKey) bool { func (user *User) IsInPortal(key PortalKey) bool {
// row := user.db.QueryRow(`SELECT EXISTS(SELECT 1 FROM user_portal WHERE user_jid=$1 AND portal_jid=$2 AND portal_receiver=$3)`, user.jidPtr(), &key.JID, &key.Receiver) var count int64
// var exists bool user.db.Find(&UserPortal{
// _ = row.Scan(&exists) UserJID: *user.jidPtr(),
// return exists PortalJID: key.JID,
return false PortalReceiver: key.Receiver,
}).Count(&count) //TODO: efficient
return count > 0
} }
func (user *User) GetPortalKeys() []PortalKey { func (user *User) GetPortalKeys() []PortalKey {
// rows, err := user.db.Query(`SELECT portal_jid, portal_receiver FROM user_portal WHERE user_jid=$1`, user.jidPtr()) var up []UserPortal
// if err != nil { ans := user.db.Where("user_jid = ?", *user.jidPtr()).Find(&up)
// user.log.Warnln("Failed to get user portal keys:", err) if ans.Error != nil {
// return nil user.log.Warnln("Failed to get user portal keys:", ans.Error)
// }
// var keys []PortalKey
// for rows.Next() {
// var key PortalKey
// err = rows.Scan(&key.JID, &key.Receiver)
// if err != nil {
// user.log.Warnln("Failed to scan row:", err)
// continue
// }
// keys = append(keys, key)
// }
// return keys
return nil return nil
} }
var keys []PortalKey
for _, i := range up {
key := PortalKey{
JID: i.UserJID,
Receiver: i.PortalReceiver,
}
keys = append(keys, key)
}
return keys
}
func (user *User) GetInCommunityMap() map[PortalKey]bool { func (user *User) GetInCommunityMap() map[PortalKey]bool {
// rows, err := user.db.Query(`SELECT portal_jid, portal_receiver, in_community FROM user_portal WHERE user_jid=$1`, user.jidPtr()) var up []UserPortal
// if err != nil { ans := user.db.Where("user_jid = ?", *user.jidPtr()).Find(&up)
// user.log.Warnln("Failed to get user portal keys:", err) if ans.Error != nil {
// return nil user.log.Warnln("Failed to get user portal keys:", ans.Error)
// }
// keys := make(map[PortalKey]bool)
// for rows.Next() {
// var key PortalKey
// var inCommunity bool
// err = rows.Scan(&key.JID, &key.Receiver, &inCommunity)
// if err != nil {
// user.log.Warnln("Failed to scan row:", err)
// continue
// }
// keys[key] = inCommunity
// }
// return keys
return nil return nil
} }
keys := make(map[PortalKey]bool)
for _, i := range up {
key := PortalKey{
JID: i.PortalJID,
Receiver: i.PortalReceiver,
}
keys[key] = i.InCommunity
}
return keys
}

View File

@ -1,3 +0,0 @@
package groupmeExt
type Session struct{}

52
groupmeExt/client.go Normal file
View File

@ -0,0 +1,52 @@
package groupmeExt
import (
"context"
"fmt"
"github.com/karmanyaahm/groupme"
)
type Client struct {
*groupme.Client
}
// NewClient creates a new GroupMe API Client
func NewClient(authToken string) *Client {
n := Client{
Client: groupme.NewClient(authToken),
}
return &n
}
func (c Client) IndexAllGroups() ([]*groupme.Group, error) {
return c.IndexGroups(context.TODO(), &groupme.GroupsQuery{
Omit: "memberships",
PerPage: 100, //TODO: Configurable and add multipage support
})
}
func (c Client) LoadMessagesAfter(groupID, lastMessageID string, lastMessageFromMe bool, num int) ([]*groupme.Message, error) {
//TODO: limit max 100
i, e := c.IndexMessages(context.TODO(), groupme.ID(groupID), &groupme.IndexMessagesQuery{
AfterID: groupme.ID(lastMessageID),
Limit: num,
})
if e != nil {
return nil, e
}
return i.Messages, nil
}
func (c Client) LoadMessagesBefore(groupID, lastMessageID string, num int) ([]*groupme.Message, error) {
//TODO: limit max 100
i, e := c.IndexMessages(context.TODO(), groupme.ID(groupID), &groupme.IndexMessagesQuery{
BeforeID: groupme.ID(lastMessageID),
Limit: num,
})
fmt.Println(groupID, lastMessageID, num, i.Count, e)
if e != nil {
return nil, e
}
return i.Messages, nil
}

6
groupmeExt/user.go Normal file
View File

@ -0,0 +1,6 @@
package groupmeExt
const (
OldUserSuffix = "@c.groupme.com"
NewUserSuffix = "@groupme.com"
)

View File

@ -327,7 +327,7 @@ func (bridge *Bridge) LoadRelaybot() {
} }
bridge.Relaybot.ManagementRoom = bridge.Config.Bridge.Relaybot.ManagementRoom bridge.Relaybot.ManagementRoom = bridge.Config.Bridge.Relaybot.ManagementRoom
bridge.Relaybot.IsRelaybot = true bridge.Relaybot.IsRelaybot = true
bridge.Relaybot.Connect(false) bridge.Relaybot.Connect()
} }
func (bridge *Bridge) UpdateBotProfile() { func (bridge *Bridge) UpdateBotProfile() {
@ -361,7 +361,7 @@ func (bridge *Bridge) UpdateBotProfile() {
func (bridge *Bridge) StartUsers() { func (bridge *Bridge) StartUsers() {
bridge.Log.Debugln("Starting users") bridge.Log.Debugln("Starting users")
for _, user := range bridge.GetAllUsers() { for _, user := range bridge.GetAllUsers() {
go user.Connect(false) go user.Connect()
} }
bridge.Log.Debugln("Starting custom puppets") bridge.Log.Debugln("Starting custom puppets")
for _, loopuppet := range bridge.GetAllPuppetsWithCustomMXID() { for _, loopuppet := range bridge.GetAllPuppetsWithCustomMXID() {

View File

@ -336,6 +336,7 @@ func (mx *MatrixHandler) shouldIgnoreEvent(evt *event.Event) bool {
const sessionWaitTimeout = 5 * time.Second const sessionWaitTimeout = 5 * time.Second
func (mx *MatrixHandler) HandleEncrypted(evt *event.Event) { func (mx *MatrixHandler) HandleEncrypted(evt *event.Event) {
println("IDK iF encryption works yet")
defer mx.bridge.Metrics.TrackEvent(evt.Type)() defer mx.bridge.Metrics.TrackEvent(evt.Type)()
if mx.shouldIgnoreEvent(evt) || mx.bridge.Crypto == nil { if mx.shouldIgnoreEvent(evt) || mx.bridge.Crypto == nil {
return return

980
portal.go

File diff suppressed because it is too large Load Diff

View File

@ -45,7 +45,7 @@ func (bridge *Bridge) ParsePuppetMXID(mxid id.UserID) (types.GroupMeID, bool) {
return "", false return "", false
} }
jid := types.GroupMeID(match[1] + whatsappExt.NewUserSuffix) jid := types.GroupMeID(match[1])
return jid, true return jid, true
} }
@ -159,6 +159,7 @@ type Puppet struct {
} }
func (puppet *Puppet) PhoneNumber() string { func (puppet *Puppet) PhoneNumber() string {
println("phone num")
return strings.Replace(puppet.JID, whatsappExt.NewUserSuffix, "", 1) return strings.Replace(puppet.JID, whatsappExt.NewUserSuffix, "", 1)
} }

View File

@ -24,3 +24,5 @@ type WhatsAppMessageID = string
//AuthToken is the authentication token //AuthToken is the authentication token
type AuthToken = string type AuthToken = string
type TmpID = GroupMeID

377
user.go
View File

@ -22,11 +22,11 @@ import (
"errors" "errors"
"fmt" "fmt"
"net/http" "net/http"
"sort"
"strings" "strings"
"sync" "sync"
"time" "time"
"github.com/skip2/go-qrcode"
log "maunium.net/go/maulogger/v2" log "maunium.net/go/maulogger/v2"
"github.com/Rhymen/go-whatsapp" "github.com/Rhymen/go-whatsapp"
@ -40,6 +40,7 @@ import (
"github.com/karmanyaahm/groupme" "github.com/karmanyaahm/groupme"
"maunium.net/go/mautrix-whatsapp/database" "maunium.net/go/mautrix-whatsapp/database"
"maunium.net/go/mautrix-whatsapp/groupmeExt"
"maunium.net/go/mautrix-whatsapp/types" "maunium.net/go/mautrix-whatsapp/types"
whatsappExt "maunium.net/go/mautrix-whatsapp/whatsapp-ext" whatsappExt "maunium.net/go/mautrix-whatsapp/whatsapp-ext"
) )
@ -57,7 +58,7 @@ type User struct {
IsRelaybot bool IsRelaybot bool
Client *groupme.Client Client *groupmeExt.Client
ConnectionErrors int ConnectionErrors int
CommunityID string CommunityID string
@ -230,10 +231,10 @@ func (user *User) SetSession(session *whatsapp.Session) {
// user.Update() // user.Update()
} }
func (user *User) Connect(evenIfNoLogin bool) bool { func (user *User) Connect() bool {
if user.Conn != nil { if user.Conn != nil {
return true return true
} else if !evenIfNoLogin && len(user.Token) < 0 { } else if len(user.Token) == 0 {
return false return false
} }
user.log.Debugln("Connecting to WhatsApp") user.log.Debugln("Connecting to WhatsApp")
@ -260,8 +261,6 @@ func (user *User) Connect(evenIfNoLogin bool) bool {
func (user *User) RestoreSession() bool { func (user *User) RestoreSession() bool {
if len(user.Token) > 0 { if len(user.Token) > 0 {
//sess, err :=
user.Conn.SubscribeToUser(context.TODO(), groupme.ID(user.GetJID()), user.Token)
// if err == whatsapp.ErrAlreadyLoggedIn { // if err == whatsapp.ErrAlreadyLoggedIn {
// return true // return true
// } else if err != nil { // } else if err != nil {
@ -275,7 +274,6 @@ func (user *User) RestoreSession() bool {
// } // }
// user.log.Debugln("Disconnecting due to failed session restore...") // user.log.Debugln("Disconnecting due to failed session restore...")
// _, err := // _, err :=
user.Conn.Stop(context.TODO())
// if err != nil { // if err != nil {
// user.log.Errorln("Failed to disconnect after failed session restore:", err) // user.log.Errorln("Failed to disconnect after failed session restore:", err)
// } // }
@ -283,29 +281,31 @@ func (user *User) RestoreSession() bool {
// } // }
user.Conn.SubscribeToUser(context.TODO(), groupme.ID(user.JID), user.Token) user.Conn.SubscribeToUser(context.TODO(), groupme.ID(user.JID), user.Token)
//TODO: typing notifics
user.ConnectionErrors = 0 user.ConnectionErrors = 0
//user.SetSession(&sess) //user.SetSession(&sess)
user.log.Debugln("Session restored successfully") user.log.Debugln("Session restored successfully")
user.PostLogin() user.PostLogin()
}
return true return true
} else {
user.log.Debugln("tried login but no token")
return false
}
} }
func (user *User) HasSession() bool { func (user *User) HasSession() bool {
return user.Conn != nil && len(user.Token) > 0 return len(user.Token) > 0
} }
func (user *User) IsConnected() bool { func (user *User) IsConnected() bool {
// return user.Conn != nil && user.Conn.IsConnected() && user.Conn.IsLoggedIn() println("better connectoin check TODO")
return true return user.Conn != nil
} }
func (user *User) IsLoggedIn() bool { func (user *User) IsLoggedIn() bool {
return true return true
} }
func (user *User) IsLoginInProgress() bool { func (user *User) IsLoginInProgress() bool {
// return user.Conn != nil && user.Conn.IsLoginInProgress() // return user.Conn != nil && user.Conn.IsLoginInProgress()
return false return false
@ -318,59 +318,6 @@ func (user *User) GetJID() types.GroupMeID {
} }
return user.JID return user.JID
} }
func (user *User) loginQrChannel(ce *CommandEvent, qrChan <-chan string, eventIDChan chan<- id.EventID) {
var qrEventID id.EventID
for code := range qrChan {
if code == "stop" {
return
}
qrCode, err := qrcode.Encode(code, qrcode.Low, 256)
if err != nil {
user.log.Errorln("Failed to encode QR code:", err)
ce.Reply("Failed to encode QR code: %v", err)
return
}
bot := user.bridge.AS.BotClient()
resp, err := bot.UploadBytes(qrCode, "image/png")
if err != nil {
user.log.Errorln("Failed to upload QR code:", err)
ce.Reply("Failed to upload QR code: %v", err)
return
}
if qrEventID == "" {
sendResp, err := bot.SendImage(ce.RoomID, code, resp.ContentURI)
if err != nil {
user.log.Errorln("Failed to send QR code to user:", err)
return
}
qrEventID = sendResp.EventID
eventIDChan <- qrEventID
} else {
_, err = bot.SendMessageEvent(ce.RoomID, event.EventMessage, &event.MessageEventContent{
MsgType: event.MsgImage,
Body: code,
URL: resp.ContentURI.CUString(),
NewContent: &event.MessageEventContent{
MsgType: event.MsgImage,
Body: code,
URL: resp.ContentURI.CUString(),
},
RelatesTo: &event.RelatesTo{
Type: event.RelReplace,
EventID: qrEventID,
},
})
if err != nil {
user.log.Errorln("Failed to send edited QR code to user:", err)
}
}
}
}
func (user *User) Login(ce *CommandEvent) { func (user *User) Login(ce *CommandEvent) {
// qrChan := make(chan string, 3) // qrChan := make(chan string, 3)
// eventIDChan := make(chan id.EventID, 1) // eventIDChan := make(chan id.EventID, 1)
@ -416,13 +363,13 @@ func (user *User) Login(ce *CommandEvent) {
user.addToJIDMap() user.addToJIDMap()
//user.SetSession(&session) //user.SetSession(&session)
ce.Reply("Successfully logged in, synchronizing chats...") ce.Reply("Successfully logged in, synchronizing chats...")
// user.PostLogin() user.PostLogin()
} }
type Chat struct { type Chat struct {
Portal *Portal Portal *Portal
LastMessageTime uint64 LastMessageTime uint64
Contact whatsapp.Contact Group groupme.Group
} }
type ChatList []Chat type ChatList []Chat
@ -521,10 +468,19 @@ func (user *User) postConnPing() bool {
func (user *User) intPostLogin() { func (user *User) intPostLogin() {
defer user.syncWait.Done() defer user.syncWait.Done()
user.lastReconnection = time.Now().Unix() user.lastReconnection = time.Now().Unix()
user.Client = groupmeExt.NewClient(user.Token)
myuser, err := user.Client.MyUser(context.TODO())
if err != nil {
log.Fatal(err) //TODO
}
user.JID = myuser.ID.String()
user.Update()
user.createCommunity() user.createCommunity()
user.tryAutomaticDoublePuppeting() user.tryAutomaticDoublePuppeting()
user.log.Debugln("Waiting for chat list receive confirmation") user.log.Debugln("Waiting for chat list receive confirmation")
user.HandleChatList()
select { select {
case <-user.chatListReceived: case <-user.chatListReceived:
user.log.Debugln("Chat list receive confirmation received in PostLogin") user.log.Debugln("Chat list receive confirmation received in PostLogin")
@ -565,84 +521,79 @@ func (user *User) HandleStreamEvent(evt whatsappExt.StreamEvent) {
} }
} }
func (user *User) HandleChatList(chats []whatsapp.Chat) { func (user *User) HandleChatList() {
// user.log.Infoln("Chat list received") chatMap := make(map[string]groupme.Group)
// chatMap := make(map[string]whatsapp.Chat) chats, err := user.Client.IndexAllGroups()
// for _, chat := range user.Conn.Store.Chats { if err != nil {
// chatMap[chat.Jid] = chat log.Fatal(err) //TODO: handle
// } }
// for _, chat := range chats { for _, chat := range chats {
// chatMap[chat.Jid] = chat chatMap[chat.ID.String()] = *chat
// } }
// select { user.chatListReceived <- struct{}{}
// case user.chatListReceived <- struct{}{}: user.log.Infoln("Chat list received")
// default: go user.syncPortals(chatMap, false)
// }
// go user.syncPortals(chatMap, false)
} }
func (user *User) syncPortals(chatMap map[string]whatsapp.Chat, createAll bool) { func (user *User) syncPortals(chatMap map[string]groupme.Group, createAll bool) {
// if chatMap == nil { if chatMap == nil {
// chatMap = user.Conn.Store.Chats // chatMap = user.Conn.Store.Chats
// } log.Fatal("chatmap nil major oops")
// user.log.Infoln("Reading chat list") }
// chats := make(ChatList, 0, len(chatMap)) user.log.Infoln("Reading chat list")
// existingKeys := user.GetInCommunityMap()
// portalKeys := make([]database.PortalKeyWithMeta, 0, len(chatMap))
// for _, chat := range chatMap {
// ts, err := strconv.ParseUint(chat.LastMessageTime, 10, 64)
// if err != nil {
// user.log.Warnfln("Non-integer last message time in %s: %s", chat.Jid, chat.LastMessageTime)
// continue
// }
// portal := user.GetPortalByJID(chat.Jid)
// chats = append(chats, Chat{ chats := make(ChatList, 0, len(chatMap))
// Portal: portal, existingKeys := user.GetInCommunityMap()
// Contact: user.Conn.Store.Contacts[chat.Jid], portalKeys := make([]database.PortalKeyWithMeta, 0, len(chatMap))
// LastMessageTime: ts, for _, chat := range chatMap {
// }) portal := user.GetPortalByJID(chat.ID.String())
// var inCommunity, ok bool
// if inCommunity, ok = existingKeys[portal.Key]; !ok || !inCommunity { chats = append(chats, Chat{
// inCommunity = user.addPortalToCommunity(portal) Portal: portal,
// if portal.IsPrivateChat() { LastMessageTime: uint64(time.Now().Unix()),
// puppet := user.bridge.GetPuppetByJID(portal.Key.JID) Group: chat,
// user.addPuppetToCommunity(puppet) })
// } var inCommunity, ok bool
// } if inCommunity, ok = existingKeys[portal.Key]; !ok || !inCommunity {
// portalKeys = append(portalKeys, database.PortalKeyWithMeta{PortalKey: portal.Key, InCommunity: inCommunity}) inCommunity = user.addPortalToCommunity(portal)
// } if portal.IsPrivateChat() {
// user.log.Infoln("Read chat list, updating user-portal mapping") puppet := user.bridge.GetPuppetByJID(portal.Key.JID)
// err := user.SetPortalKeys(portalKeys) user.addPuppetToCommunity(puppet)
// if err != nil { }
// user.log.Warnln("Failed to update user-portal mapping:", err) }
// } portalKeys = append(portalKeys, database.PortalKeyWithMeta{PortalKey: portal.Key, InCommunity: inCommunity})
// sort.Sort(chats) }
// limit := user.bridge.Config.Bridge.InitialChatSync user.log.Infoln("Read chat list, updating user-portal mapping")
// if limit < 0 { err := user.SetPortalKeys(portalKeys)
// limit = len(chats) if err != nil {
// } user.log.Warnln("Failed to update user-portal mapping:", err)
// now := uint64(time.Now().Unix()) }
// user.log.Infoln("Syncing portals") sort.Sort(chats)
// for i, chat := range chats { limit := user.bridge.Config.Bridge.InitialChatSync
// if chat.LastMessageTime+user.bridge.Config.Bridge.SyncChatMaxAge < now { if limit < 0 {
// break limit = len(chats)
// } }
// create := (chat.LastMessageTime >= user.LastConnection && user.LastConnection > 0) || i < limit now := uint64(time.Now().Unix())
// if len(chat.Portal.MXID) > 0 || create || createAll { user.log.Infoln("Syncing portals")
// chat.Portal.Sync(user, chat.Contact) for i, chat := range chats {
// err := chat.Portal.BackfillHistory(user, chat.LastMessageTime) if chat.LastMessageTime+user.bridge.Config.Bridge.SyncChatMaxAge < now {
// if err != nil { break
// chat.Portal.log.Errorln("Error backfilling history:", err) }
// } create := (chat.LastMessageTime >= user.LastConnection && user.LastConnection > 0) || i < limit
// } if len(chat.Portal.MXID) > 0 || create || createAll {
// } chat.Portal.Sync(user, chat.Group)
// user.UpdateDirectChats(nil) err := chat.Portal.BackfillHistory(user, chat.LastMessageTime)
// user.log.Infoln("Finished syncing portals") if err != nil {
// select { chat.Portal.log.Errorln("Error backfilling history:", err)
// case user.syncPortalsDone <- struct{}{}: }
// default: }
// } }
user.UpdateDirectChats(nil)
user.log.Infoln("Finished syncing portals")
select {
case user.syncPortalsDone <- struct{}{}:
default:
}
} }
func (user *User) getDirectChats() map[id.UserID][]id.RoomID { func (user *User) getDirectChats() map[id.UserID][]id.RoomID {
@ -881,41 +832,41 @@ func (user *User) HandleBatteryMessage(battery whatsapp.BatteryMessage) {
} }
} }
func (user *User) HandleTextMessage(message whatsapp.TextMessage) { func (user *User) HandleTextMessage(message groupme.Message) {
user.messageInput <- PortalMessage{message.Info.RemoteJid, user, message, message.Info.Timestamp} user.messageInput <- PortalMessage{message.GroupID.String(), user, &message, uint64(message.CreatedAt.ToTime().Unix())}
} }
func (user *User) HandleImageMessage(message whatsapp.ImageMessage) { //func (user *User) HandleImageMessage(message whatsapp.ImageMessage) {
user.messageInput <- PortalMessage{message.Info.RemoteJid, user, message, message.Info.Timestamp} // user.messageInput <- PortalMessage{message.Info.RemoteJid, user, message, message.Info.Timestamp}
} //}
//
func (user *User) HandleStickerMessage(message whatsapp.StickerMessage) { //func (user *User) HandleStickerMessage(message whatsapp.StickerMessage) {
user.messageInput <- PortalMessage{message.Info.RemoteJid, user, message, message.Info.Timestamp} // user.messageInput <- PortalMessage{message.Info.RemoteJid, user, message, message.Info.Timestamp}
} //}
//
func (user *User) HandleVideoMessage(message whatsapp.VideoMessage) { //func (user *User) HandleVideoMessage(message whatsapp.VideoMessage) {
user.messageInput <- PortalMessage{message.Info.RemoteJid, user, message, message.Info.Timestamp} // user.messageInput <- PortalMessage{message.Info.RemoteJid, user, message, message.Info.Timestamp}
} //}
//
func (user *User) HandleAudioMessage(message whatsapp.AudioMessage) { //func (user *User) HandleAudioMessage(message whatsapp.AudioMessage) {
user.messageInput <- PortalMessage{message.Info.RemoteJid, user, message, message.Info.Timestamp} // user.messageInput <- PortalMessage{message.Info.RemoteJid, user, message, message.Info.Timestamp}
} //}
//
func (user *User) HandleDocumentMessage(message whatsapp.DocumentMessage) { //func (user *User) HandleDocumentMessage(message whatsapp.DocumentMessage) {
user.messageInput <- PortalMessage{message.Info.RemoteJid, user, message, message.Info.Timestamp} // user.messageInput <- PortalMessage{message.Info.RemoteJid, user, message, message.Info.Timestamp}
} //}
//
func (user *User) HandleContactMessage(message whatsapp.ContactMessage) { //func (user *User) HandleContactMessage(message whatsapp.ContactMessage) {
user.messageInput <- PortalMessage{message.Info.RemoteJid, user, message, message.Info.Timestamp} // user.messageInput <- PortalMessage{message.Info.RemoteJid, user, message, message.Info.Timestamp}
} //}
//
func (user *User) HandleLocationMessage(message whatsapp.LocationMessage) { //func (user *User) HandleLocationMessage(message whatsapp.LocationMessage) {
user.messageInput <- PortalMessage{message.Info.RemoteJid, user, message, message.Info.Timestamp} // user.messageInput <- PortalMessage{message.Info.RemoteJid, user, message, message.Info.Timestamp}
} //}
//
func (user *User) HandleMessageRevoke(message whatsappExt.MessageRevocation) { //func (user *User) HandleMessageRevoke(message whatsappExt.MessageRevocation) {
user.messageInput <- PortalMessage{message.RemoteJid, user, message, 0} // user.messageInput <- PortalMessage{message.RemoteJid, user, message, 0}
} //}
type FakeMessage struct { type FakeMessage struct {
Text string Text string
@ -923,40 +874,40 @@ type FakeMessage struct {
Alert bool Alert bool
} }
func (user *User) HandleCallInfo(info whatsappExt.CallInfo) { //func (user *User) HandleCallInfo(info whatsappExt.CallInfo) {
if info.Data != nil { // if info.Data != nil {
return // return
} // }
data := FakeMessage{ // data := FakeMessage{
ID: info.ID, // ID: info.ID,
} // }
switch info.Type { // switch info.Type {
case whatsappExt.CallOffer: // case whatsappExt.CallOffer:
if !user.bridge.Config.Bridge.CallNotices.Start { // if !user.bridge.Config.Bridge.CallNotices.Start {
return // return
} // }
data.Text = "Incoming call" // data.Text = "Incoming call"
data.Alert = true // data.Alert = true
case whatsappExt.CallOfferVideo: // case whatsappExt.CallOfferVideo:
if !user.bridge.Config.Bridge.CallNotices.Start { // if !user.bridge.Config.Bridge.CallNotices.Start {
return // return
} // }
data.Text = "Incoming video call" // data.Text = "Incoming video call"
data.Alert = true // data.Alert = true
case whatsappExt.CallTerminate: // case whatsappExt.CallTerminate:
if !user.bridge.Config.Bridge.CallNotices.End { // if !user.bridge.Config.Bridge.CallNotices.End {
return // return
} // }
data.Text = "Call ended" // data.Text = "Call ended"
data.ID += "E" // data.ID += "E"
default: // default:
return // return
} // }
portal := user.GetPortalByJID(info.From) // portal := user.GetPortalByJID(info.From)
if portal != nil { // if portal != nil {
portal.messages <- PortalMessage{info.From, user, data, 0} // portal.messages <- PortalMessage{info.From, user, data, 0}
} // }
} //}
func (user *User) HandlePresence(info whatsappExt.Presence) { func (user *User) HandlePresence(info whatsappExt.Presence) {
puppet := user.bridge.GetPuppetByJID(info.SenderJID) puppet := user.bridge.GetPuppetByJID(info.SenderJID)
@ -1119,10 +1070,10 @@ func (user *User) HandleChatUpdate(cmd whatsappExt.ChatUpdate) {
go portal.HandleWhatsAppKick(cmd.Data.SenderJID, cmd.Data.UserChange.JIDs) go portal.HandleWhatsAppKick(cmd.Data.SenderJID, cmd.Data.UserChange.JIDs)
case whatsappExt.ChatActionAdd: case whatsappExt.ChatActionAdd:
go portal.HandleWhatsAppInvite(cmd.Data.SenderJID, cmd.Data.UserChange.JIDs) go portal.HandleWhatsAppInvite(cmd.Data.SenderJID, cmd.Data.UserChange.JIDs)
case whatsappExt.ChatActionIntroduce: //case whatsappExt.ChatActionIntroduce:
if cmd.Data.SenderJID != "unknown" { // if cmd.Data.SenderJID != "unknown" {
go portal.Sync(user, whatsapp.Contact{Jid: portal.Key.JID}) // go portal.Sync(user, whatsapp.Contact{Jid: portal.Key.JID})
} // }
} }
} }