mirror of
https://github.com/mautrix/telegram.git
synced 2026-05-17 07:25:46 +03:00
@@ -47,7 +47,6 @@ import (
|
||||
"go.mau.fi/mautrix-telegram/pkg/connector/matrixfmt"
|
||||
"go.mau.fi/mautrix-telegram/pkg/connector/store"
|
||||
"go.mau.fi/mautrix-telegram/pkg/connector/telegramfmt"
|
||||
"go.mau.fi/mautrix-telegram/pkg/connector/util"
|
||||
"go.mau.fi/mautrix-telegram/pkg/gotd/telegram"
|
||||
"go.mau.fi/mautrix-telegram/pkg/gotd/telegram/auth"
|
||||
"go.mau.fi/mautrix-telegram/pkg/gotd/telegram/updates"
|
||||
@@ -430,12 +429,12 @@ func (t *TelegramClient) onPing() {
|
||||
}
|
||||
}
|
||||
|
||||
func userToRemoteProfile(
|
||||
func (t *TelegramConnector) userToRemoteProfile(
|
||||
self *tg.User,
|
||||
ghost *bridgev2.Ghost,
|
||||
prevState *status.RemoteProfile,
|
||||
) (profile status.RemoteProfile, name string) {
|
||||
profile.Name = util.FormatFullName(self.FirstName, self.LastName, self.Deleted, self.ID)
|
||||
profile.Name = t.Config.FormatDisplayname(self.FirstName, self.LastName, self.Username, self.Deleted, self.ID)
|
||||
if self.Phone != "" {
|
||||
profile.Phone = "+" + strings.TrimPrefix(self.Phone, "+")
|
||||
} else if prevState != nil {
|
||||
@@ -455,7 +454,7 @@ func userToRemoteProfile(
|
||||
}
|
||||
|
||||
func (t *TelegramClient) updateRemoteProfile(ctx context.Context, self *tg.User, ghost *bridgev2.Ghost) bool {
|
||||
newProfile, newName := userToRemoteProfile(self, ghost, &t.userLogin.RemoteProfile)
|
||||
newProfile, newName := t.main.userToRemoteProfile(self, ghost, &t.userLogin.RemoteProfile)
|
||||
if t.userLogin.RemoteProfile != newProfile || t.userLogin.RemoteName != newName {
|
||||
t.userLogin.RemoteProfile = newProfile
|
||||
t.userLogin.RemoteName = newName
|
||||
|
||||
@@ -20,8 +20,11 @@ import (
|
||||
_ "embed"
|
||||
"fmt"
|
||||
"slices"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
up "go.mau.fi/util/configupgrade"
|
||||
"gopkg.in/yaml.v3"
|
||||
"maunium.net/go/mautrix/bridgev2"
|
||||
"maunium.net/go/mautrix/bridgev2/bridgeconfig"
|
||||
"maunium.net/go/mautrix/id"
|
||||
@@ -86,12 +89,55 @@ type TelegramConfig struct {
|
||||
AlwaysTombstoneOnSupergroupMigration bool `yaml:"always_tombstone_on_supergroup_migration"`
|
||||
ImageAsFilePixels int `yaml:"image_as_file_pixels"`
|
||||
DisableViewOnce bool `yaml:"disable_view_once"`
|
||||
DisplaynameTemplate string `yaml:"displayname_template"`
|
||||
displaynameTemplate *template.Template `yaml:"-"`
|
||||
}
|
||||
|
||||
func (c TelegramConfig) ShouldBridge(participantCount int) bool {
|
||||
return c.MaxMemberCount < 0 || participantCount <= c.MaxMemberCount
|
||||
}
|
||||
|
||||
type DisplaynameParams struct {
|
||||
FullName string
|
||||
FirstName string
|
||||
LastName string
|
||||
Username string
|
||||
UserID int64
|
||||
Deleted bool
|
||||
}
|
||||
|
||||
func (c *TelegramConfig) FormatDisplayname(firstName, lastName, username string, deleted bool, userID int64) string {
|
||||
var buf strings.Builder
|
||||
err := c.displaynameTemplate.Execute(&buf, DisplaynameParams{
|
||||
FullName: strings.TrimSpace(firstName + " " + lastName),
|
||||
FirstName: firstName,
|
||||
LastName: lastName,
|
||||
Username: username,
|
||||
UserID: userID,
|
||||
Deleted: deleted,
|
||||
})
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("displayname template is broken: %w", err))
|
||||
}
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
type umConfig TelegramConfig
|
||||
|
||||
func (c *TelegramConfig) UnmarshalYAML(node *yaml.Node) error {
|
||||
err := node.Decode((*umConfig)(c))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return c.PostProcess()
|
||||
}
|
||||
|
||||
func (c *TelegramConfig) PostProcess() error {
|
||||
var err error
|
||||
c.displaynameTemplate, err = template.New("displayname").Parse(c.DisplaynameTemplate)
|
||||
return err
|
||||
}
|
||||
|
||||
//go:embed example-config.yaml
|
||||
var ExampleConfig string
|
||||
|
||||
@@ -130,6 +176,7 @@ func upgradeConfig(helper up.Helper) {
|
||||
helper.Copy(up.Bool, "always_tombstone_on_supergroup_migration")
|
||||
helper.Copy(up.Int, "image_as_file_pixels")
|
||||
helper.Copy(up.Bool, "disable_view_once")
|
||||
helper.Copy(up.Str, "displayname_template")
|
||||
}
|
||||
|
||||
func (tg *TelegramConnector) GetConfig() (example string, data any, upgrader up.Upgrader) {
|
||||
|
||||
@@ -104,3 +104,11 @@ always_tombstone_on_supergroup_migration: false
|
||||
image_as_file_pixels: 16777216
|
||||
# Should view-once messages be disabled entirely?
|
||||
disable_view_once: false
|
||||
# Displayname template for Telegram users.
|
||||
# {{ .FullName }} - the full name of the Telegram user
|
||||
# {{ .FirstName }} - the first name of the Telegram user
|
||||
# {{ .LastName }} - the last name of the Telegram user
|
||||
# {{ .Username }} - the primary username of the Telegram user, if the user has one
|
||||
# {{ .UserID }} - the internal user ID of the Telegram user
|
||||
# {{ .Deleted }} - true if the user has been deleted, false otherwise
|
||||
displayname_template: "{{ if .Deleted }}Deleted account {{ .UserID }}{{ else }}{{ .FullName }}{{ end }}"
|
||||
|
||||
@@ -42,7 +42,6 @@ import (
|
||||
"go.mau.fi/mautrix-telegram/pkg/connector/media"
|
||||
"go.mau.fi/mautrix-telegram/pkg/connector/store"
|
||||
"go.mau.fi/mautrix-telegram/pkg/connector/tljson"
|
||||
"go.mau.fi/mautrix-telegram/pkg/connector/util"
|
||||
"go.mau.fi/mautrix-telegram/pkg/gotd/tg"
|
||||
"go.mau.fi/mautrix-telegram/pkg/gotd/tgerr"
|
||||
)
|
||||
@@ -728,13 +727,7 @@ func (t *TelegramClient) onUserName(ctx context.Context, e tg.Entities, update *
|
||||
|
||||
var userInfo bridgev2.UserInfo
|
||||
|
||||
name := util.FormatFullName(update.FirstName, update.LastName, false, update.UserID)
|
||||
userInfo.Name = &name
|
||||
if meta.ContactSource != 0 && meta.ContactSource != t.telegramUserID && !t.main.Config.ContactNames {
|
||||
// TODO fetch full info to accurately detect if the user is a contact or not
|
||||
userInfo.Name = nil
|
||||
}
|
||||
|
||||
var firstUsername string
|
||||
if len(update.Usernames) > 0 {
|
||||
for _, ident := range ghost.Identifiers {
|
||||
if !strings.HasPrefix(ident, "telegram:") {
|
||||
@@ -742,7 +735,10 @@ func (t *TelegramClient) onUserName(ctx context.Context, e tg.Entities, update *
|
||||
}
|
||||
}
|
||||
|
||||
for _, username := range update.Usernames {
|
||||
for i, username := range update.Usernames {
|
||||
if i == 0 {
|
||||
firstUsername = username.Username
|
||||
}
|
||||
userInfo.Identifiers = append(userInfo.Identifiers, fmt.Sprintf("telegram:%s", username.Username))
|
||||
}
|
||||
|
||||
@@ -750,6 +746,13 @@ func (t *TelegramClient) onUserName(ctx context.Context, e tg.Entities, update *
|
||||
userInfo.Identifiers = slices.Compact(userInfo.Identifiers)
|
||||
}
|
||||
|
||||
name := t.main.Config.FormatDisplayname(update.FirstName, update.LastName, firstUsername, false, update.UserID)
|
||||
userInfo.Name = &name
|
||||
if meta.ContactSource != 0 && meta.ContactSource != t.telegramUserID && !t.main.Config.ContactNames {
|
||||
// TODO fetch full info to accurately detect if the user is a contact or not
|
||||
userInfo.Name = nil
|
||||
}
|
||||
|
||||
ghost.UpdateInfo(ctx, &userInfo)
|
||||
if ghost.ID == t.userID {
|
||||
var firstUsername string
|
||||
|
||||
@@ -216,7 +216,7 @@ func (bl *baseLogin) finalizeLogin(
|
||||
}
|
||||
metadata.Session = bl.session
|
||||
metadata.LoginMethod = bl.flowID
|
||||
profile, name := userToRemoteProfile(self, nil, nil)
|
||||
profile, name := bl.main.userToRemoteProfile(self, nil, nil)
|
||||
userLoginID := ids.MakeUserLoginID(authorization.User.GetID())
|
||||
ul, err := bl.user.NewLogin(ctx, &database.UserLogin{
|
||||
ID: userLoginID,
|
||||
|
||||
@@ -41,7 +41,6 @@ import (
|
||||
"go.mau.fi/mautrix-telegram/pkg/connector/media"
|
||||
"go.mau.fi/mautrix-telegram/pkg/connector/store"
|
||||
"go.mau.fi/mautrix-telegram/pkg/connector/telegramfmt"
|
||||
"go.mau.fi/mautrix-telegram/pkg/connector/util"
|
||||
"go.mau.fi/mautrix-telegram/pkg/connector/waveform"
|
||||
"go.mau.fi/mautrix-telegram/pkg/gotd/tg"
|
||||
"go.mau.fi/mautrix-telegram/pkg/gotd/tgerr"
|
||||
@@ -729,7 +728,7 @@ func (c *TelegramClient) convertMediaRequiringUpload(
|
||||
|
||||
func (c *TelegramClient) convertContact(media tg.MessageMediaClass) *bridgev2.ConvertedMessagePart {
|
||||
contact := media.(*tg.MessageMediaContact)
|
||||
name := util.FormatFullName(contact.FirstName, contact.LastName, false, contact.UserID)
|
||||
name := c.main.Config.FormatDisplayname(contact.FirstName, contact.LastName, "", false, contact.UserID)
|
||||
formattedPhone := fmt.Sprintf("+%s", strings.TrimPrefix(contact.PhoneNumber, "+"))
|
||||
|
||||
content := event.MessageEventContent{
|
||||
|
||||
@@ -13,7 +13,6 @@ import (
|
||||
|
||||
"go.mau.fi/mautrix-telegram/pkg/connector/ids"
|
||||
"go.mau.fi/mautrix-telegram/pkg/connector/store"
|
||||
"go.mau.fi/mautrix-telegram/pkg/connector/util"
|
||||
"go.mau.fi/mautrix-telegram/pkg/gotd/tg"
|
||||
)
|
||||
|
||||
@@ -258,7 +257,7 @@ func (t *TelegramClient) wrapUserInfo(ctx context.Context, u tg.UserClass, ghost
|
||||
}
|
||||
}
|
||||
|
||||
name := util.FormatFullName(user.FirstName, user.LastName, user.Deleted, user.ID)
|
||||
name := t.main.Config.FormatDisplayname(user.FirstName, user.LastName, user.Username, user.Deleted, user.ID)
|
||||
namePtr := &name
|
||||
if user.Contact && ghost.Name != "" && oldMeta.ContactSource != t.telegramUserID && oldMeta.ContactSource != 0 && !t.main.Config.ContactNames {
|
||||
namePtr = nil
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
// mautrix-telegram - A Matrix-Telegram puppeting bridge.
|
||||
// Copyright (C) 2025 Sumner Evans
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
package util
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func FormatFullName(first, last string, deleted bool, userID int64) string {
|
||||
if deleted {
|
||||
return fmt.Sprintf("Deleted account %d", userID)
|
||||
}
|
||||
return strings.TrimSpace(fmt.Sprintf("%s %s", first, last))
|
||||
}
|
||||
Reference in New Issue
Block a user