kinda
This commit is contained in:
parent
7cb9983da8
commit
f1c093896e
@ -22,8 +22,7 @@ import (
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
"github.com/Rhymen/go-whatsapp"
|
||||
|
||||
"github.com/karmanyaahm/groupme"
|
||||
"maunium.net/go/mautrix/event"
|
||||
"maunium.net/go/mautrix/id"
|
||||
|
||||
@ -158,19 +157,19 @@ type UsernameTemplateArgs struct {
|
||||
UserID id.UserID
|
||||
}
|
||||
|
||||
func (bc BridgeConfig) FormatDisplayname(contact whatsapp.Contact) (string, int8) {
|
||||
func (bc BridgeConfig) FormatDisplayname(contact groupme.User) (string, int8) {
|
||||
var buf bytes.Buffer
|
||||
if index := strings.IndexRune(contact.Jid, '@'); index > 0 {
|
||||
contact.Jid = "+" + contact.Jid[:index]
|
||||
if index := strings.IndexRune(contact.ID.String(), '@'); index > 0 {
|
||||
contact.ID = groupme.ID("+" + contact.ID.String()[:index])
|
||||
}
|
||||
bc.displaynameTemplate.Execute(&buf, contact)
|
||||
var quality int8
|
||||
switch {
|
||||
case len(contact.Notify) > 0:
|
||||
case len(contact.Name) > 0:
|
||||
quality = 3
|
||||
case len(contact.Name) > 0 || len(contact.Short) > 0:
|
||||
case len(contact.Name) > 0 || len(contact.Name) > 0:
|
||||
quality = 2
|
||||
case len(contact.Jid) > 0:
|
||||
case len(contact.ID) > 0:
|
||||
quality = 1
|
||||
default:
|
||||
quality = 0
|
||||
|
@ -52,8 +52,9 @@ func New(dbType string, uri string, baseLog log.Logger) (*Database, error) {
|
||||
} else {
|
||||
conn = postgres.Open(uri)
|
||||
}
|
||||
print("no")
|
||||
|
||||
gdb, err := gorm.Open(conn, &gorm.Config{
|
||||
// Logger: logger.Default.LogMode(logger.Info),
|
||||
// Logger: baseLog,
|
||||
NamingStrategy: schema.NamingStrategy{
|
||||
NameReplacer: strings.NewReplacer("JID", "Jid", "MXID", "Mxid"),
|
||||
|
@ -17,9 +17,9 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"github.com/karmanyaahm/groupme"
|
||||
log "maunium.net/go/maulogger/v2"
|
||||
|
||||
"maunium.net/go/mautrix-whatsapp/groupmeExt"
|
||||
"maunium.net/go/mautrix-whatsapp/types"
|
||||
"maunium.net/go/mautrix/id"
|
||||
)
|
||||
@ -76,12 +76,12 @@ type Message struct {
|
||||
db *Database
|
||||
log log.Logger
|
||||
|
||||
Chat PortalKey `gorm:"primaryKey;embedded;embeddedPrefix:chat_"`
|
||||
JID types.GroupMeID `gorm:"primaryKey"`
|
||||
MXID id.EventID `gorm:"unique;notNull"`
|
||||
Sender types.GroupMeID `gorm:"notNull"`
|
||||
Timestamp uint64 `gorm:"notNull;default:0"`
|
||||
Content *groupme.Message `gorm:"type:TEXT;notNull"`
|
||||
Chat PortalKey `gorm:"primaryKey;embedded;embeddedPrefix:chat_"`
|
||||
JID types.GroupMeID `gorm:"primaryKey"`
|
||||
MXID id.EventID `gorm:"unique;notNull"`
|
||||
Sender types.GroupMeID `gorm:"notNull"`
|
||||
Timestamp uint64 `gorm:"notNull;default:0"`
|
||||
Content *groupmeExt.Message `gorm:"type:TEXT;notNull"`
|
||||
|
||||
// Portal Portal `gorm:"foreignKey:JID;"` //`gorm:"foreignKey:Chat.Receiver,Chat.JID;references:jid,receiver;constraint:onDelete:CASCADE;"`TODO
|
||||
}
|
||||
@ -124,13 +124,13 @@ type Message struct {
|
||||
func (msg *Message) Insert() {
|
||||
ans := msg.db.Create(&msg)
|
||||
if ans.Error != nil {
|
||||
// msg.log.Warnfln("Failed to insert %s@%s: %v", msg.Chat, msg.JID, ans.Error)
|
||||
msg.log.Warnfln("Failed to insert %s@%s: %v", msg.Chat, msg.JID, ans.Error)
|
||||
}
|
||||
}
|
||||
|
||||
func (msg *Message) Delete() {
|
||||
ans := msg.db.Delete(&msg)
|
||||
if ans.Error != nil {
|
||||
// msg.log.Warnfln("Failed to delete %s@%s: %v", msg.Chat, msg.JID, ans.Error)
|
||||
msg.log.Warnfln("Failed to delete %s@%s: %v", msg.Chat, msg.JID, ans.Error)
|
||||
}
|
||||
}
|
||||
|
@ -44,6 +44,10 @@ func (pq *PuppetQuery) GetAll() (puppets []*Puppet) {
|
||||
if ans.Error != nil || len(puppets) == 0 {
|
||||
return nil
|
||||
}
|
||||
for _, puppet := range puppets {
|
||||
puppet.db = pq.db
|
||||
puppet.log = pq.log
|
||||
}
|
||||
// defer rows.Close()
|
||||
// for rows.Next() {
|
||||
// puppets = append(puppets, pq.New().Scan(rows))
|
||||
@ -57,6 +61,8 @@ func (pq *PuppetQuery) Get(jid types.GroupMeID) *Puppet {
|
||||
if ans.Error != nil || ans.RowsAffected == 0 {
|
||||
return nil
|
||||
}
|
||||
puppet.db = pq.db
|
||||
puppet.log = pq.log
|
||||
return &puppet
|
||||
}
|
||||
|
||||
@ -66,6 +72,8 @@ func (pq *PuppetQuery) GetByCustomMXID(mxid id.UserID) *Puppet {
|
||||
if ans.Error != nil || ans.RowsAffected == 0 {
|
||||
return nil
|
||||
}
|
||||
puppet.db = pq.db
|
||||
puppet.log = pq.log
|
||||
return &puppet
|
||||
}
|
||||
|
||||
@ -75,6 +83,10 @@ func (pq *PuppetQuery) GetAllWithCustomMXID() (puppets []*Puppet) {
|
||||
if ans.Error != nil || len(puppets) != 0 {
|
||||
return nil
|
||||
}
|
||||
for _, puppet := range puppets {
|
||||
puppet.db = pq.db
|
||||
puppet.log = pq.log
|
||||
}
|
||||
// defer rows.Close()
|
||||
// for rows.Next() {
|
||||
// puppets = append(puppets, pq.New().Scan(rows))
|
||||
|
@ -153,6 +153,8 @@ func (store *SQLStateStore) FindSharedRooms(userID id.UserID) (rooms []id.RoomID
|
||||
rows, err := store.db.Table("mx_user_profile").Select("room_id").
|
||||
Joins("LEFT JOIN portal ON portal.mxid=mx_user_profile.room_id").
|
||||
Where("user_id = ? AND portal.encrypted=true", userID).Rows()
|
||||
defer rows.Close()
|
||||
|
||||
if err != nil {
|
||||
store.log.Warnfln("Failed to query shared rooms with %s: %v", userID, err)
|
||||
return
|
||||
@ -198,7 +200,7 @@ func (store *SQLStateStore) SetMembership(roomID id.RoomID, userID id.UserID, me
|
||||
print("weird thing 2 502650285")
|
||||
print(user.Membership)
|
||||
|
||||
ans := store.db.Debug().Clauses(clause.OnConflict{
|
||||
ans := store.db.Clauses(clause.OnConflict{
|
||||
Columns: []clause.Column{{Name: "room_id"}, {Name: "user_id"}},
|
||||
DoUpdates: clause.AssignmentColumns([]string{"membership"}),
|
||||
}).Create(&user)
|
||||
|
@ -154,8 +154,9 @@ func (user *User) UpdateLastConnection() {
|
||||
func (user *User) Update() {
|
||||
ans := user.db.Save(&user)
|
||||
if ans.Error != nil {
|
||||
user.log.Warnfln("Failed to update last connection ts: %v", ans.Error)
|
||||
user.log.Warnfln("Failed to update user: %v", ans.Error)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
type PortalKeyWithMeta struct {
|
||||
@ -197,6 +198,7 @@ func (user *User) SetPortalKeys(newKeys []PortalKeyWithMeta) error {
|
||||
}
|
||||
}
|
||||
|
||||
println("portalkey transaction complete")
|
||||
return tx.Commit().Error
|
||||
}
|
||||
|
||||
|
48
portal.go
48
portal.go
@ -288,29 +288,30 @@ func init() {
|
||||
|
||||
func (portal *Portal) markHandled(source *User, message *groupme.Message, mxid id.EventID) {
|
||||
print("handle message")
|
||||
// msg := portal.bridge.DB.Message.New()
|
||||
// msg.Chat = portal.Key
|
||||
// msg.JID = message.GetKey().GetId()
|
||||
// msg.MXID = mxid
|
||||
// msg.Timestamp = message.GetMessageTimestamp()
|
||||
// if message.GetKey().GetFromMe() {
|
||||
// msg.Sender = source.JID
|
||||
// } else if portal.IsPrivateChat() {
|
||||
// msg.Sender = portal.Key.JID
|
||||
// } else {
|
||||
// msg.Sender = message.GetKey().GetParticipant()
|
||||
// if len(msg.Sender) == 0 {
|
||||
// msg.Sender = message.GetParticipant()
|
||||
// }
|
||||
// }
|
||||
// msg.Content = message.Message
|
||||
// msg.Insert()
|
||||
msg := portal.bridge.DB.Message.New()
|
||||
msg.Chat = portal.Key
|
||||
msg.JID = message.ID.String()
|
||||
msg.MXID = mxid
|
||||
msg.Timestamp = uint64(message.CreatedAt.ToTime().Unix())
|
||||
if message.UserID.String() == source.JID {
|
||||
msg.Sender = source.JID
|
||||
} else if portal.IsPrivateChat() {
|
||||
msg.Sender = portal.Key.JID
|
||||
} else {
|
||||
msg.Sender = message.ID.String()
|
||||
if len(msg.Sender) == 0 {
|
||||
println("AAAAAAAAAAAAAAAAAAAAAAAAAAIDK")
|
||||
msg.Sender = message.SenderID.String()
|
||||
}
|
||||
}
|
||||
msg.Content = &groupmeExt.Message{Message: *message}
|
||||
msg.Insert()
|
||||
|
||||
// portal.recentlyHandledLock.Lock()
|
||||
// index := portal.recentlyHandledIndex
|
||||
// portal.recentlyHandledIndex = (portal.recentlyHandledIndex + 1) % recentlyHandledLength
|
||||
// portal.recentlyHandledLock.Unlock()
|
||||
// portal.recentlyHandled[index] = msg.JID
|
||||
portal.recentlyHandledLock.Lock()
|
||||
index := portal.recentlyHandledIndex
|
||||
portal.recentlyHandledIndex = (portal.recentlyHandledIndex + 1) % recentlyHandledLength
|
||||
portal.recentlyHandledLock.Unlock()
|
||||
portal.recentlyHandled[index] = groupme.ID(msg.JID)
|
||||
}
|
||||
|
||||
func (portal *Portal) getMessageIntent(user *User, info *groupme.Message) *appservice.IntentAPI {
|
||||
@ -703,10 +704,13 @@ func (portal *Portal) BackfillHistory(user *User, lastMessageTime uint64) error
|
||||
endBackfill := portal.beginBackfill()
|
||||
defer endBackfill()
|
||||
|
||||
println("hi")
|
||||
lastMessage := portal.bridge.DB.Message.GetLastInChat(portal.Key)
|
||||
fmt.Println(lastMessage)
|
||||
if lastMessage == nil {
|
||||
return nil
|
||||
}
|
||||
println(lastMessage.Timestamp, lastMessageTime)
|
||||
if lastMessage.Timestamp >= lastMessageTime {
|
||||
portal.log.Debugln("Not backfilling: no new messages")
|
||||
return nil
|
||||
|
33
puppet.go
33
puppet.go
@ -21,7 +21,7 @@ import (
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/Rhymen/go-whatsapp"
|
||||
"github.com/karmanyaahm/groupme"
|
||||
log "maunium.net/go/maulogger/v2"
|
||||
|
||||
"maunium.net/go/mautrix/appservice"
|
||||
@ -232,7 +232,7 @@ func (puppet *Puppet) UpdateAvatar(source *User, avatar *whatsappExt.ProfilePicI
|
||||
return true
|
||||
}
|
||||
|
||||
func (puppet *Puppet) UpdateName(source *User, contact whatsapp.Contact) bool {
|
||||
func (puppet *Puppet) UpdateName(source *User, contact groupme.User) bool {
|
||||
newName, quality := puppet.bridge.Config.Bridge.FormatDisplayname(contact)
|
||||
if puppet.Displayname != newName && quality >= puppet.NameQuality {
|
||||
err := puppet.DefaultIntent().SetDisplayName(newName)
|
||||
@ -284,20 +284,21 @@ func (puppet *Puppet) updatePortalName() {
|
||||
})
|
||||
}
|
||||
|
||||
func (puppet *Puppet) Sync(source *User, contact whatsapp.Contact) {
|
||||
// err := puppet.DefaultIntent().EnsureRegistered()
|
||||
// if err != nil {
|
||||
// puppet.log.Errorln("Failed to ensure registered:", err)
|
||||
// }
|
||||
func (puppet *Puppet) Sync(source *User, contact groupme.User) {
|
||||
err := puppet.DefaultIntent().EnsureRegistered()
|
||||
if err != nil {
|
||||
puppet.log.Errorln("Failed to ensure registered:", err)
|
||||
}
|
||||
|
||||
// if contact.Jid == source.JID {
|
||||
// contact.Notify = source.Conn.Info.Pushname
|
||||
// }
|
||||
if contact.ID.String() == source.JID {
|
||||
//TODO What is this
|
||||
// contact.Notify = source.Conn.Info.Pushname
|
||||
}
|
||||
|
||||
// update := false
|
||||
// update = puppet.UpdateName(source, contact) || update
|
||||
// update = puppet.UpdateAvatar(source, nil) || update
|
||||
// if update {
|
||||
// puppet.Update()
|
||||
// }
|
||||
update := false
|
||||
update = puppet.UpdateName(source, contact) || update
|
||||
update = puppet.UpdateAvatar(source, nil) || update
|
||||
if update {
|
||||
puppet.Update()
|
||||
}
|
||||
}
|
||||
|
453
user.go
453
user.go
@ -18,20 +18,16 @@ package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
log "maunium.net/go/maulogger/v2"
|
||||
|
||||
"github.com/Rhymen/go-whatsapp"
|
||||
waBinary "github.com/Rhymen/go-whatsapp/binary"
|
||||
waProto "github.com/Rhymen/go-whatsapp/binary/proto"
|
||||
|
||||
"maunium.net/go/mautrix"
|
||||
"maunium.net/go/mautrix/event"
|
||||
@ -154,10 +150,10 @@ func (bridge *Bridge) loadDBUser(dbUser *database.User, mxid *id.UserID) *User {
|
||||
}
|
||||
|
||||
func (user *User) GetPortals() []*Portal {
|
||||
user.bridge.portalsLock.Lock()
|
||||
keys := user.User.GetPortalKeys()
|
||||
portals := make([]*Portal, len(keys))
|
||||
|
||||
user.bridge.portalsLock.Lock()
|
||||
for i, key := range keys {
|
||||
portal, ok := user.bridge.portalsByJID[key]
|
||||
if !ok {
|
||||
@ -237,6 +233,7 @@ func (user *User) Connect() bool {
|
||||
} else if len(user.Token) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
user.log.Debugln("Connecting to WhatsApp")
|
||||
timeout := time.Duration(user.bridge.Config.Bridge.ConnectionTimeout)
|
||||
if timeout == 0 {
|
||||
@ -244,6 +241,7 @@ func (user *User) Connect() bool {
|
||||
}
|
||||
conn := groupme.NewPushSubscription(context.TODO())
|
||||
user.Conn = &conn
|
||||
user.Conn.StartListening(context.TODO())
|
||||
// if err != nil {
|
||||
// user.log.Errorln("Failed to connect to WhatsApp:", err)
|
||||
// user.sendMarkdownBridgeAlert("\u26a0 Failed to connect to WhatsApp server. " +
|
||||
@ -253,7 +251,7 @@ func (user *User) Connect() bool {
|
||||
// user.Conn = whatsappExt.ExtendConn(conn)
|
||||
// _ = user.Conn.SetClientName(user.bridge.Config.WhatsApp.OSName, user.bridge.Config.WhatsApp.BrowserName, WAVersion)
|
||||
// user.log.Debugln("WhatsApp connection successful")
|
||||
// user.Conn.AddHandler(user)
|
||||
user.Conn.AddHandler(user)
|
||||
|
||||
//TODO: typing notification?
|
||||
return user.RestoreSession()
|
||||
@ -280,7 +278,10 @@ func (user *User) RestoreSession() bool {
|
||||
// return false
|
||||
// }
|
||||
|
||||
user.Conn.SubscribeToUser(context.TODO(), groupme.ID(user.JID), user.Token)
|
||||
err := user.Conn.SubscribeToUser(context.TODO(), groupme.ID(user.JID), user.Token)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
//TODO: typing notifics
|
||||
user.ConnectionErrors = 0
|
||||
//user.SetSession(&sess)
|
||||
@ -469,12 +470,14 @@ func (user *User) intPostLogin() {
|
||||
defer user.syncWait.Done()
|
||||
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
|
||||
if len(user.JID) == 0 {
|
||||
myuser, err := user.Client.MyUser(context.TODO())
|
||||
if err != nil {
|
||||
log.Fatal(err) //TODO
|
||||
}
|
||||
user.JID = myuser.ID.String()
|
||||
user.Update()
|
||||
}
|
||||
user.JID = myuser.ID.String()
|
||||
user.Update()
|
||||
|
||||
user.createCommunity()
|
||||
user.tryAutomaticDoublePuppeting()
|
||||
@ -550,7 +553,7 @@ func (user *User) syncPortals(chatMap map[string]groupme.Group, createAll bool)
|
||||
|
||||
chats = append(chats, Chat{
|
||||
Portal: portal,
|
||||
LastMessageTime: uint64(time.Now().Unix()),
|
||||
LastMessageTime: uint64(chat.UpdatedAt.ToTime().Unix()),
|
||||
Group: chat,
|
||||
})
|
||||
var inCommunity, ok bool
|
||||
@ -564,6 +567,7 @@ func (user *User) syncPortals(chatMap map[string]groupme.Group, createAll bool)
|
||||
portalKeys = append(portalKeys, database.PortalKeyWithMeta{PortalKey: portal.Key, InCommunity: inCommunity})
|
||||
}
|
||||
user.log.Infoln("Read chat list, updating user-portal mapping")
|
||||
|
||||
err := user.SetPortalKeys(portalKeys)
|
||||
if err != nil {
|
||||
user.log.Warnln("Failed to update user-portal mapping:", err)
|
||||
@ -793,6 +797,13 @@ func (user *User) handleMessageLoop() {
|
||||
select {
|
||||
case msg := <-user.messageOutput:
|
||||
user.bridge.Metrics.TrackBufferLength(user.MXID, len(user.messageOutput))
|
||||
puppet := user.bridge.GetPuppetByJID(msg.data.UserID.String())
|
||||
if puppet != nil {
|
||||
puppet.Sync(user, groupme.User{
|
||||
ID: msg.data.ID,
|
||||
Name: msg.data.Name,
|
||||
}) //TODO: add params or docs?
|
||||
}
|
||||
user.GetPortalByJID(msg.chat).messages <- msg
|
||||
case <-user.syncStart:
|
||||
user.log.Debugln("Processing of incoming messages is locked")
|
||||
@ -804,33 +815,33 @@ func (user *User) handleMessageLoop() {
|
||||
}
|
||||
}
|
||||
|
||||
func (user *User) HandleNewContact(contact whatsapp.Contact) {
|
||||
user.log.Debugfln("Contact message: %+v", contact)
|
||||
go func() {
|
||||
if strings.HasSuffix(contact.Jid, whatsappExt.OldUserSuffix) {
|
||||
contact.Jid = strings.Replace(contact.Jid, whatsappExt.OldUserSuffix, whatsappExt.NewUserSuffix, -1)
|
||||
}
|
||||
puppet := user.bridge.GetPuppetByJID(contact.Jid)
|
||||
puppet.UpdateName(user, contact)
|
||||
}()
|
||||
}
|
||||
//func (user *User) HandleNewContact(contact whatsapp.Contact) {
|
||||
// user.log.Debugfln("Contact message: %+v", contact)
|
||||
// go func() {
|
||||
// if strings.HasSuffix(contact.Jid, whatsappExt.OldUserSuffix) {
|
||||
// contact.Jid = strings.Replace(contact.Jid, whatsappExt.OldUserSuffix, whatsappExt.NewUserSuffix, -1)
|
||||
// }
|
||||
// puppet := user.bridge.GetPuppetByJID(contact.Jid)
|
||||
// puppet.UpdateName(user, contact)
|
||||
// }()
|
||||
//}
|
||||
|
||||
func (user *User) HandleBatteryMessage(battery whatsapp.BatteryMessage) {
|
||||
user.log.Debugfln("Battery message: %+v", battery)
|
||||
var notice string
|
||||
if !battery.Plugged && battery.Percentage < 15 && user.batteryWarningsSent < 1 {
|
||||
notice = fmt.Sprintf("Phone battery low (%d %% remaining)", battery.Percentage)
|
||||
user.batteryWarningsSent = 1
|
||||
} else if !battery.Plugged && battery.Percentage < 5 && user.batteryWarningsSent < 2 {
|
||||
notice = fmt.Sprintf("Phone battery very low (%d %% remaining)", battery.Percentage)
|
||||
user.batteryWarningsSent = 2
|
||||
} else if battery.Percentage > 15 || battery.Plugged {
|
||||
user.batteryWarningsSent = 0
|
||||
}
|
||||
if notice != "" {
|
||||
go user.sendBridgeNotice("%s", notice)
|
||||
}
|
||||
}
|
||||
//func (user *User) HandleBatteryMessage(battery whatsapp.BatteryMessage) {
|
||||
// user.log.Debugfln("Battery message: %+v", battery)
|
||||
// var notice string
|
||||
// if !battery.Plugged && battery.Percentage < 15 && user.batteryWarningsSent < 1 {
|
||||
// notice = fmt.Sprintf("Phone battery low (%d %% remaining)", battery.Percentage)
|
||||
// user.batteryWarningsSent = 1
|
||||
// } else if !battery.Plugged && battery.Percentage < 5 && user.batteryWarningsSent < 2 {
|
||||
// notice = fmt.Sprintf("Phone battery very low (%d %% remaining)", battery.Percentage)
|
||||
// user.batteryWarningsSent = 2
|
||||
// } else if battery.Percentage > 15 || battery.Plugged {
|
||||
// user.batteryWarningsSent = 0
|
||||
// }
|
||||
// if notice != "" {
|
||||
// go user.sendBridgeNotice("%s", notice)
|
||||
// }
|
||||
//}
|
||||
|
||||
func (user *User) HandleTextMessage(message groupme.Message) {
|
||||
user.messageInput <- PortalMessage{message.GroupID.String(), user, &message, uint64(message.CreatedAt.ToTime().Unix())}
|
||||
@ -909,191 +920,191 @@ type FakeMessage struct {
|
||||
// }
|
||||
//}
|
||||
|
||||
func (user *User) HandlePresence(info whatsappExt.Presence) {
|
||||
puppet := user.bridge.GetPuppetByJID(info.SenderJID)
|
||||
switch info.Status {
|
||||
case whatsapp.PresenceUnavailable:
|
||||
_ = puppet.DefaultIntent().SetPresence("offline")
|
||||
case whatsapp.PresenceAvailable:
|
||||
if len(puppet.typingIn) > 0 && puppet.typingAt+15 > time.Now().Unix() {
|
||||
portal := user.bridge.GetPortalByMXID(puppet.typingIn)
|
||||
_, _ = puppet.IntentFor(portal).UserTyping(puppet.typingIn, false, 0)
|
||||
puppet.typingIn = ""
|
||||
puppet.typingAt = 0
|
||||
} else {
|
||||
_ = puppet.DefaultIntent().SetPresence("online")
|
||||
}
|
||||
case whatsapp.PresenceComposing:
|
||||
portal := user.GetPortalByJID(info.JID)
|
||||
if len(puppet.typingIn) > 0 && puppet.typingAt+15 > time.Now().Unix() {
|
||||
if puppet.typingIn == portal.MXID {
|
||||
return
|
||||
}
|
||||
_, _ = puppet.IntentFor(portal).UserTyping(puppet.typingIn, false, 0)
|
||||
}
|
||||
puppet.typingIn = portal.MXID
|
||||
puppet.typingAt = time.Now().Unix()
|
||||
_, _ = puppet.IntentFor(portal).UserTyping(portal.MXID, true, 15*1000)
|
||||
}
|
||||
}
|
||||
//func (user *User) HandlePresence(info whatsappExt.Presence) {
|
||||
// puppet := user.bridge.GetPuppetByJID(info.SenderJID)
|
||||
// switch info.Status {
|
||||
// case whatsapp.PresenceUnavailable:
|
||||
// _ = puppet.DefaultIntent().SetPresence("offline")
|
||||
// case whatsapp.PresenceAvailable:
|
||||
// if len(puppet.typingIn) > 0 && puppet.typingAt+15 > time.Now().Unix() {
|
||||
// portal := user.bridge.GetPortalByMXID(puppet.typingIn)
|
||||
// _, _ = puppet.IntentFor(portal).UserTyping(puppet.typingIn, false, 0)
|
||||
// puppet.typingIn = ""
|
||||
// puppet.typingAt = 0
|
||||
// } else {
|
||||
// _ = puppet.DefaultIntent().SetPresence("online")
|
||||
// }
|
||||
// case whatsapp.PresenceComposing:
|
||||
// portal := user.GetPortalByJID(info.JID)
|
||||
// if len(puppet.typingIn) > 0 && puppet.typingAt+15 > time.Now().Unix() {
|
||||
// if puppet.typingIn == portal.MXID {
|
||||
// return
|
||||
// }
|
||||
// _, _ = puppet.IntentFor(portal).UserTyping(puppet.typingIn, false, 0)
|
||||
// }
|
||||
// puppet.typingIn = portal.MXID
|
||||
// puppet.typingAt = time.Now().Unix()
|
||||
// _, _ = puppet.IntentFor(portal).UserTyping(portal.MXID, true, 15*1000)
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//func (user *User) HandleMsgInfo(info whatsappExt.MsgInfo) {
|
||||
// if (info.Command == whatsappExt.MsgInfoCommandAck || info.Command == whatsappExt.MsgInfoCommandAcks) && info.Acknowledgement == whatsappExt.AckMessageRead {
|
||||
// portal := user.GetPortalByJID(info.ToJID)
|
||||
// if len(portal.MXID) == 0 {
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// go func() {
|
||||
// intent := user.bridge.GetPuppetByJID(info.SenderJID).IntentFor(portal)
|
||||
// for _, msgID := range info.IDs {
|
||||
// msg := user.bridge.DB.Message.GetByJID(portal.Key, msgID)
|
||||
// if msg == nil {
|
||||
// continue
|
||||
// }
|
||||
//
|
||||
// err := intent.MarkRead(portal.MXID, msg.MXID)
|
||||
// if err != nil {
|
||||
// user.log.Warnln("Failed to mark message %s as read by %s: %v", msg.MXID, info.SenderJID, err)
|
||||
// }
|
||||
// }
|
||||
// }()
|
||||
// }
|
||||
//}
|
||||
|
||||
func (user *User) HandleMsgInfo(info whatsappExt.MsgInfo) {
|
||||
if (info.Command == whatsappExt.MsgInfoCommandAck || info.Command == whatsappExt.MsgInfoCommandAcks) && info.Acknowledgement == whatsappExt.AckMessageRead {
|
||||
portal := user.GetPortalByJID(info.ToJID)
|
||||
if len(portal.MXID) == 0 {
|
||||
return
|
||||
}
|
||||
//func (user *User) HandleReceivedMessage(received whatsapp.ReceivedMessage) {
|
||||
// if received.Type == "read" {
|
||||
// user.markSelfRead(received.Jid, received.Index)
|
||||
// } else {
|
||||
// user.log.Debugfln("Unknown received message type: %+v", received)
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//func (user *User) HandleReadMessage(read whatsapp.ReadMessage) {
|
||||
// user.log.Debugfln("Received chat read message: %+v", read)
|
||||
// user.markSelfRead(read.Jid, "")
|
||||
//}
|
||||
//
|
||||
//func (user *User) markSelfRead(jid, messageID string) {
|
||||
// if strings.HasSuffix(jid, whatsappExt.OldUserSuffix) {
|
||||
// jid = strings.Replace(jid, whatsappExt.OldUserSuffix, whatsappExt.NewUserSuffix, -1)
|
||||
// }
|
||||
// puppet := user.bridge.GetPuppetByJID(user.JID)
|
||||
// if puppet == nil {
|
||||
// return
|
||||
// }
|
||||
// intent := puppet.CustomIntent()
|
||||
// if intent == nil {
|
||||
// return
|
||||
// }
|
||||
// portal := user.GetPortalByJID(jid)
|
||||
// if portal == nil {
|
||||
// return
|
||||
// }
|
||||
// var message *database.Message
|
||||
// if messageID == "" {
|
||||
// message = user.bridge.DB.Message.GetLastInChat(portal.Key)
|
||||
// if message == nil {
|
||||
// return
|
||||
// }
|
||||
// user.log.Debugfln("User read chat %s/%s in WhatsApp mobile (last known event: %s/%s)", portal.Key.JID, portal.MXID, message.JID, message.MXID)
|
||||
// } else {
|
||||
// message = user.bridge.DB.Message.GetByJID(portal.Key, messageID)
|
||||
// if message == nil {
|
||||
// return
|
||||
// }
|
||||
// user.log.Debugfln("User read message %s/%s in %s/%s in WhatsApp mobile", message.JID, message.MXID, portal.Key.JID, portal.MXID)
|
||||
// }
|
||||
// err := intent.MarkRead(portal.MXID, message.MXID)
|
||||
// if err != nil {
|
||||
// user.log.Warnfln("Failed to bridge own read receipt in %s: %v", jid, err)
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//func (user *User) HandleCommand(cmd whatsappExt.Command) {
|
||||
// switch cmd.Type {
|
||||
// case whatsappExt.CommandPicture:
|
||||
// if strings.HasSuffix(cmd.JID, whatsappExt.NewUserSuffix) {
|
||||
// puppet := user.bridge.GetPuppetByJID(cmd.JID)
|
||||
// go puppet.UpdateAvatar(user, cmd.ProfilePicInfo)
|
||||
// } else {
|
||||
// portal := user.GetPortalByJID(cmd.JID)
|
||||
// go portal.UpdateAvatar(user, cmd.ProfilePicInfo, true)
|
||||
// }
|
||||
// case whatsappExt.CommandDisconnect:
|
||||
// user.cleanDisconnection = true
|
||||
// if cmd.Kind == "replaced" {
|
||||
// go user.sendMarkdownBridgeAlert("\u26a0 Your WhatsApp connection was closed by the server because you opened another WhatsApp Web client.\n\n" +
|
||||
// "Use the `reconnect` command to disconnect the other client and resume bridging.")
|
||||
// } else {
|
||||
// user.log.Warnln("Unknown kind of disconnect:", string(cmd.Raw))
|
||||
// go user.sendMarkdownBridgeAlert("\u26a0 Your WhatsApp connection was closed by the server (reason code: %s).\n\n"+
|
||||
// "Use the `reconnect` command to reconnect.", cmd.Kind)
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//func (user *User) HandleChatUpdate(cmd whatsappExt.ChatUpdate) {
|
||||
// if cmd.Command != whatsappExt.ChatUpdateCommandAction {
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// portal := user.GetPortalByJID(cmd.JID)
|
||||
// if len(portal.MXID) == 0 {
|
||||
// if cmd.Data.Action == whatsappExt.ChatActionIntroduce || cmd.Data.Action == whatsappExt.ChatActionCreate {
|
||||
// go func() {
|
||||
// err := portal.CreateMatrixRoom(user)
|
||||
// if err != nil {
|
||||
// user.log.Errorln("Failed to create portal room after receiving join event:", err)
|
||||
// }
|
||||
// }()
|
||||
// }
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// switch cmd.Data.Action {
|
||||
// case whatsappExt.ChatActionNameChange:
|
||||
// go portal.UpdateName(cmd.Data.NameChange.Name, cmd.Data.SenderJID, true)
|
||||
// case whatsappExt.ChatActionAddTopic:
|
||||
// go portal.UpdateTopic(cmd.Data.AddTopic.Topic, cmd.Data.SenderJID, true)
|
||||
// case whatsappExt.ChatActionRemoveTopic:
|
||||
// go portal.UpdateTopic("", cmd.Data.SenderJID, true)
|
||||
// case whatsappExt.ChatActionPromote:
|
||||
// go portal.ChangeAdminStatus(cmd.Data.UserChange.JIDs, true)
|
||||
// case whatsappExt.ChatActionDemote:
|
||||
// go portal.ChangeAdminStatus(cmd.Data.UserChange.JIDs, false)
|
||||
// case whatsappExt.ChatActionAnnounce:
|
||||
// go portal.RestrictMessageSending(cmd.Data.Announce)
|
||||
// case whatsappExt.ChatActionRestrict:
|
||||
// go portal.RestrictMetadataChanges(cmd.Data.Restrict)
|
||||
// case whatsappExt.ChatActionRemove:
|
||||
// go portal.HandleWhatsAppKick(cmd.Data.SenderJID, cmd.Data.UserChange.JIDs)
|
||||
// case whatsappExt.ChatActionAdd:
|
||||
// go portal.HandleWhatsAppInvite(cmd.Data.SenderJID, cmd.Data.UserChange.JIDs)
|
||||
// //case whatsappExt.ChatActionIntroduce:
|
||||
// // if cmd.Data.SenderJID != "unknown" {
|
||||
// // go portal.Sync(user, whatsapp.Contact{Jid: portal.Key.JID})
|
||||
// // }
|
||||
// }
|
||||
//}
|
||||
|
||||
go func() {
|
||||
intent := user.bridge.GetPuppetByJID(info.SenderJID).IntentFor(portal)
|
||||
for _, msgID := range info.IDs {
|
||||
msg := user.bridge.DB.Message.GetByJID(portal.Key, msgID)
|
||||
if msg == nil {
|
||||
continue
|
||||
}
|
||||
//func (user *User) HandleJsonMessage(message string) {
|
||||
// var msg json.RawMessage
|
||||
// err := json.Unmarshal([]byte(message), &msg)
|
||||
// if err != nil {
|
||||
// return
|
||||
// }
|
||||
// user.log.Debugln("JSON message:", message)
|
||||
// user.updateLastConnectionIfNecessary()
|
||||
//}
|
||||
|
||||
err := intent.MarkRead(portal.MXID, msg.MXID)
|
||||
if err != nil {
|
||||
user.log.Warnln("Failed to mark message %s as read by %s: %v", msg.MXID, info.SenderJID, err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
}
|
||||
|
||||
func (user *User) HandleReceivedMessage(received whatsapp.ReceivedMessage) {
|
||||
if received.Type == "read" {
|
||||
user.markSelfRead(received.Jid, received.Index)
|
||||
} else {
|
||||
user.log.Debugfln("Unknown received message type: %+v", received)
|
||||
}
|
||||
}
|
||||
|
||||
func (user *User) HandleReadMessage(read whatsapp.ReadMessage) {
|
||||
user.log.Debugfln("Received chat read message: %+v", read)
|
||||
user.markSelfRead(read.Jid, "")
|
||||
}
|
||||
|
||||
func (user *User) markSelfRead(jid, messageID string) {
|
||||
if strings.HasSuffix(jid, whatsappExt.OldUserSuffix) {
|
||||
jid = strings.Replace(jid, whatsappExt.OldUserSuffix, whatsappExt.NewUserSuffix, -1)
|
||||
}
|
||||
puppet := user.bridge.GetPuppetByJID(user.JID)
|
||||
if puppet == nil {
|
||||
return
|
||||
}
|
||||
intent := puppet.CustomIntent()
|
||||
if intent == nil {
|
||||
return
|
||||
}
|
||||
portal := user.GetPortalByJID(jid)
|
||||
if portal == nil {
|
||||
return
|
||||
}
|
||||
var message *database.Message
|
||||
if messageID == "" {
|
||||
message = user.bridge.DB.Message.GetLastInChat(portal.Key)
|
||||
if message == nil {
|
||||
return
|
||||
}
|
||||
user.log.Debugfln("User read chat %s/%s in WhatsApp mobile (last known event: %s/%s)", portal.Key.JID, portal.MXID, message.JID, message.MXID)
|
||||
} else {
|
||||
message = user.bridge.DB.Message.GetByJID(portal.Key, messageID)
|
||||
if message == nil {
|
||||
return
|
||||
}
|
||||
user.log.Debugfln("User read message %s/%s in %s/%s in WhatsApp mobile", message.JID, message.MXID, portal.Key.JID, portal.MXID)
|
||||
}
|
||||
err := intent.MarkRead(portal.MXID, message.MXID)
|
||||
if err != nil {
|
||||
user.log.Warnfln("Failed to bridge own read receipt in %s: %v", jid, err)
|
||||
}
|
||||
}
|
||||
|
||||
func (user *User) HandleCommand(cmd whatsappExt.Command) {
|
||||
switch cmd.Type {
|
||||
case whatsappExt.CommandPicture:
|
||||
if strings.HasSuffix(cmd.JID, whatsappExt.NewUserSuffix) {
|
||||
puppet := user.bridge.GetPuppetByJID(cmd.JID)
|
||||
go puppet.UpdateAvatar(user, cmd.ProfilePicInfo)
|
||||
} else {
|
||||
portal := user.GetPortalByJID(cmd.JID)
|
||||
go portal.UpdateAvatar(user, cmd.ProfilePicInfo, true)
|
||||
}
|
||||
case whatsappExt.CommandDisconnect:
|
||||
user.cleanDisconnection = true
|
||||
if cmd.Kind == "replaced" {
|
||||
go user.sendMarkdownBridgeAlert("\u26a0 Your WhatsApp connection was closed by the server because you opened another WhatsApp Web client.\n\n" +
|
||||
"Use the `reconnect` command to disconnect the other client and resume bridging.")
|
||||
} else {
|
||||
user.log.Warnln("Unknown kind of disconnect:", string(cmd.Raw))
|
||||
go user.sendMarkdownBridgeAlert("\u26a0 Your WhatsApp connection was closed by the server (reason code: %s).\n\n"+
|
||||
"Use the `reconnect` command to reconnect.", cmd.Kind)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (user *User) HandleChatUpdate(cmd whatsappExt.ChatUpdate) {
|
||||
if cmd.Command != whatsappExt.ChatUpdateCommandAction {
|
||||
return
|
||||
}
|
||||
|
||||
portal := user.GetPortalByJID(cmd.JID)
|
||||
if len(portal.MXID) == 0 {
|
||||
if cmd.Data.Action == whatsappExt.ChatActionIntroduce || cmd.Data.Action == whatsappExt.ChatActionCreate {
|
||||
go func() {
|
||||
err := portal.CreateMatrixRoom(user)
|
||||
if err != nil {
|
||||
user.log.Errorln("Failed to create portal room after receiving join event:", err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
switch cmd.Data.Action {
|
||||
case whatsappExt.ChatActionNameChange:
|
||||
go portal.UpdateName(cmd.Data.NameChange.Name, cmd.Data.SenderJID, true)
|
||||
case whatsappExt.ChatActionAddTopic:
|
||||
go portal.UpdateTopic(cmd.Data.AddTopic.Topic, cmd.Data.SenderJID, true)
|
||||
case whatsappExt.ChatActionRemoveTopic:
|
||||
go portal.UpdateTopic("", cmd.Data.SenderJID, true)
|
||||
case whatsappExt.ChatActionPromote:
|
||||
go portal.ChangeAdminStatus(cmd.Data.UserChange.JIDs, true)
|
||||
case whatsappExt.ChatActionDemote:
|
||||
go portal.ChangeAdminStatus(cmd.Data.UserChange.JIDs, false)
|
||||
case whatsappExt.ChatActionAnnounce:
|
||||
go portal.RestrictMessageSending(cmd.Data.Announce)
|
||||
case whatsappExt.ChatActionRestrict:
|
||||
go portal.RestrictMetadataChanges(cmd.Data.Restrict)
|
||||
case whatsappExt.ChatActionRemove:
|
||||
go portal.HandleWhatsAppKick(cmd.Data.SenderJID, cmd.Data.UserChange.JIDs)
|
||||
case whatsappExt.ChatActionAdd:
|
||||
go portal.HandleWhatsAppInvite(cmd.Data.SenderJID, cmd.Data.UserChange.JIDs)
|
||||
//case whatsappExt.ChatActionIntroduce:
|
||||
// if cmd.Data.SenderJID != "unknown" {
|
||||
// go portal.Sync(user, whatsapp.Contact{Jid: portal.Key.JID})
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
func (user *User) HandleJsonMessage(message string) {
|
||||
var msg json.RawMessage
|
||||
err := json.Unmarshal([]byte(message), &msg)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
user.log.Debugln("JSON message:", message)
|
||||
user.updateLastConnectionIfNecessary()
|
||||
}
|
||||
|
||||
func (user *User) HandleRawMessage(message *waProto.WebMessageInfo) {
|
||||
user.updateLastConnectionIfNecessary()
|
||||
}
|
||||
|
||||
func (user *User) HandleUnknownBinaryNode(node *waBinary.Node) {
|
||||
user.log.Debugfln("Unknown binary message: %+v", node)
|
||||
}
|
||||
//func (user *User) HandleRawMessage(message *waProto.WebMessageInfo) {
|
||||
// user.updateLastConnectionIfNecessary()
|
||||
//}
|
||||
//
|
||||
//func (user *User) HandleUnknownBinaryNode(node *waBinary.Node) {
|
||||
// user.log.Debugfln("Unknown binary message: %+v", node)
|
||||
//}
|
||||
|
||||
func (user *User) NeedsRelaybot(portal *Portal) bool {
|
||||
return !user.HasSession() || !user.IsInPortal(portal.Key)
|
||||
|
Loading…
Reference in New Issue
Block a user