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)
|
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) {
|
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)
|
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" (
|
CREATE TABLE "user" (
|
||||||
-- only: postgres
|
-- only: postgres
|
||||||
|
@ -54,6 +54,7 @@ CREATE TABLE portal (
|
||||||
CONSTRAINT portal_user_fkey FOREIGN KEY (receiver) REFERENCES "user"(rowid) ON DELETE CASCADE,
|
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
|
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 (
|
CREATE TABLE message (
|
||||||
conv_id TEXT NOT NULL,
|
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
|
managementRoomsLock sync.Mutex
|
||||||
portalsByMXID map[id.RoomID]*Portal
|
portalsByMXID map[id.RoomID]*Portal
|
||||||
portalsByKey map[database.Key]*Portal
|
portalsByKey map[database.Key]*Portal
|
||||||
|
portalsByOtherUser map[database.Key]*Portal
|
||||||
portalsLock sync.Mutex
|
portalsLock sync.Mutex
|
||||||
puppetsByKey map[database.Key]*Puppet
|
puppetsByKey map[database.Key]*Puppet
|
||||||
puppetsLock sync.Mutex
|
puppetsLock sync.Mutex
|
||||||
|
@ -153,12 +154,13 @@ func (br *GMBridge) GetConfigPtr() interface{} {
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
br := &GMBridge{
|
br := &GMBridge{
|
||||||
usersByMXID: make(map[id.UserID]*User),
|
usersByMXID: make(map[id.UserID]*User),
|
||||||
spaceRooms: make(map[id.RoomID]*User),
|
spaceRooms: make(map[id.RoomID]*User),
|
||||||
managementRooms: make(map[id.RoomID]*User),
|
managementRooms: make(map[id.RoomID]*User),
|
||||||
portalsByMXID: make(map[id.RoomID]*Portal),
|
portalsByMXID: make(map[id.RoomID]*Portal),
|
||||||
portalsByKey: make(map[database.Key]*Portal),
|
portalsByKey: make(map[database.Key]*Portal),
|
||||||
puppetsByKey: make(map[database.Key]*Puppet),
|
portalsByOtherUser: make(map[database.Key]*Portal),
|
||||||
|
puppetsByKey: make(map[database.Key]*Puppet),
|
||||||
}
|
}
|
||||||
br.Bridge = bridge.Bridge{
|
br.Bridge = bridge.Bridge{
|
||||||
Name: "mautrix-gmessages",
|
Name: "mautrix-gmessages",
|
||||||
|
@ -166,8 +168,8 @@ func main() {
|
||||||
Description: "A Matrix-Google Messages puppeting bridge.",
|
Description: "A Matrix-Google Messages puppeting bridge.",
|
||||||
Version: "0.1.0",
|
Version: "0.1.0",
|
||||||
ProtocolName: "Google Messages",
|
ProtocolName: "Google Messages",
|
||||||
BeeperServiceName: "googlesms",
|
BeeperServiceName: "gmessages",
|
||||||
BeeperNetworkName: "googlesms",
|
BeeperNetworkName: "gmessages",
|
||||||
|
|
||||||
CryptoPickleKey: "go.mau.fi/mautrix-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
|
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 {
|
func (br *GMBridge) GetExistingPortalByKey(key database.Key) *Portal {
|
||||||
br.portalsLock.Lock()
|
br.portalsLock.Lock()
|
||||||
defer br.portalsLock.Unlock()
|
defer br.portalsLock.Unlock()
|
||||||
|
@ -180,6 +201,9 @@ func (br *GMBridge) loadDBPortal(dbPortal *database.Portal, key *database.Key) *
|
||||||
if len(portal.MXID) > 0 {
|
if len(portal.MXID) > 0 {
|
||||||
br.portalsByMXID[portal.MXID] = portal
|
br.portalsByMXID[portal.MXID] = portal
|
||||||
}
|
}
|
||||||
|
if len(portal.OtherUserID) > 0 {
|
||||||
|
br.portalsByOtherUser[database.Key{ID: portal.OtherUserID, Receiver: portal.Receiver}] = portal
|
||||||
|
}
|
||||||
return portal
|
return portal
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1241,6 +1265,12 @@ func (portal *Portal) SyncParticipants(source *User, metadata *gmproto.Conversat
|
||||||
Str("new_other_user_id", firstParticipant.ID.ParticipantID).
|
Str("new_other_user_id", firstParticipant.ID.ParticipantID).
|
||||||
Msg("Found other user ID in DM")
|
Msg("Found other user ID in DM")
|
||||||
portal.OtherUserID = firstParticipant.ID.ParticipantID
|
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
|
changed = true
|
||||||
}
|
}
|
||||||
if portal.MXID != "" {
|
if portal.MXID != "" {
|
||||||
|
@ -1486,10 +1516,17 @@ func (portal *Portal) CreateMatrixRoom(user *User, conv *gmproto.Conversation, i
|
||||||
}
|
}
|
||||||
|
|
||||||
members := portal.UpdateMetadata(user, conv)
|
members := portal.UpdateMetadata(user, conv)
|
||||||
|
var avatarURL id.ContentURI
|
||||||
|
|
||||||
if portal.IsPrivateChat() && portal.GetDMPuppet() == nil {
|
if portal.IsPrivateChat() {
|
||||||
portal.zlog.Error().Msg("Didn't find ghost of other user in DM :(")
|
puppet := portal.GetDMPuppet()
|
||||||
return fmt.Errorf("ghost not found")
|
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()
|
intent := portal.MainIntent()
|
||||||
|
@ -1530,6 +1567,14 @@ func (portal *Portal) CreateMatrixRoom(user *User, conv *gmproto.Conversation, i
|
||||||
invite = append(invite, portal.bridge.Bot.UserID)
|
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{})
|
creationContent := make(map[string]interface{})
|
||||||
if !portal.bridge.Config.Bridge.FederateRooms {
|
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()
|
puppet.AvatarUpdateTS = time.Now()
|
||||||
if len(resp.Thumbnail) == 0 {
|
if len(resp.Thumbnail) == 0 {
|
||||||
if puppet.AvatarHash == [32]byte{} {
|
if puppet.AvatarHash == [32]byte{} && puppet.AvatarMXC.IsEmpty() {
|
||||||
|
puppet.AvatarSet = true
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
puppet.AvatarHash = [32]byte{}
|
puppet.AvatarHash = [32]byte{}
|
||||||
|
@ -223,7 +224,7 @@ func (puppet *Puppet) UpdateAvatar(source *User) bool {
|
||||||
} else {
|
} else {
|
||||||
thumbData := resp.Thumbnail[0].GetData()
|
thumbData := resp.Thumbnail[0].GetData()
|
||||||
hash := sha256.Sum256(thumbData.GetImageBuffer())
|
hash := sha256.Sum256(thumbData.GetImageBuffer())
|
||||||
if hash == puppet.AvatarHash {
|
if hash == puppet.AvatarHash && puppet.AvatarSet {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
puppet.AvatarHash = hash
|
puppet.AvatarHash = hash
|
||||||
|
@ -249,6 +250,22 @@ func (puppet *Puppet) UpdateAvatar(source *User) bool {
|
||||||
return true
|
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 {
|
func (puppet *Puppet) UpdateName(formattedPhone, fullName, firstName string) bool {
|
||||||
newName := puppet.bridge.Config.Bridge.FormatDisplayname(formattedPhone, fullName, firstName)
|
newName := puppet.bridge.Config.Bridge.FormatDisplayname(formattedPhone, fullName, firstName)
|
||||||
if puppet.Name != newName || !puppet.NameSet {
|
if puppet.Name != newName || !puppet.NameSet {
|
||||||
|
@ -259,7 +276,6 @@ func (puppet *Puppet) UpdateName(formattedPhone, fullName, firstName string) boo
|
||||||
if err == nil {
|
if err == nil {
|
||||||
puppet.log.Debug().Str("old_name", oldName).Str("new_name", newName).Msg("Updated displayname")
|
puppet.log.Debug().Str("old_name", oldName).Str("new_name", newName).Msg("Updated displayname")
|
||||||
puppet.NameSet = true
|
puppet.NameSet = true
|
||||||
go puppet.updatePortalName()
|
|
||||||
} else {
|
} else {
|
||||||
puppet.log.Warn().Err(err).Msg("Failed to set displayname")
|
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) {
|
func (puppet *Puppet) Sync(source *User, contact *gmproto.Participant) {
|
||||||
err := puppet.DefaultIntent().EnsureRegistered()
|
err := puppet.DefaultIntent().EnsureRegistered()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
Loading…
Reference in a new issue