Skip to content

Commit

Permalink
Fix even more bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
tulir committed Apr 20, 2024
1 parent 4743225 commit 230f357
Show file tree
Hide file tree
Showing 10 changed files with 52 additions and 33 deletions.
1 change: 1 addition & 0 deletions config/bridge.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ type BridgeConfig struct {
WorkspaceAvatarInRooms bool `yaml:"workspace_avatar_in_rooms"`
ParticipantSyncCount int `yaml:"participant_sync_count"`
ParticipantSyncOnlyOnCreate bool `yaml:"participant_sync_only_on_create"`
CaptionInMessage bool `yaml:"caption_in_message"`

ManagementRoomText bridgeconfig.ManagementRoomTexts `yaml:"management_room_text"`

Expand Down
1 change: 1 addition & 0 deletions config/upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ func DoUpgrade(helper *up.Helper) {
helper.Copy(up.Bool, "bridge", "workspace_avatar_in_rooms")
helper.Copy(up.Int, "bridge", "participant_sync_count")
helper.Copy(up.Bool, "bridge", "participant_sync_only_on_create")
helper.Copy(up.Bool, "bridge", "caption_in_message")
helper.Copy(up.Bool, "bridge", "sync_direct_chat_list")
helper.Copy(up.Bool, "bridge", "federate_rooms")
if legacyPrivateChatPortalMeta, ok := helper.Get(up.Bool, "bridge", "private_chat_portal_meta"); ok {
Expand Down
2 changes: 1 addition & 1 deletion database/emoji.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func (eq *EmojiQuery) GetBySlackID(ctx context.Context, teamID, emojiID string)
}

func (eq *EmojiQuery) GetByMXC(ctx context.Context, mxc id.ContentURI) (*Emoji, error) {
return eq.QueryOne(ctx, getEmojiByMXCQuery, mxc)
return eq.QueryOne(ctx, getEmojiByMXCQuery, &mxc)
}

func buildSQLiteEmojiDeleteQuery(baseQuery string, teamID string, emojiIDs ...string) (string, []any) {
Expand Down
2 changes: 1 addition & 1 deletion database/reaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ const (
)

func (rq *ReactionQuery) GetBySlackID(ctx context.Context, key PortalKey, messageID, authorID, emojiID string) (*Reaction, error) {
return rq.QueryOne(ctx, getReactionBySlackIDQuery, key.ChannelID, key.TeamID, messageID, authorID, emojiID)
return rq.QueryOne(ctx, getReactionBySlackIDQuery, key.TeamID, key.ChannelID, messageID, authorID, emojiID)
}

func (rq *ReactionQuery) GetByMXID(ctx context.Context, eventID id.EventID) (*Reaction, error) {
Expand Down
4 changes: 3 additions & 1 deletion emoji.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,13 @@ package main
import (
"context"
_ "embed"
"fmt"
"strings"

"github.com/rs/zerolog"
"github.com/slack-go/slack"
"maunium.net/go/mautrix/id"

"github.com/slack-go/slack"
"go.mau.fi/mautrix-slack/database"
"go.mau.fi/mautrix-slack/msgconv/emoji"
)
Expand Down Expand Up @@ -176,6 +177,7 @@ func (ut *UserTeam) syncEmojis(ctx context.Context, onlyIfCountMismatch bool) er
dbEmoji := ut.bridge.DB.Emoji.New()
dbEmoji.EmojiID = key
dbEmoji.TeamID = ut.TeamID
dbEmoji.Value = fmt.Sprintf("alias:%s", alias)
if uri, ok := uploaded[alias]; ok {
dbEmoji.Alias = alias
dbEmoji.ImageMXC = uri
Expand Down
3 changes: 3 additions & 0 deletions example-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,9 @@ bridge:
# Should channel participants only be synced when creating the room?
# If you want participants to always be accurately synced, set participant_sync_count to a high value and this to false.
participant_sync_only_on_create: true
# Should single images with a caption be sent as a single event to Matrix?
# This requires a client with Matrix 1.10 support.
caption_in_message: true

# Should the bridge update the m.direct account data event when double puppeting is enabled.
# Note that updating the m.direct event is not atomic (except with mautrix-asmux)
Expand Down
30 changes: 19 additions & 11 deletions msgconv/from-matrix.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ import (
"maunium.net/go/mautrix/id"

"github.com/slack-go/slack"

"go.mau.fi/mautrix-slack/database"
)

var (
Expand All @@ -41,23 +43,29 @@ var (
ErrThreadRootNotFound = errors.New("thread root message not found")
)

func (mc *MessageConverter) ToSlack(ctx context.Context, evt *event.Event) (sendReq slack.MsgOption, fileUpload *slack.FileUploadParameters, threadRootID string, err error) {
func (mc *MessageConverter) ToSlack(ctx context.Context, evt *event.Event) (sendReq slack.MsgOption, fileUpload *slack.FileUploadParameters, threadRootID string, editTarget *database.Message, err error) {
log := zerolog.Ctx(ctx)
content, ok := evt.Content.Parsed.(*event.MessageEventContent)
if !ok {
return nil, nil, "", ErrUnexpectedParsedContentType
return nil, nil, "", nil, ErrUnexpectedParsedContentType
}

if evt.Type == event.EventSticker {
// Slack doesn't have stickers, just bridge stickers as images
content.MsgType = event.MsgImage
}

var editTargetID string
if replaceEventID := content.RelatesTo.GetReplaceID(); replaceEventID != "" {
existing, err := mc.GetMessageInfo(ctx, replaceEventID)
if err != nil {
log.Err(err).Msg("Failed to get edit target message")
return nil, nil, "", fmt.Errorf("failed to get edit target message: %w", err)
return nil, nil, "", nil, fmt.Errorf("failed to get edit target message: %w", err)
} else if existing == nil {
return nil, nil, "", ErrEditTargetNotFound
return nil, nil, "", nil, ErrEditTargetNotFound
} else {
editTargetID = existing.MessageID
editTarget = existing
if content.NewContent != nil {
content = content.NewContent
}
Expand All @@ -71,9 +79,9 @@ func (mc *MessageConverter) ToSlack(ctx context.Context, evt *event.Event) (send
if threadMXID != "" {
rootMessage, err := mc.GetMessageInfo(ctx, threadMXID)
if err != nil {
return nil, nil, "", fmt.Errorf("failed to get thread root message: %w", err)
return nil, nil, "", nil, fmt.Errorf("failed to get thread root message: %w", err)
} else if rootMessage == nil {
return nil, nil, "", ErrThreadRootNotFound
return nil, nil, "", nil, ErrThreadRootNotFound
} else if rootMessage.ThreadID != "" {
threadRootID = rootMessage.ThreadID
} else {
Expand All @@ -85,7 +93,7 @@ func (mc *MessageConverter) ToSlack(ctx context.Context, evt *event.Event) (send
if editTargetID != "" && isMediaMsgtype(content.MsgType) {
content.MsgType = event.MsgText
if content.FileName == "" || content.FileName == content.Body {
return nil, nil, "", ErrMediaOnlyEditCaption
return nil, nil, "", editTarget, ErrMediaOnlyEditCaption
}
}

Expand All @@ -107,12 +115,12 @@ func (mc *MessageConverter) ToSlack(ctx context.Context, evt *event.Event) (send
if content.MsgType == event.MsgEmote {
options = append(options, slack.MsgOptionMeMessage())
}
return slack.MsgOptionCompose(options...), nil, threadRootID, nil
return slack.MsgOptionCompose(options...), nil, threadRootID, editTarget, nil
case event.MsgAudio, event.MsgFile, event.MsgImage, event.MsgVideo:
data, err := mc.downloadMatrixAttachment(ctx, content)
if err != nil {
log.Err(err).Msg("Failed to download Matrix attachment")
return nil, nil, "", ErrMediaDownloadFailed
return nil, nil, "", editTarget, ErrMediaDownloadFailed
}

var filename, caption string
Expand All @@ -132,9 +140,9 @@ func (mc *MessageConverter) ToSlack(ctx context.Context, evt *event.Event) (send
if caption != "" {
fileUpload.InitialComment = caption
}
return nil, fileUpload, threadRootID, nil
return nil, fileUpload, threadRootID, editTarget, nil
default:
return nil, nil, "", ErrUnknownMsgType
return nil, nil, "", editTarget, ErrUnknownMsgType
}
}

Expand Down
4 changes: 4 additions & 0 deletions msgconv/from-slack.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,10 @@ func (mc *MessageConverter) ToMatrix(ctx context.Context, msg *slack.Msg) *Conve
output.Parts = append(output.Parts, textPart)
}
for i, file := range msg.Files {
// mode=tombstone seems to mean the file was deleted
if file.Mode == "tombstone" {
continue
}
partID := database.PartID{
Type: database.PartTypeFile,
Index: i,
Expand Down
33 changes: 18 additions & 15 deletions portal.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,11 @@ import (
"time"

"github.com/rs/zerolog"
"github.com/slack-go/slack"
"go.mau.fi/util/exslices"
"golang.org/x/exp/slices"
log "maunium.net/go/maulogger/v2"
"maunium.net/go/maulogger/v2/maulogadapt"

"github.com/slack-go/slack"
"go.mau.fi/mautrix-slack/msgconv"
"go.mau.fi/mautrix-slack/msgconv/emoji"

"maunium.net/go/mautrix"
"maunium.net/go/mautrix/appservice"
"maunium.net/go/mautrix/bridge"
Expand All @@ -45,6 +41,8 @@ import (

"go.mau.fi/mautrix-slack/config"
"go.mau.fi/mautrix-slack/database"
"go.mau.fi/mautrix-slack/msgconv"
"go.mau.fi/mautrix-slack/msgconv/emoji"
)

type portalMatrixMessage struct {
Expand Down Expand Up @@ -555,7 +553,7 @@ func (portal *Portal) handleMatrixMessages(msg portalMatrixMessage) {
})

switch msg.evt.Type {
case event.EventMessage:
case event.EventMessage, event.EventSticker:
portal.handleMatrixMessage(ctx, ut, msg.evt, &ms)
case event.EventRedaction:
portal.handleMatrixRedaction(ctx, ut, msg.evt)
Expand All @@ -570,7 +568,7 @@ func (portal *Portal) handleMatrixMessage(ctx context.Context, sender *UserTeam,
log := zerolog.Ctx(ctx)
ctx = context.WithValue(ctx, convertContextKeySource, sender)
start := time.Now()
sendOpts, fileUpload, threadID, err := portal.MsgConv.ToSlack(ctx, evt)
sendOpts, fileUpload, threadID, editTarget, err := portal.MsgConv.ToSlack(ctx, evt)
ms.timings.convert = time.Since(start)

start = time.Now()
Expand Down Expand Up @@ -611,7 +609,7 @@ func (portal *Portal) handleMatrixMessage(ctx context.Context, sender *UserTeam,
}
ms.timings.totalSend = time.Since(start)
go ms.sendMessageMetrics(ctx, evt, err, "Error sending", true)
if timestamp != "" {
if timestamp != "" && editTarget == nil {
dbMsg := portal.bridge.DB.Message.New()
dbMsg.PortalKey = portal.PortalKey
dbMsg.MessageID = timestamp
Expand Down Expand Up @@ -1435,6 +1433,9 @@ func (portal *Portal) HandleSlackMessage(ctx context.Context, source *UserTeam,
if slackAuthor == "" {
slackAuthor = msg.BotID
}
if slackAuthor == "" && msg.SubMessage != nil {
slackAuthor = msg.SubMessage.User
}
var sender *Puppet
if slackAuthor != "" {
sender = portal.Team.GetPuppetByID(slackAuthor)
Expand Down Expand Up @@ -1512,10 +1513,11 @@ func (portal *Portal) HandleSlackEditMessage(ctx context.Context, source *UserTe
ts := parseSlackTimestamp(msg.Timestamp)
ctx = context.WithValue(ctx, convertContextKeySource, source)
ctx = context.WithValue(ctx, convertContextKeyIntent, intent)
// TODO avoid reuploading files when editing messages
converted := portal.MsgConv.ToMatrix(ctx, msg)
// Don't merge caption if there's more than one part in the database
// (because it means the original didn't have a merged caption)
if len(editTarget) == 1 {
if len(editTarget) == 1 && portal.bridge.Config.Bridge.CaptionInMessage {
converted.MergeCaption()
}

Expand Down Expand Up @@ -1610,6 +1612,9 @@ func (portal *Portal) HandleSlackNormalMessage(ctx context.Context, source *User
ctx = context.WithValue(ctx, convertContextKeySource, source)
ctx = context.WithValue(ctx, convertContextKeyIntent, intent)
converted := portal.MsgConv.ToMatrix(ctx, msg)
if portal.bridge.Config.Bridge.CaptionInMessage {
converted.MergeCaption()
}

var lastEventID id.EventID
for _, part := range converted.Parts {
Expand Down Expand Up @@ -1673,9 +1678,7 @@ func (portal *Portal) HandleSlackReaction(ctx context.Context, source *UserTeam,
return
}

slackReaction := strings.Trim(msg.Reaction, ":")

key := source.GetEmoji(ctx, slackReaction)
key := source.GetEmoji(ctx, msg.Reaction)

var content event.ReactionEventContent
content.RelatesTo = event.RelatesTo{
Expand All @@ -1686,12 +1689,12 @@ func (portal *Portal) HandleSlackReaction(ctx context.Context, source *UserTeam,
extraContent := map[string]any{}
if strings.HasPrefix(key, "mxc://") {
extraContent["fi.mau.slack.reaction"] = map[string]any{
"name": slackReaction,
"name": msg.Reaction,
"mxc": key,
}
extraContent["com.beeper.reaction.shortcode"] = msg.Reaction
extraContent["com.beeper.reaction.shortcode"] = fmt.Sprintf(":%s:", msg.Reaction)
if !portal.bridge.Config.Bridge.CustomEmojiReactions {
content.RelatesTo.Key = slackReaction
content.RelatesTo.Key = msg.Reaction
}
}

Expand Down
5 changes: 1 addition & 4 deletions userteam.go
Original file line number Diff line number Diff line change
Expand Up @@ -426,10 +426,7 @@ func (ut *UserTeam) handleSlackEvent(ctx context.Context, rawEvt any) {
case *slack.InvalidAuthEvent:
ut.Logout(context.TODO(), status.BridgeState{StateEvent: status.StateBadCredentials, Error: "slack-invalid-auth"})
return
case *slack.LatencyReport:
ut.Log.Trace().Dur("latency", evt.Value).Msg("Latency report")
case *slack.MessageEvent:
ut.Log.Trace().Any("event_content", evt).Msg("Received Slack message event")
ut.pushPortalEvent(evt.Channel, evt)
case *slack.ReactionAddedEvent:
ut.pushPortalEvent(evt.Item.Channel, evt)
Expand Down Expand Up @@ -466,7 +463,7 @@ func (ut *UserTeam) handleSlackEvent(ctx context.Context, rawEvt any) {
Error: status.BridgeStateErrorCode(fmt.Sprintf("slack-rtm-error-%d", evt.Code)),
Message: fmt.Sprintf("%d: %s", evt.Code, evt.Msg),
})
case *slack.FileSharedEvent, *slack.FilePublicEvent, *slack.FilePrivateEvent, *slack.FileCreatedEvent, *slack.FileChangeEvent, *slack.FileDeletedEvent, *slack.DesktopNotificationEvent:
case *slack.FileSharedEvent, *slack.FilePublicEvent, *slack.FilePrivateEvent, *slack.FileCreatedEvent, *slack.FileChangeEvent, *slack.FileDeletedEvent, *slack.DesktopNotificationEvent, *slack.ReconnectUrlEvent, *slack.LatencyReport:
// ignored intentionally, these are duplicates or do not contain useful information
default:
ut.Log.Warn().Any("event_data", evt).Msg("Unrecognized Slack event type")
Expand Down

0 comments on commit 230f357

Please sign in to comment.