// mautrix-signal - A Matrix-signal puppeting bridge. // Copyright (C) 2024 Tulir Asokan // // 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 . package msgconv import ( "context" "github.com/google/uuid" "maunium.net/go/mautrix/bridgev2" "maunium.net/go/mautrix/bridgev2/networkid" "maunium.net/go/mautrix/id" "go.mau.fi/mautrix-signal/pkg/msgconv/matrixfmt" "go.mau.fi/mautrix-signal/pkg/msgconv/signalfmt" "go.mau.fi/mautrix-signal/pkg/signalid" "go.mau.fi/mautrix-signal/pkg/signalmeow" ) type contextKey int const ( contextKeyPortal contextKey = iota contextKeyClient contextKeyIntent ) type MessageConverter struct { Bridge *bridgev2.Bridge SignalFmtParams *signalfmt.FormatParams MatrixFmtParams *matrixfmt.HTMLParser MaxFileSize int64 LocationFormat string DisappearViewOnce bool DirectMedia bool ExtEvPolls bool } func NewMessageConverter(br *bridgev2.Bridge) *MessageConverter { return &MessageConverter{ Bridge: br, SignalFmtParams: &signalfmt.FormatParams{ GetUserInfo: func(ctx context.Context, uuid uuid.UUID) signalfmt.UserInfo { ghost, err := br.GetGhostByID(ctx, signalid.MakeUserID(uuid)) if err != nil { // TODO log? return signalfmt.UserInfo{} } userInfo := signalfmt.UserInfo{ MXID: ghost.Intent.GetMXID(), Name: ghost.Name, } userLogin := br.GetCachedUserLoginByID(networkid.UserLoginID(uuid.String())) portal := getPortal(ctx) if userLogin != nil && (portal.Receiver == "" || portal.Receiver == userLogin.ID) { userInfo.MXID = userLogin.UserMXID // TODO find matrix user displayname? } return userInfo }, }, MatrixFmtParams: &matrixfmt.HTMLParser{ GetUUIDFromMXID: func(ctx context.Context, userID id.UserID) uuid.UUID { parsed, ok := br.Matrix.ParseGhostMXID(userID) if ok { u, _ := signalid.ParseUserID(parsed) return u } user, _ := br.GetExistingUserByMXID(ctx, userID) // TODO log errors? if user != nil { preferredLogin, _, _ := getPortal(ctx).FindPreferredLogin(ctx, user, true) if preferredLogin != nil { u, _ := signalid.ParseUserLoginID(preferredLogin.ID) return u } } return uuid.Nil }, }, MaxFileSize: 50 * 1024 * 1024, } } func getClient(ctx context.Context) *signalmeow.Client { return ctx.Value(contextKeyClient).(*signalmeow.Client) } func getPortal(ctx context.Context) *bridgev2.Portal { return ctx.Value(contextKeyPortal).(*bridgev2.Portal) } func getIntent(ctx context.Context) bridgev2.MatrixAPI { return ctx.Value(contextKeyIntent).(bridgev2.MatrixAPI) }