Set room avatar for DM portals
This commit is contained in:
parent
a415444fc0
commit
95c0cfa983
6 changed files with 85 additions and 23 deletions
|
@ -55,6 +55,10 @@ func (pq *PortalQuery) GetByKey(ctx context.Context, key Key) (*Portal, error) {
|
|||
return get[*Portal](pq, ctx, "SELECT id, receiver, self_user, other_user, type, mxid, name, name_set, encrypted, in_space FROM portal WHERE id=$1 AND receiver=$2", key.ID, key.Receiver)
|
||||
}
|
||||
|
||||
func (pq *PortalQuery) GetByOtherUser(ctx context.Context, key Key) (*Portal, error) {
|
||||
return get[*Portal](pq, ctx, "SELECT id, receiver, self_user, other_user, type, mxid, name, name_set, encrypted, in_space FROM portal WHERE other_user=$1 AND receiver=$2", key.ID, key.Receiver)
|
||||
}
|
||||
|
||||
func (pq *PortalQuery) GetByMXID(ctx context.Context, mxid id.RoomID) (*Portal, error) {
|
||||
return get[*Portal](pq, ctx, "SELECT id, receiver, self_user, other_user, type, mxid, name, name_set, encrypted, in_space FROM portal WHERE mxid=$1", mxid)
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
-- v0 -> v6: Latest revision
|
||||
-- v0 -> v8: Latest revision
|
||||
|
||||
CREATE TABLE "user" (
|
||||
-- only: postgres
|
||||
|
@ -54,6 +54,7 @@ CREATE TABLE portal (
|
|||
CONSTRAINT portal_user_fkey FOREIGN KEY (receiver) REFERENCES "user"(rowid) ON DELETE CASCADE,
|
||||
CONSTRAINT portal_puppet_fkey FOREIGN KEY (other_user, receiver) REFERENCES puppet(id, receiver) ON DELETE CASCADE
|
||||
);
|
||||
CREATE INDEX ON portal(receiver, other_user);
|
||||
|
||||
CREATE TABLE message (
|
||||
conv_id TEXT NOT NULL,
|
||||
|
|
2
database/upgrades/08-portal-other-user-idx.sql
Normal file
2
database/upgrades/08-portal-other-user-idx.sql
Normal file
|
@ -0,0 +1,2 @@
|
|||
-- v8: Add index for DM portals
|
||||
CREATE INDEX ON portal(receiver, other_user);
|
18
main.go
18
main.go
|
@ -57,6 +57,7 @@ type GMBridge struct {
|
|||
managementRoomsLock sync.Mutex
|
||||
portalsByMXID map[id.RoomID]*Portal
|
||||
portalsByKey map[database.Key]*Portal
|
||||
portalsByOtherUser map[database.Key]*Portal
|
||||
portalsLock sync.Mutex
|
||||
puppetsByKey map[database.Key]*Puppet
|
||||
puppetsLock sync.Mutex
|
||||
|
@ -153,12 +154,13 @@ func (br *GMBridge) GetConfigPtr() interface{} {
|
|||
|
||||
func main() {
|
||||
br := &GMBridge{
|
||||
usersByMXID: make(map[id.UserID]*User),
|
||||
spaceRooms: make(map[id.RoomID]*User),
|
||||
managementRooms: make(map[id.RoomID]*User),
|
||||
portalsByMXID: make(map[id.RoomID]*Portal),
|
||||
portalsByKey: make(map[database.Key]*Portal),
|
||||
puppetsByKey: make(map[database.Key]*Puppet),
|
||||
usersByMXID: make(map[id.UserID]*User),
|
||||
spaceRooms: make(map[id.RoomID]*User),
|
||||
managementRooms: make(map[id.RoomID]*User),
|
||||
portalsByMXID: make(map[id.RoomID]*Portal),
|
||||
portalsByKey: make(map[database.Key]*Portal),
|
||||
portalsByOtherUser: make(map[database.Key]*Portal),
|
||||
puppetsByKey: make(map[database.Key]*Puppet),
|
||||
}
|
||||
br.Bridge = bridge.Bridge{
|
||||
Name: "mautrix-gmessages",
|
||||
|
@ -166,8 +168,8 @@ func main() {
|
|||
Description: "A Matrix-Google Messages puppeting bridge.",
|
||||
Version: "0.1.0",
|
||||
ProtocolName: "Google Messages",
|
||||
BeeperServiceName: "googlesms",
|
||||
BeeperNetworkName: "googlesms",
|
||||
BeeperServiceName: "gmessages",
|
||||
BeeperNetworkName: "gmessages",
|
||||
|
||||
CryptoPickleKey: "go.mau.fi/mautrix-gmessages",
|
||||
|
||||
|
|
51
portal.go
51
portal.go
|
@ -106,6 +106,27 @@ func (br *GMBridge) GetPortalByKey(key database.Key) *Portal {
|
|||
return portal
|
||||
}
|
||||
|
||||
func (br *GMBridge) GetPortalByOtherUser(key database.Key) *Portal {
|
||||
br.portalsLock.Lock()
|
||||
defer br.portalsLock.Unlock()
|
||||
portal, ok := br.portalsByOtherUser[key]
|
||||
if !ok {
|
||||
dbPortal, err := br.DB.Portal.GetByKey(context.TODO(), key)
|
||||
if err != nil {
|
||||
br.ZLog.Err(err).Object("portal_key", key).Msg("Failed to get portal from database")
|
||||
return nil
|
||||
}
|
||||
if dbPortal != nil {
|
||||
existingPortal, ok := br.portalsByKey[dbPortal.Key]
|
||||
if ok {
|
||||
return existingPortal
|
||||
}
|
||||
}
|
||||
return br.loadDBPortal(dbPortal, nil)
|
||||
}
|
||||
return portal
|
||||
}
|
||||
|
||||
func (br *GMBridge) GetExistingPortalByKey(key database.Key) *Portal {
|
||||
br.portalsLock.Lock()
|
||||
defer br.portalsLock.Unlock()
|
||||
|
@ -180,6 +201,9 @@ func (br *GMBridge) loadDBPortal(dbPortal *database.Portal, key *database.Key) *
|
|||
if len(portal.MXID) > 0 {
|
||||
br.portalsByMXID[portal.MXID] = portal
|
||||
}
|
||||
if len(portal.OtherUserID) > 0 {
|
||||
br.portalsByOtherUser[database.Key{ID: portal.OtherUserID, Receiver: portal.Receiver}] = portal
|
||||
}
|
||||
return portal
|
||||
}
|
||||
|
||||
|
@ -1241,6 +1265,12 @@ func (portal *Portal) SyncParticipants(source *User, metadata *gmproto.Conversat
|
|||
Str("new_other_user_id", firstParticipant.ID.ParticipantID).
|
||||
Msg("Found other user ID in DM")
|
||||
portal.OtherUserID = firstParticipant.ID.ParticipantID
|
||||
portal.bridge.portalsLock.Lock()
|
||||
portal.bridge.portalsByOtherUser[database.Key{
|
||||
ID: portal.OtherUserID,
|
||||
Receiver: portal.Receiver,
|
||||
}] = portal
|
||||
portal.bridge.portalsLock.Unlock()
|
||||
changed = true
|
||||
}
|
||||
if portal.MXID != "" {
|
||||
|
@ -1486,10 +1516,17 @@ func (portal *Portal) CreateMatrixRoom(user *User, conv *gmproto.Conversation, i
|
|||
}
|
||||
|
||||
members := portal.UpdateMetadata(user, conv)
|
||||
var avatarURL id.ContentURI
|
||||
|
||||
if portal.IsPrivateChat() && portal.GetDMPuppet() == nil {
|
||||
portal.zlog.Error().Msg("Didn't find ghost of other user in DM :(")
|
||||
return fmt.Errorf("ghost not found")
|
||||
if portal.IsPrivateChat() {
|
||||
puppet := portal.GetDMPuppet()
|
||||
if puppet == nil {
|
||||
portal.zlog.Error().Msg("Didn't find ghost of other user in DM :(")
|
||||
return fmt.Errorf("ghost not found")
|
||||
}
|
||||
if portal.shouldSetDMRoomMetadata() {
|
||||
avatarURL = puppet.AvatarMXC
|
||||
}
|
||||
}
|
||||
|
||||
intent := portal.MainIntent()
|
||||
|
@ -1530,6 +1567,14 @@ func (portal *Portal) CreateMatrixRoom(user *User, conv *gmproto.Conversation, i
|
|||
invite = append(invite, portal.bridge.Bot.UserID)
|
||||
}
|
||||
}
|
||||
if !avatarURL.IsEmpty() {
|
||||
initialState = append(initialState, &event.Event{
|
||||
Type: event.StateRoomAvatar,
|
||||
Content: event.Content{
|
||||
Parsed: &event.RoomAvatarEventContent{URL: avatarURL},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
creationContent := make(map[string]interface{})
|
||||
if !portal.bridge.Config.Bridge.FederateRooms {
|
||||
|
|
30
puppet.go
30
puppet.go
|
@ -214,7 +214,8 @@ func (puppet *Puppet) UpdateAvatar(source *User) bool {
|
|||
}
|
||||
puppet.AvatarUpdateTS = time.Now()
|
||||
if len(resp.Thumbnail) == 0 {
|
||||
if puppet.AvatarHash == [32]byte{} {
|
||||
if puppet.AvatarHash == [32]byte{} && puppet.AvatarMXC.IsEmpty() {
|
||||
puppet.AvatarSet = true
|
||||
return true
|
||||
}
|
||||
puppet.AvatarHash = [32]byte{}
|
||||
|
@ -223,7 +224,7 @@ func (puppet *Puppet) UpdateAvatar(source *User) bool {
|
|||
} else {
|
||||
thumbData := resp.Thumbnail[0].GetData()
|
||||
hash := sha256.Sum256(thumbData.GetImageBuffer())
|
||||
if hash == puppet.AvatarHash {
|
||||
if hash == puppet.AvatarHash && puppet.AvatarSet {
|
||||
return true
|
||||
}
|
||||
puppet.AvatarHash = hash
|
||||
|
@ -249,6 +250,22 @@ func (puppet *Puppet) UpdateAvatar(source *User) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
func (puppet *Puppet) updatePortalAvatar() {
|
||||
portal := puppet.bridge.GetPortalByOtherUser(puppet.Key)
|
||||
if portal == nil {
|
||||
return
|
||||
}
|
||||
portal.roomCreateLock.Lock()
|
||||
defer portal.roomCreateLock.Unlock()
|
||||
if portal.MXID == "" || !portal.shouldSetDMRoomMetadata() {
|
||||
return
|
||||
}
|
||||
_, err := portal.MainIntent().SetRoomAvatar(portal.MXID, puppet.AvatarMXC)
|
||||
if err != nil {
|
||||
puppet.log.Err(err).Str("room_id", portal.MXID.String()).Msg("Failed to update DM room avatar")
|
||||
}
|
||||
}
|
||||
|
||||
func (puppet *Puppet) UpdateName(formattedPhone, fullName, firstName string) bool {
|
||||
newName := puppet.bridge.Config.Bridge.FormatDisplayname(formattedPhone, fullName, firstName)
|
||||
if puppet.Name != newName || !puppet.NameSet {
|
||||
|
@ -259,7 +276,6 @@ func (puppet *Puppet) UpdateName(formattedPhone, fullName, firstName string) boo
|
|||
if err == nil {
|
||||
puppet.log.Debug().Str("old_name", oldName).Str("new_name", newName).Msg("Updated displayname")
|
||||
puppet.NameSet = true
|
||||
go puppet.updatePortalName()
|
||||
} else {
|
||||
puppet.log.Warn().Err(err).Msg("Failed to set displayname")
|
||||
}
|
||||
|
@ -296,14 +312,6 @@ func (puppet *Puppet) UpdateContactInfo() bool {
|
|||
}
|
||||
}
|
||||
|
||||
func (puppet *Puppet) updatePortalAvatar() {
|
||||
// TODO implement
|
||||
}
|
||||
|
||||
func (puppet *Puppet) updatePortalName() {
|
||||
// TODO implement
|
||||
}
|
||||
|
||||
func (puppet *Puppet) Sync(source *User, contact *gmproto.Participant) {
|
||||
err := puppet.DefaultIntent().EnsureRegistered()
|
||||
if err != nil {
|
||||
|
|
Loading…
Reference in a new issue