bridge state: set remote name and profile
Signed-off-by: Sumner Evans <sumner.evans@automattic.com>
This commit is contained in:
@@ -12,7 +12,7 @@ require (
|
|||||||
go.uber.org/zap v1.27.0
|
go.uber.org/zap v1.27.0
|
||||||
golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa
|
golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa
|
||||||
golang.org/x/net v0.28.0
|
golang.org/x/net v0.28.0
|
||||||
maunium.net/go/mautrix v0.20.1-0.20240827221252-892e5cf01fc8
|
maunium.net/go/mautrix v0.20.1-0.20240828181422-5f49ca683a3d
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
|||||||
@@ -116,8 +116,8 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
|||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M=
|
maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M=
|
||||||
maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA=
|
maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA=
|
||||||
maunium.net/go/mautrix v0.20.1-0.20240827221252-892e5cf01fc8 h1:k+HkbFrExb508ofb+Snz+yGa1/GQ6WKqyGzGYXSzT3A=
|
maunium.net/go/mautrix v0.20.1-0.20240828181422-5f49ca683a3d h1:JMsmZmi6NnlE0Y6bC81UHCCRLfzovpPZWzI6dDetU54=
|
||||||
maunium.net/go/mautrix v0.20.1-0.20240827221252-892e5cf01fc8/go.mod h1:7hh/Hx5W9lUcqL0hkSw52kMyY+6nMUPTtdDN0qVEXwI=
|
maunium.net/go/mautrix v0.20.1-0.20240828181422-5f49ca683a3d/go.mod h1:7hh/Hx5W9lUcqL0hkSw52kMyY+6nMUPTtdDN0qVEXwI=
|
||||||
nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0=
|
nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0=
|
||||||
nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c=
|
nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c=
|
||||||
rsc.io/qr v0.2.0 h1:6vBLea5/NRMVTz8V66gipeLycZMl/+UlFmk8DvqQ6WY=
|
rsc.io/qr v0.2.0 h1:6vBLea5/NRMVTz8V66gipeLycZMl/+UlFmk8DvqQ6WY=
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ func APICallWithUpdates[U hasUpdates](ctx context.Context, t *TelegramClient, fn
|
|||||||
if !ok {
|
if !ok {
|
||||||
return resp, fmt.Errorf("user is %T not *tg.User", user)
|
return resp, fmt.Errorf("user is %T not *tg.User", user)
|
||||||
}
|
}
|
||||||
err := t.updateGhost(ctx, user.ID, user)
|
_, err := t.updateGhost(ctx, user.ID, user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return resp, err
|
return resp, err
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-2
@@ -393,6 +393,14 @@ func (t *TelegramClient) Connect(ctx context.Context) (err error) {
|
|||||||
t.clientCancel()
|
t.clientCancel()
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
// Update the logged-in user's ghost info (this also updates the user
|
||||||
|
// login's remote name and profile).
|
||||||
|
if me, err := t.client.Self(ctx); err != nil {
|
||||||
|
return fmt.Errorf("failed to get self: %w", err)
|
||||||
|
} else if _, err := t.updateGhost(ctx, t.telegramUserID, me); err != nil {
|
||||||
|
return fmt.Errorf("failed to update ghost: %w", err)
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -427,10 +435,10 @@ func (t *TelegramClient) GetUserInfo(ctx context.Context, ghost *bridgev2.Ghost)
|
|||||||
}
|
}
|
||||||
if user, err := t.getSingleUser(ctx, id); err != nil {
|
if user, err := t.getSingleUser(ctx, id); err != nil {
|
||||||
return nil, fmt.Errorf("failed to get user %d: %w", id, err)
|
return nil, fmt.Errorf("failed to get user %d: %w", id, err)
|
||||||
} else if userInfo, err := t.getUserInfoFromTelegramUser(ctx, user); err != nil {
|
} else if user.TypeID() != tg.UserTypeID {
|
||||||
return nil, err
|
return nil, err
|
||||||
} else {
|
} else {
|
||||||
return userInfo, t.updateGhostWithUserInfo(ctx, id, userInfo)
|
return t.updateGhost(ctx, id, user.(*tg.User))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -60,9 +60,9 @@ func fnSync(ce *commands.Event) {
|
|||||||
ce.Reply("Failed to get your info for %s: %v", login.ID, err)
|
ce.Reply("Failed to get your info for %s: %v", login.ID, err)
|
||||||
} else if len(users) == 0 {
|
} else if len(users) == 0 {
|
||||||
ce.Reply("Failed to get your info for %s: no users returned", login.ID)
|
ce.Reply("Failed to get your info for %s: no users returned", login.ID)
|
||||||
} else if userInfo, err := client.getUserInfoFromTelegramUser(ce.Ctx, users[0]); err != nil {
|
} else if users[0].TypeID() != tg.UserTypeID {
|
||||||
ce.Reply("Failed to get your info for %s: %v", login.ID, err)
|
ce.Reply("Unexpected user type %s", users[0].TypeName())
|
||||||
} else if err = client.updateGhostWithUserInfo(ce.Ctx, client.telegramUserID, userInfo); err != nil {
|
} else if _, err = client.updateGhost(ce.Ctx, client.telegramUserID, users[0].(*tg.User)); err != nil {
|
||||||
ce.Reply("Failed to update your info for %s: %v", login.ID, err)
|
ce.Reply("Failed to update your info for %s: %v", login.ID, err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|||||||
+26
-1
@@ -21,6 +21,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/gotd/td/tg"
|
"github.com/gotd/td/tg"
|
||||||
|
"maunium.net/go/mautrix/bridge/status"
|
||||||
"maunium.net/go/mautrix/bridgev2"
|
"maunium.net/go/mautrix/bridgev2"
|
||||||
"maunium.net/go/mautrix/bridgev2/database"
|
"maunium.net/go/mautrix/bridgev2/database"
|
||||||
|
|
||||||
@@ -85,10 +86,34 @@ func finalizeLogin(ctx context.Context, user *bridgev2.User, authorization *tg.A
|
|||||||
log.Err(err).Msg("Failed to sync chats")
|
log.Err(err).Msg("Failed to sync chats")
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
fullName := util.FormatFullName(me.FirstName, me.LastName)
|
||||||
|
username := me.Username
|
||||||
|
if username == "" && len(me.Usernames) > 0 {
|
||||||
|
username = me.Usernames[0].Username
|
||||||
|
}
|
||||||
|
remoteName := username
|
||||||
|
if remoteName == "" {
|
||||||
|
remoteName = me.Phone
|
||||||
|
}
|
||||||
|
if remoteName == "" {
|
||||||
|
remoteName = fullName
|
||||||
|
}
|
||||||
|
ul.RemoteName = remoteName
|
||||||
|
ul.RemoteProfile = status.RemoteProfile{
|
||||||
|
Phone: me.Phone,
|
||||||
|
Username: username,
|
||||||
|
Name: fullName,
|
||||||
|
}
|
||||||
|
err = ul.Save(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to save login: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
return &bridgev2.LoginStep{
|
return &bridgev2.LoginStep{
|
||||||
Type: bridgev2.LoginStepTypeComplete,
|
Type: bridgev2.LoginStepTypeComplete,
|
||||||
StepID: LoginStepIDComplete,
|
StepID: LoginStepIDComplete,
|
||||||
Instructions: fmt.Sprintf("Successfully logged in as %d / +%s (%s)", me.ID, me.Phone, util.FormatFullName(me.FirstName, me.LastName)),
|
Instructions: fmt.Sprintf("Successfully logged in as %d / +%s (%s)", me.ID, me.Phone, remoteName),
|
||||||
CompleteParams: &bridgev2.LoginCompleteParams{
|
CompleteParams: &bridgev2.LoginCompleteParams{
|
||||||
UserLoginID: ul.ID,
|
UserLoginID: ul.ID,
|
||||||
},
|
},
|
||||||
|
|||||||
+71
-16
@@ -4,10 +4,13 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"slices"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gotd/td/tg"
|
"github.com/gotd/td/tg"
|
||||||
"github.com/rs/zerolog"
|
"github.com/rs/zerolog"
|
||||||
|
"maunium.net/go/mautrix/bridge/status"
|
||||||
"maunium.net/go/mautrix/bridgev2"
|
"maunium.net/go/mautrix/bridgev2"
|
||||||
"maunium.net/go/mautrix/bridgev2/database"
|
"maunium.net/go/mautrix/bridgev2/database"
|
||||||
"maunium.net/go/mautrix/bridgev2/networkid"
|
"maunium.net/go/mautrix/bridgev2/networkid"
|
||||||
@@ -194,6 +197,52 @@ func (t *TelegramClient) getEventSender(msg interface {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *TelegramClient) maybeUpdateRemoteProfile(ctx context.Context, ghost *bridgev2.Ghost, user *tg.User) error {
|
||||||
|
if ghost.ID != t.userID {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var changed bool
|
||||||
|
if user != nil {
|
||||||
|
fullName := util.FormatFullName(user.FirstName, user.LastName)
|
||||||
|
username := user.Username
|
||||||
|
if username == "" && len(user.Usernames) > 0 {
|
||||||
|
username = user.Usernames[0].Username
|
||||||
|
}
|
||||||
|
|
||||||
|
normalizedPhone := "+" + strings.TrimPrefix(user.Phone, "+")
|
||||||
|
remoteName := username
|
||||||
|
if remoteName == "" {
|
||||||
|
remoteName = normalizedPhone
|
||||||
|
}
|
||||||
|
if remoteName == "" {
|
||||||
|
remoteName = fullName
|
||||||
|
}
|
||||||
|
|
||||||
|
changed = t.userLogin.RemoteName != remoteName ||
|
||||||
|
t.userLogin.RemoteProfile.Phone != normalizedPhone ||
|
||||||
|
t.userLogin.RemoteProfile.Username != username ||
|
||||||
|
t.userLogin.RemoteProfile.Name != fullName
|
||||||
|
t.userLogin.RemoteName = remoteName
|
||||||
|
t.userLogin.RemoteProfile.Phone = normalizedPhone
|
||||||
|
t.userLogin.RemoteProfile.Username = username
|
||||||
|
t.userLogin.RemoteProfile.Name = fullName
|
||||||
|
} else {
|
||||||
|
changed = t.userLogin.RemoteName != ghost.Name
|
||||||
|
t.userLogin.RemoteProfile.Name = ghost.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
changed = changed || t.userLogin.RemoteProfile.Avatar != ghost.AvatarMXC
|
||||||
|
t.userLogin.RemoteProfile.Avatar = ghost.AvatarMXC
|
||||||
|
if changed {
|
||||||
|
if err := t.userLogin.Save(ctx); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
t.userLogin.BridgeState.Send(status.BridgeState{StateEvent: status.StateConnected})
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (t *TelegramClient) onUserName(ctx context.Context, e tg.Entities, update *tg.UpdateUserName) error {
|
func (t *TelegramClient) onUserName(ctx context.Context, e tg.Entities, update *tg.UpdateUserName) error {
|
||||||
ghost, err := t.main.Bridge.GetGhostByID(ctx, ids.MakeUserID(update.UserID))
|
ghost, err := t.main.Bridge.GetGhostByID(ctx, ids.MakeUserID(update.UserID))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -201,10 +250,25 @@ func (t *TelegramClient) onUserName(ctx context.Context, e tg.Entities, update *
|
|||||||
}
|
}
|
||||||
|
|
||||||
name := util.FormatFullName(update.FirstName, update.LastName)
|
name := util.FormatFullName(update.FirstName, update.LastName)
|
||||||
|
userInfo := bridgev2.UserInfo{Name: &name}
|
||||||
|
|
||||||
// TODO update identifiers?
|
if len(update.Usernames) > 0 {
|
||||||
ghost.UpdateInfo(ctx, &bridgev2.UserInfo{Name: &name})
|
for _, ident := range ghost.Identifiers {
|
||||||
return nil
|
if !strings.HasPrefix(ident, "telegram:") {
|
||||||
|
userInfo.Identifiers = append(userInfo.Identifiers, ident)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, username := range update.Usernames {
|
||||||
|
userInfo.Identifiers = append(userInfo.Identifiers, fmt.Sprintf("telegram:%s", username.Username))
|
||||||
|
}
|
||||||
|
|
||||||
|
slices.Sort(userInfo.Identifiers)
|
||||||
|
userInfo.Identifiers = slices.Compact(userInfo.Identifiers)
|
||||||
|
}
|
||||||
|
|
||||||
|
ghost.UpdateInfo(ctx, &userInfo)
|
||||||
|
return t.maybeUpdateRemoteProfile(ctx, ghost, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TelegramClient) onDeleteMessages(ctx context.Context, channelID int64, update IGetMessages) error {
|
func (t *TelegramClient) onDeleteMessages(ctx context.Context, channelID int64, update IGetMessages) error {
|
||||||
@@ -241,26 +305,17 @@ func (t *TelegramClient) onDeleteMessages(ctx context.Context, channelID int64,
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TelegramClient) updateGhost(ctx context.Context, userID int64, user *tg.User) error {
|
func (t *TelegramClient) updateGhost(ctx context.Context, userID int64, user *tg.User) (*bridgev2.UserInfo, error) {
|
||||||
ghost, err := t.main.Bridge.GetGhostByID(ctx, ids.MakeUserID(userID))
|
ghost, err := t.main.Bridge.GetGhostByID(ctx, ids.MakeUserID(userID))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
userInfo, err := t.getUserInfoFromTelegramUser(ctx, user)
|
userInfo, err := t.getUserInfoFromTelegramUser(ctx, user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
ghost.UpdateInfo(ctx, userInfo)
|
ghost.UpdateInfo(ctx, userInfo)
|
||||||
return nil
|
return userInfo, t.maybeUpdateRemoteProfile(ctx, ghost, user)
|
||||||
}
|
|
||||||
|
|
||||||
func (t *TelegramClient) updateGhostWithUserInfo(ctx context.Context, userID int64, userInfo *bridgev2.UserInfo) error {
|
|
||||||
ghost, err := t.main.Bridge.GetGhostByID(ctx, ids.MakeUserID(userID))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
ghost.UpdateInfo(ctx, userInfo)
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TelegramClient) onEntityUpdate(ctx context.Context, e tg.Entities) error {
|
func (t *TelegramClient) onEntityUpdate(ctx context.Context, e tg.Entities) error {
|
||||||
|
|||||||
Reference in New Issue
Block a user