diff --git a/commands.go b/commands.go index 3052533..1fd3862 100644 --- a/commands.go +++ b/commands.go @@ -918,31 +918,31 @@ func (handler *CommandHandler) CommandPM(ce *CommandEvent) { const cmdLoginMatrixHelp = `login-matrix <_access token_> - Replace your WhatsApp account's Matrix puppet with your real Matrix account.'` func (handler *CommandHandler) CommandLoginMatrix(ce *CommandEvent) { - if len(ce.Args) == 0 { - ce.Reply("**Usage:** `login-matrix `") - return - } - puppet := handler.bridge.GetPuppetByJID(ce.User.JID) - err := puppet.SwitchCustomMXID(ce.Args[0], ce.User.MXID) - if err != nil { - ce.Reply("Failed to switch puppet: %v", err) - return - } - ce.Reply("Successfully switched puppet") + //if len(ce.Args) == 0 { + // ce.Reply("**Usage:** `login-matrix `") + // return + //} + //puppet := handler.bridge.GetPuppetByJID(ce.User.JID) + //err := puppet.SwitchCustomMXID(ce.Args[0], ce.User.MXID) + //if err != nil { + // ce.Reply("Failed to switch puppet: %v", err) + // return + //} + //ce.Reply("Successfully switched puppet") } const cmdLogoutMatrixHelp = `logout-matrix - Switch your WhatsApp account's Matrix puppet back to the default one.` func (handler *CommandHandler) CommandLogoutMatrix(ce *CommandEvent) { - puppet := handler.bridge.GetPuppetByJID(ce.User.JID) - if len(puppet.CustomMXID) == 0 { - ce.Reply("You had not changed your WhatsApp account's Matrix puppet.") - return - } - err := puppet.SwitchCustomMXID("", "") - if err != nil { - ce.Reply("Failed to remove custom puppet: %v", err) - return - } - ce.Reply("Successfully removed custom puppet") + //puppet := handler.bridge.GetPuppetByJID(ce.User.JID) + //if len(puppet.CustomMXID) == 0 { + // ce.Reply("You had not changed your WhatsApp account's Matrix puppet.") + // return + //} + //err := puppet.SwitchCustomMXID("", "") + //if err != nil { + // ce.Reply("Failed to remove custom puppet: %v", err) + // return + //} + //ce.Reply("Successfully removed custom puppet") } diff --git a/config/bridge.go b/config/bridge.go index 79c3079..dd8fbaa 100644 --- a/config/bridge.go +++ b/config/bridge.go @@ -157,7 +157,7 @@ type UsernameTemplateArgs struct { UserID id.UserID } -func (bc BridgeConfig) FormatDisplayname(contact groupme.User) (string, int8) { +func (bc BridgeConfig) FormatDisplayname(contact groupme.Member) (string, int8) { var buf bytes.Buffer if index := strings.IndexRune(contact.ID.String(), '@'); index > 0 { contact.ID = groupme.ID("+" + contact.ID.String()[:index]) @@ -165,10 +165,9 @@ func (bc BridgeConfig) FormatDisplayname(contact groupme.User) (string, int8) { bc.displaynameTemplate.Execute(&buf, contact) var quality int8 switch { - case len(contact.Name) > 0: + case len(contact.Nickname) > 0: quality = 3 - case len(contact.Name) > 0 || len(contact.Name) > 0: - quality = 2 + //TODO what case len(contact.ID) > 0: quality = 1 default: diff --git a/custompuppet.go b/custompuppet.go index 20374e8..5f49e7d 100644 --- a/custompuppet.go +++ b/custompuppet.go @@ -17,18 +17,8 @@ package main import ( - "crypto/hmac" - "crypto/sha512" - "encoding/hex" "errors" - "time" - // "github.com/Rhymen/go-whatsapp" - - "maunium.net/go/mautrix" - "maunium.net/go/mautrix/appservice" - "maunium.net/go/mautrix/event" - "maunium.net/go/mautrix/id" ) var ( @@ -36,246 +26,246 @@ var ( ErrMismatchingMXID = errors.New("whoami result does not match custom mxid") ) -func (puppet *Puppet) SwitchCustomMXID(accessToken string, mxid id.UserID) error { - prevCustomMXID := puppet.CustomMXID - if puppet.customIntent != nil { - puppet.stopSyncing() - } - puppet.CustomMXID = mxid - puppet.AccessToken = accessToken - - err := puppet.StartCustomMXID() - if err != nil { - return err - } - - if len(prevCustomMXID) > 0 { - delete(puppet.bridge.puppetsByCustomMXID, prevCustomMXID) - } - if len(puppet.CustomMXID) > 0 { - puppet.bridge.puppetsByCustomMXID[puppet.CustomMXID] = puppet - } - puppet.EnablePresence = puppet.bridge.Config.Bridge.DefaultBridgePresence - puppet.EnableReceipts = puppet.bridge.Config.Bridge.DefaultBridgeReceipts - puppet.bridge.AS.StateStore.MarkRegistered(puppet.CustomMXID) - puppet.Update() - // TODO leave rooms with default puppet - return nil -} - -func (puppet *Puppet) loginWithSharedSecret(mxid id.UserID) (string, error) { - puppet.log.Debugfln("Logging into %s with shared secret", mxid) - mac := hmac.New(sha512.New, []byte(puppet.bridge.Config.Bridge.LoginSharedSecret)) - mac.Write([]byte(mxid)) - resp, err := puppet.bridge.AS.BotClient().Login(&mautrix.ReqLogin{ - Type: mautrix.AuthTypePassword, - Identifier: mautrix.UserIdentifier{Type: mautrix.IdentifierTypeUser, User: string(mxid)}, - Password: hex.EncodeToString(mac.Sum(nil)), - DeviceID: "WhatsApp Bridge", - InitialDeviceDisplayName: "WhatsApp Bridge", - }) - if err != nil { - return "", err - } - return resp.AccessToken, nil -} - -func (puppet *Puppet) newCustomIntent() (*appservice.IntentAPI, error) { - if len(puppet.CustomMXID) == 0 { - return nil, ErrNoCustomMXID - } - client, err := mautrix.NewClient(puppet.bridge.AS.HomeserverURL, puppet.CustomMXID, puppet.AccessToken) - if err != nil { - return nil, err - } - client.Logger = puppet.bridge.AS.Log.Sub(string(puppet.CustomMXID)) - client.Syncer = puppet - client.Store = puppet - - ia := puppet.bridge.AS.NewIntentAPI("custom") - ia.Client = client - ia.Localpart, _, _ = puppet.CustomMXID.Parse() - ia.UserID = puppet.CustomMXID - ia.IsCustomPuppet = true - return ia, nil -} - -func (puppet *Puppet) clearCustomMXID() { - puppet.CustomMXID = "" - puppet.AccessToken = "" - puppet.customIntent = nil - puppet.customTypingIn = nil - puppet.customUser = nil -} - -func (puppet *Puppet) StartCustomMXID() error { - if len(puppet.CustomMXID) == 0 { - puppet.clearCustomMXID() - return nil - } - intent, err := puppet.newCustomIntent() - if err != nil { - puppet.clearCustomMXID() - return err - } - resp, err := intent.Whoami() - if err != nil { - puppet.clearCustomMXID() - return err - } - if resp.UserID != puppet.CustomMXID { - puppet.clearCustomMXID() - return ErrMismatchingMXID - } - puppet.customIntent = intent - puppet.customTypingIn = make(map[id.RoomID]bool) - puppet.customUser = puppet.bridge.GetUserByMXID(puppet.CustomMXID) - puppet.startSyncing() - return nil -} - -func (puppet *Puppet) startSyncing() { - if !puppet.bridge.Config.Bridge.SyncWithCustomPuppets { - return - } - go func() { - puppet.log.Debugln("Starting syncing...") - puppet.customIntent.SyncPresence = "offline" - err := puppet.customIntent.Sync() - if err != nil { - puppet.log.Errorln("Fatal error syncing:", err) - } - }() -} - -func (puppet *Puppet) stopSyncing() { - if !puppet.bridge.Config.Bridge.SyncWithCustomPuppets { - return - } - puppet.customIntent.StopSync() -} - -func (puppet *Puppet) ProcessResponse(resp *mautrix.RespSync, _ string) error { - if !puppet.customUser.IsConnected() { - puppet.log.Debugln("Skipping sync processing: custom user not connected to whatsapp") - return nil - } - for roomID, events := range resp.Rooms.Join { - portal := puppet.bridge.GetPortalByMXID(roomID) - if portal == nil { - continue - } - for _, evt := range events.Ephemeral.Events { - err := evt.Content.ParseRaw(evt.Type) - if err != nil { - continue - } - switch evt.Type { - case event.EphemeralEventReceipt: - if puppet.EnableReceipts { - go puppet.handleReceiptEvent(portal, evt) - } - case event.EphemeralEventTyping: - go puppet.handleTypingEvent(portal, evt) - } - } - } - if puppet.EnablePresence { - for _, evt := range resp.Presence.Events { - if evt.Sender != puppet.CustomMXID { - continue - } - err := evt.Content.ParseRaw(evt.Type) - if err != nil { - continue - } - go puppet.handlePresenceEvent(evt) - } - } - return nil -} - -func (puppet *Puppet) handlePresenceEvent(event *event.Event) { - // presence := whatsapp.PresenceAvailable - // if event.Content.Raw["presence"].(string) != "online" { - // presence = whatsapp.PresenceUnavailable - // puppet.customUser.log.Debugln("Marking offline") - // } else { - // puppet.customUser.log.Debugln("Marking online") - // } - // _, err := puppet.customUser.Conn.Presence("", presence) - // if err != nil { - // puppet.customUser.log.Warnln("Failed to set presence:", err) - // } -} - -func (puppet *Puppet) handleReceiptEvent(portal *Portal, event *event.Event) { - // for eventID, receipts := range *event.Content.AsReceipt() { - // if _, ok := receipts.Read[puppet.CustomMXID]; !ok { - // continue - // } - // message := puppet.bridge.DB.Message.GetByMXID(eventID) - // if message == nil { - // continue - // } - // puppet.customUser.log.Debugfln("Marking %s/%s in %s/%s as read", message.JID, message.MXID, portal.Key.JID, portal.MXID) - // _, err := puppet.customUser.Conn.Read(portal.Key.JID, message.JID) - // if err != nil { - // puppet.customUser.log.Warnln("Error marking read:", err) - // } - // } -} - -func (puppet *Puppet) handleTypingEvent(portal *Portal, evt *event.Event) { - // isTyping := false - // for _, userID := range evt.Content.AsTyping().UserIDs { - // if userID == puppet.CustomMXID { - // isTyping = true - // break - // } - // } - // if puppet.customTypingIn[evt.RoomID] != isTyping { - // puppet.customTypingIn[evt.RoomID] = isTyping - // presence := whatsapp.PresenceComposing - // if !isTyping { - // puppet.customUser.log.Debugfln("Marking not typing in %s/%s", portal.Key.JID, portal.MXID) - // presence = whatsapp.PresencePaused - // } else { - // puppet.customUser.log.Debugfln("Marking typing in %s/%s", portal.Key.JID, portal.MXID) - // } - // _, err := puppet.customUser.Conn.Presence(portal.Key.JID, presence) - // if err != nil { - // puppet.customUser.log.Warnln("Error setting typing:", err) - // } - // } -} - -func (puppet *Puppet) OnFailedSync(_ *mautrix.RespSync, err error) (time.Duration, error) { - puppet.log.Warnln("Sync error:", err) - return 10 * time.Second, nil -} - -func (puppet *Puppet) GetFilterJSON(_ id.UserID) *mautrix.Filter { - everything := []event.Type{{Type: "*"}} - return &mautrix.Filter{ - Presence: mautrix.FilterPart{ - Senders: []id.UserID{puppet.CustomMXID}, - Types: []event.Type{event.EphemeralEventPresence}, - }, - AccountData: mautrix.FilterPart{NotTypes: everything}, - Room: mautrix.RoomFilter{ - Ephemeral: mautrix.FilterPart{Types: []event.Type{event.EphemeralEventTyping, event.EphemeralEventReceipt}}, - IncludeLeave: false, - AccountData: mautrix.FilterPart{NotTypes: everything}, - State: mautrix.FilterPart{NotTypes: everything}, - Timeline: mautrix.FilterPart{NotTypes: everything}, - }, - } -} - -func (puppet *Puppet) SaveFilterID(_ id.UserID, _ string) {} -func (puppet *Puppet) SaveNextBatch(_ id.UserID, nbt string) { puppet.NextBatch = nbt; puppet.Update() } -func (puppet *Puppet) SaveRoom(_ *mautrix.Room) {} -func (puppet *Puppet) LoadFilterID(_ id.UserID) string { return "" } -func (puppet *Puppet) LoadNextBatch(_ id.UserID) string { return puppet.NextBatch } -func (puppet *Puppet) LoadRoom(_ id.RoomID) *mautrix.Room { return nil } +//func (puppet *Puppet) SwitchCustomMXID(accessToken string, mxid id.UserID) error { +// prevCustomMXID := puppet.CustomMXID +// if puppet.customIntent != nil { +// puppet.stopSyncing() +// } +// puppet.CustomMXID = mxid +// puppet.AccessToken = accessToken +// +// err := puppet.StartCustomMXID() +// if err != nil { +// return err +// } +// +// if len(prevCustomMXID) > 0 { +// delete(puppet.bridge.puppetsByCustomMXID, prevCustomMXID) +// } +// if len(puppet.CustomMXID) > 0 { +// puppet.bridge.puppetsByCustomMXID[puppet.CustomMXID] = puppet +// } +// puppet.EnablePresence = puppet.bridge.Config.Bridge.DefaultBridgePresence +// puppet.EnableReceipts = puppet.bridge.Config.Bridge.DefaultBridgeReceipts +// puppet.bridge.AS.StateStore.MarkRegistered(puppet.CustomMXID) +// puppet.Update() +// // TODO leave rooms with default puppet +// return nil +//} +// +//func (puppet *Puppet) loginWithSharedSecret(mxid id.UserID) (string, error) { +// puppet.log.Debugfln("Logging into %s with shared secret", mxid) +// mac := hmac.New(sha512.New, []byte(puppet.bridge.Config.Bridge.LoginSharedSecret)) +// mac.Write([]byte(mxid)) +// resp, err := puppet.bridge.AS.BotClient().Login(&mautrix.ReqLogin{ +// Type: mautrix.AuthTypePassword, +// Identifier: mautrix.UserIdentifier{Type: mautrix.IdentifierTypeUser, User: string(mxid)}, +// Password: hex.EncodeToString(mac.Sum(nil)), +// DeviceID: "WhatsApp Bridge", +// InitialDeviceDisplayName: "WhatsApp Bridge", +// }) +// if err != nil { +// return "", err +// } +// return resp.AccessToken, nil +//} +// +//func (puppet *Puppet) newCustomIntent() (*appservice.IntentAPI, error) { +// if len(puppet.CustomMXID) == 0 { +// return nil, ErrNoCustomMXID +// } +// client, err := mautrix.NewClient(puppet.bridge.AS.HomeserverURL, puppet.CustomMXID, puppet.AccessToken) +// if err != nil { +// return nil, err +// } +// client.Logger = puppet.bridge.AS.Log.Sub(string(puppet.CustomMXID)) +// client.Syncer = puppet +// client.Store = puppet +// +// ia := puppet.bridge.AS.NewIntentAPI("custom") +// ia.Client = client +// ia.Localpart, _, _ = puppet.CustomMXID.Parse() +// ia.UserID = puppet.CustomMXID +// ia.IsCustomPuppet = true +// return ia, nil +//} +// +//func (puppet *Puppet) clearCustomMXID() { +// puppet.CustomMXID = "" +// puppet.AccessToken = "" +// puppet.customIntent = nil +// puppet.customTypingIn = nil +// puppet.customUser = nil +//} +// +//func (puppet *Puppet) StartCustomMXID() error { +// if len(puppet.CustomMXID) == 0 { +// puppet.clearCustomMXID() +// return nil +// } +// intent, err := puppet.newCustomIntent() +// if err != nil { +// puppet.clearCustomMXID() +// return err +// } +// resp, err := intent.Whoami() +// if err != nil { +// puppet.clearCustomMXID() +// return err +// } +// if resp.UserID != puppet.CustomMXID { +// puppet.clearCustomMXID() +// return ErrMismatchingMXID +// } +// puppet.customIntent = intent +// puppet.customTypingIn = make(map[id.RoomID]bool) +// puppet.customUser = puppet.bridge.GetUserByMXID(puppet.CustomMXID) +// puppet.startSyncing() +// return nil +//} +// +//func (puppet *Puppet) startSyncing() { +// if !puppet.bridge.Config.Bridge.SyncWithCustomPuppets { +// return +// } +// go func() { +// puppet.log.Debugln("Starting syncing...") +// puppet.customIntent.SyncPresence = "offline" +// err := puppet.customIntent.Sync() +// if err != nil { +// puppet.log.Errorln("Fatal error syncing:", err) +// } +// }() +//} +// +//func (puppet *Puppet) stopSyncing() { +// if !puppet.bridge.Config.Bridge.SyncWithCustomPuppets { +// return +// } +// puppet.customIntent.StopSync() +//} +// +//func (puppet *Puppet) ProcessResponse(resp *mautrix.RespSync, _ string) error { +// if !puppet.customUser.IsConnected() { +// puppet.log.Debugln("Skipping sync processing: custom user not connected to whatsapp") +// return nil +// } +// for roomID, events := range resp.Rooms.Join { +// portal := puppet.bridge.GetPortalByMXID(roomID) +// if portal == nil { +// continue +// } +// for _, evt := range events.Ephemeral.Events { +// err := evt.Content.ParseRaw(evt.Type) +// if err != nil { +// continue +// } +// switch evt.Type { +// case event.EphemeralEventReceipt: +// if puppet.EnableReceipts { +// go puppet.handleReceiptEvent(portal, evt) +// } +// case event.EphemeralEventTyping: +// go puppet.handleTypingEvent(portal, evt) +// } +// } +// } +// if puppet.EnablePresence { +// for _, evt := range resp.Presence.Events { +// if evt.Sender != puppet.CustomMXID { +// continue +// } +// err := evt.Content.ParseRaw(evt.Type) +// if err != nil { +// continue +// } +// go puppet.handlePresenceEvent(evt) +// } +// } +// return nil +//} +// +//func (puppet *Puppet) handlePresenceEvent(event *event.Event) { +// // presence := whatsapp.PresenceAvailable +// // if event.Content.Raw["presence"].(string) != "online" { +// // presence = whatsapp.PresenceUnavailable +// // puppet.customUser.log.Debugln("Marking offline") +// // } else { +// // puppet.customUser.log.Debugln("Marking online") +// // } +// // _, err := puppet.customUser.Conn.Presence("", presence) +// // if err != nil { +// // puppet.customUser.log.Warnln("Failed to set presence:", err) +// // } +//} +// +//func (puppet *Puppet) handleReceiptEvent(portal *Portal, event *event.Event) { +// // for eventID, receipts := range *event.Content.AsReceipt() { +// // if _, ok := receipts.Read[puppet.CustomMXID]; !ok { +// // continue +// // } +// // message := puppet.bridge.DB.Message.GetByMXID(eventID) +// // if message == nil { +// // continue +// // } +// // puppet.customUser.log.Debugfln("Marking %s/%s in %s/%s as read", message.JID, message.MXID, portal.Key.JID, portal.MXID) +// // _, err := puppet.customUser.Conn.Read(portal.Key.JID, message.JID) +// // if err != nil { +// // puppet.customUser.log.Warnln("Error marking read:", err) +// // } +// // } +//} +// +//func (puppet *Puppet) handleTypingEvent(portal *Portal, evt *event.Event) { +// // isTyping := false +// // for _, userID := range evt.Content.AsTyping().UserIDs { +// // if userID == puppet.CustomMXID { +// // isTyping = true +// // break +// // } +// // } +// // if puppet.customTypingIn[evt.RoomID] != isTyping { +// // puppet.customTypingIn[evt.RoomID] = isTyping +// // presence := whatsapp.PresenceComposing +// // if !isTyping { +// // puppet.customUser.log.Debugfln("Marking not typing in %s/%s", portal.Key.JID, portal.MXID) +// // presence = whatsapp.PresencePaused +// // } else { +// // puppet.customUser.log.Debugfln("Marking typing in %s/%s", portal.Key.JID, portal.MXID) +// // } +// // _, err := puppet.customUser.Conn.Presence(portal.Key.JID, presence) +// // if err != nil { +// // puppet.customUser.log.Warnln("Error setting typing:", err) +// // } +// // } +//} +// +//func (puppet *Puppet) OnFailedSync(_ *mautrix.RespSync, err error) (time.Duration, error) { +// puppet.log.Warnln("Sync error:", err) +// return 10 * time.Second, nil +//} +// +//func (puppet *Puppet) GetFilterJSON(_ id.UserID) *mautrix.Filter { +// everything := []event.Type{{Type: "*"}} +// return &mautrix.Filter{ +// Presence: mautrix.FilterPart{ +// Senders: []id.UserID{puppet.CustomMXID}, +// Types: []event.Type{event.EphemeralEventPresence}, +// }, +// AccountData: mautrix.FilterPart{NotTypes: everything}, +// Room: mautrix.RoomFilter{ +// Ephemeral: mautrix.FilterPart{Types: []event.Type{event.EphemeralEventTyping, event.EphemeralEventReceipt}}, +// IncludeLeave: false, +// AccountData: mautrix.FilterPart{NotTypes: everything}, +// State: mautrix.FilterPart{NotTypes: everything}, +// Timeline: mautrix.FilterPart{NotTypes: everything}, +// }, +// } +//} +// +//func (puppet *Puppet) SaveFilterID(_ id.UserID, _ string) {} +//func (puppet *Puppet) SaveNextBatch(_ id.UserID, nbt string) { puppet.NextBatch = nbt; puppet.Update() } +//func (puppet *Puppet) SaveRoom(_ *mautrix.Room) {} +//func (puppet *Puppet) LoadFilterID(_ id.UserID) string { return "" } +//func (puppet *Puppet) LoadNextBatch(_ id.UserID) string { return puppet.NextBatch } +//func (puppet *Puppet) LoadRoom(_ id.RoomID) *mautrix.Room { return nil } diff --git a/example-config.yaml b/example-config.yaml index eeb0747..5ea0f3d 100644 --- a/example-config.yaml +++ b/example-config.yaml @@ -75,7 +75,7 @@ bridge: # {{.Short}} - short display name from contact list # To use multiple if's, you need to use: {{else if .Name}}, for example: # "{{if .Notify}}{{.Notify}}{{else if .Name}}{{.Name}}{{else}}{{.Jid}}{{end}} (WA)" - displayname_template: "{{if .Notify}}{{.Notify}}{{else}}{{.Jid}}{{end}} (WA)" + displayname_template: "{{if .Nickname}}{{.Nickname}}{{else}}{{call .ID.String}}{{end}} (WA)" # Localpart template for per-user room grouping community IDs. # On startup, the bridge will try to create these communities, add all of the specific user's # portals to the community, and invite the Matrix user to it. diff --git a/groupmeExt/client.go b/groupmeExt/client.go index 7f41f92..86e0eb8 100644 --- a/groupmeExt/client.go +++ b/groupmeExt/client.go @@ -20,7 +20,7 @@ func NewClient(authToken string) *Client { } func (c Client) IndexAllGroups() ([]*groupme.Group, error) { return c.IndexGroups(context.TODO(), &groupme.GroupsQuery{ - Omit: "memberships", + // Omit: "memberships", PerPage: 100, //TODO: Configurable and add multipage support }) } diff --git a/portal.go b/portal.go index e33cf8d..e893f77 100644 --- a/portal.go +++ b/portal.go @@ -370,7 +370,6 @@ func (portal *Portal) SyncParticipants(metadata *groupme.Group) { participantMap := make(map[string]bool) for _, participant := range metadata.Members { participantMap[participant.ID.String()] = true - fmt.Println(participant.ID.String()) user := portal.bridge.GetUserByJID(participant.ID.String()) portal.userMXIDAction(user, portal.ensureMXIDInvited) @@ -390,6 +389,7 @@ func (portal *Portal) SyncParticipants(metadata *groupme.Group) { if user != nil { changed = levels.EnsureUserLevel(user.MXID, expectedLevel) || changed } + puppet.Sync(nil, *participant) //why nil whynot } if changed { _, err = portal.MainIntent().SetPowerLevels(portal.MXID, levels) @@ -405,7 +405,6 @@ func (portal *Portal) SyncParticipants(metadata *groupme.Group) { jid, ok := portal.bridge.ParsePuppetMXID(member) if ok { _, shouldBePresent := participantMap[jid] - fmt.Println(jid) if !shouldBePresent { _, err := portal.MainIntent().KickUser(portal.MXID, &mautrix.ReqKickUser{ UserID: member, @@ -708,11 +707,9 @@ func (portal *Portal) BackfillHistory(user *User, lastMessageTime uint64) error defer endBackfill() 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 @@ -2036,13 +2033,21 @@ func (portal *Portal) HandleMatrixMessage(sender *User, evt *event.Event) { } for _, i := range info { portal.log.Debugln("Sending event", evt.ID, "to WhatsApp", info[0].ID) - i = portal.sendRaw(sender, evt, info[0], false) //TODO deal with multiple messages for longer messages - portal.markHandled(sender, i, evt.ID) + + var err error + i, err = portal.sendRaw(sender, evt, info[0], false) //TODO deal with multiple messages for longer messages + if err != nil { + portal.log.Warnln("Unable to handle message from Matrix", evt.ID) + //TODO handle deleted room and such + } else { + + portal.markHandled(sender, i, evt.ID) + } } } -func (portal *Portal) sendRaw(sender *User, evt *event.Event, info *groupme.Message, isRetry bool) *groupme.Message { +func (portal *Portal) sendRaw(sender *User, evt *event.Event, info *groupme.Message, isRetry bool) (*groupme.Message, error) { m, err := sender.Client.CreateMessage(context.TODO(), info.GroupID, info) id := "" @@ -2055,7 +2060,10 @@ func (portal *Portal) sendRaw(sender *User, evt *event.Event, info *groupme.Mess if isRetry && err != nil { m, err = sender.Client.CreateMessage(context.TODO(), info.GroupID, info) } - return m + if err != nil { + return nil, err + } + return m, nil // errChan := make(chan error, 1) // go sender.Conn.SendRaw(info, errChan) diff --git a/puppet.go b/puppet.go index df5d299..9282a9f 100644 --- a/puppet.go +++ b/puppet.go @@ -232,7 +232,7 @@ func (puppet *Puppet) UpdateAvatar(source *User, avatar string) bool { return true } -func (puppet *Puppet) UpdateName(source *User, contact groupme.User) bool { +func (puppet *Puppet) UpdateName(source *User, contact groupme.Member) bool { newName, quality := puppet.bridge.Config.Bridge.FormatDisplayname(contact) if puppet.Displayname != newName && quality >= puppet.NameQuality { err := puppet.DefaultIntent().SetDisplayName(newName) @@ -284,20 +284,30 @@ func (puppet *Puppet) updatePortalName() { }) } -func (puppet *Puppet) Sync(source *User, contact groupme.User) { +func (puppet *Puppet) Sync(source *User, contact groupme.Member) { + if contact.UserID.String() == "system" { + puppet.log.Warnln("Trying to sync system puppet") + + puppet. + portal.Sync(puppet.bridge.GetUserByJID(portal.Key.Receiver), groupme.Group{}) + //TODO permissoins idk if its fine to use portal owner + + return + } + err := puppet.DefaultIntent().EnsureRegistered() if err != nil { puppet.log.Errorln("Failed to ensure registered:", err) } - if contact.ID.String() == source.JID { - //TODO What is this - // 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, contact.AvatarURL) || update + update = puppet.UpdateAvatar(source, contact.ImageURL) || update if update { puppet.Update() } diff --git a/user.go b/user.go index b394808..90c5848 100644 --- a/user.go +++ b/user.go @@ -799,10 +799,11 @@ func (user *User) handleMessageLoop() { 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, - AvatarURL: msg.data.AvatarURL, + puppet.Sync(user, groupme.Member{ + ID: msg.data.ID, + UserID: msg.data.UserID, + Nickname: msg.data.Name, + ImageURL: msg.data.AvatarURL, }) //TODO: add params or docs? } user.GetPortalByJID(msg.chat).messages <- msg @@ -848,6 +849,11 @@ func (user *User) HandleTextMessage(message groupme.Message) { user.messageInput <- PortalMessage{message.GroupID.String(), user, &message, uint64(message.CreatedAt.ToTime().Unix())} } +func (user *User) HandleJoin(id groupme.ID) { + user.HandleChatList() + //TODO: efficient +} + //func (user *User) HandleImageMessage(message whatsapp.ImageMessage) { // user.messageInput <- PortalMessage{message.Info.RemoteJid, user, message, message.Info.Timestamp} //}