diff --git a/pkg/connector/backfill.go b/pkg/connector/backfill.go index 9470527..d212e92 100644 --- a/pkg/connector/backfill.go +++ b/pkg/connector/backfill.go @@ -37,7 +37,7 @@ func (dc *DiscordClient) FetchMessages(ctx context.Context, fetchParams bridgev2 return nil, bridgev2.ErrNotLoggedIn } - channelID := discordid.ParsePortalID(fetchParams.Portal.ID) + channelID := discordid.ParseChannelPortalID(fetchParams.Portal.ID) log := zerolog.Ctx(ctx).With(). Str("action", "fetch messages"). Str("channel_id", channelID). diff --git a/pkg/connector/chatinfo.go b/pkg/connector/chatinfo.go index e08f049..8ce7430 100644 --- a/pkg/connector/chatinfo.go +++ b/pkg/connector/chatinfo.go @@ -117,10 +117,10 @@ func (d *DiscordClient) getChannelChatInfo(ctx context.Context, ch *discordgo.Ch var parentPortalID *networkid.PortalID if ch.Type == discordgo.ChannelTypeGuildCategory || (ch.ParentID == "" && ch.GuildID != "") { // Categories and uncategorized guild channels always have the guild as their parent. - parentPortalID = ptr.Ptr(discordid.MakeGuildPortalID(ch.GuildID)) + parentPortalID = ptr.Ptr(discordid.MakeGuildPortalIDWithID(ch.GuildID)) } else if ch.ParentID != "" { // Categorized guild channels. - parentPortalID = ptr.Ptr(discordid.MakePortalID(ch.ParentID)) + parentPortalID = ptr.Ptr(discordid.MakeChannelPortalIDWithID(ch.ParentID)) } var memberList bridgev2.ChatMemberList @@ -176,7 +176,7 @@ func (d *DiscordClient) GetChatInfo(ctx context.Context, portal *bridgev2.Portal return d.getGuildSpaceInfo(ctx, guild) } else { // Portal is to a channel of some kind (private or guild). - channelID := discordid.ParsePortalID(portal.ID) + channelID := discordid.ParseChannelPortalID(portal.ID) ch, err := d.Session.State.Channel(channelID) if err != nil { diff --git a/pkg/connector/client.go b/pkg/connector/client.go index 3bf8e24..a6f852f 100644 --- a/pkg/connector/client.go +++ b/pkg/connector/client.go @@ -253,7 +253,7 @@ func (d *DiscordClient) canSeeGuildChannel(ctx context.Context, ch *discordgo.Ch func (d *DiscordClient) guildPortalKeyFromID(guildID string) networkid.PortalKey { // TODO: Support configuring `split_portals`. return networkid.PortalKey{ - ID: discordid.MakeGuildPortalID(guildID), + ID: discordid.MakeGuildPortalIDWithID(guildID), Receiver: d.UserLogin.ID, } } @@ -432,6 +432,6 @@ func (d *DiscordClient) syncChannel(_ context.Context, ch *discordgo.Channel) { d.connector.Bridge.QueueRemoteEvent(d.UserLogin, &DiscordChatResync{ Client: d, channel: ch, - portalKey: discordid.MakePortalKey(ch, d.UserLogin.ID, true), + portalKey: discordid.MakeChannelPortalKey(ch, d.UserLogin.ID, true), }) } diff --git a/pkg/connector/handlediscord.go b/pkg/connector/handlediscord.go index 8cde3d7..e8c2479 100644 --- a/pkg/connector/handlediscord.go +++ b/pkg/connector/handlediscord.go @@ -148,7 +148,7 @@ func (d *DiscordClient) wrapDiscordMessage(msg *discordgo.Message, typ bridgev2. DiscordEventMeta: &DiscordEventMeta{ Type: typ, PortalKey: networkid.PortalKey{ - ID: discordid.MakePortalID(msg.ChannelID), + ID: discordid.MakeChannelPortalIDWithID(msg.ChannelID), Receiver: d.UserLogin.ID, }, }, @@ -221,7 +221,7 @@ func (d *DiscordClient) wrapDiscordReaction(reaction *discordgo.MessageReaction, DiscordEventMeta: &DiscordEventMeta{ Type: evtType, PortalKey: networkid.PortalKey{ - ID: discordid.MakePortalID(reaction.ChannelID), + ID: discordid.MakeChannelPortalIDWithID(reaction.ChannelID), Receiver: d.UserLogin.ID, }, }, @@ -238,7 +238,7 @@ func (d *DiscordClient) handleDiscordTyping(ctx context.Context, typing *discord log := zerolog.Ctx(ctx) portalKey := networkid.PortalKey{ - ID: discordid.MakePortalID(typing.ChannelID), + ID: discordid.MakeChannelPortalIDWithID(typing.ChannelID), Receiver: d.UserLogin.ID, } portal, err := d.connector.Bridge.GetExistingPortalByKey(ctx, portalKey) diff --git a/pkg/connector/handlematrix.go b/pkg/connector/handlematrix.go index 9e4b6c4..01f5573 100644 --- a/pkg/connector/handlematrix.go +++ b/pkg/connector/handlematrix.go @@ -46,7 +46,7 @@ func (d *DiscordClient) HandleMatrixMessage(ctx context.Context, msg *bridgev2.M portal := msg.Portal guildID := portal.Metadata.(*discordid.PortalMetadata).GuildID - channelID := discordid.ParsePortalID(portal.ID) + channelID := discordid.ParseChannelPortalID(portal.ID) sendReq, err := d.connector.MsgConv.ToDiscord(ctx, d.Session, msg) if err != nil { @@ -57,7 +57,7 @@ func (d *DiscordClient) HandleMatrixMessage(ctx context.Context, msg *bridgev2.M // TODO: When supporting threads (and not a bot user), send a thread referer. options = append(options, discordgo.WithChannelReferer(guildID, channelID)) - sentMsg, err := d.Session.ChannelMessageSendComplex(discordid.ParsePortalID(msg.Portal.ID), sendReq, options...) + sentMsg, err := d.Session.ChannelMessageSendComplex(discordid.ParseChannelPortalID(msg.Portal.ID), sendReq, options...) if err != nil { return nil, err } @@ -86,7 +86,7 @@ func (d *DiscordClient) HandleMatrixEdit(ctx context.Context, msg *bridgev2.Matr ) _, err := d.Session.ChannelMessageEdit( - discordid.ParsePortalID(msg.Portal.ID), + discordid.ParseChannelPortalID(msg.Portal.ID), discordid.ParseMessageID(msg.EditTarget.ID), content, ) @@ -113,7 +113,7 @@ func (d *DiscordClient) HandleMatrixReaction(ctx context.Context, reaction *brid err := d.Session.MessageReactionAddUser( meta.GuildID, - discordid.ParsePortalID(portal.ID), + discordid.ParseChannelPortalID(portal.ID), discordid.ParseMessageID(reaction.TargetMessage.ID), discordid.ParseEmojiID(reaction.PreHandleResp.EmojiID), ) @@ -123,7 +123,7 @@ func (d *DiscordClient) HandleMatrixReaction(ctx context.Context, reaction *brid func (d *DiscordClient) HandleMatrixReactionRemove(ctx context.Context, removal *bridgev2.MatrixReactionRemove) error { removing := removal.TargetReaction emojiID := removing.EmojiID - channelID := discordid.ParsePortalID(removing.Room.ID) + channelID := discordid.ParseChannelPortalID(removing.Room.ID) guildID := removal.Portal.Metadata.(*discordid.PortalMetadata).GuildID err := d.Session.MessageReactionRemoveUser(guildID, channelID, discordid.ParseMessageID(removing.MessageID), discordid.ParseEmojiID(emojiID), discordid.ParseUserLoginID(d.UserLogin.ID)) @@ -131,7 +131,7 @@ func (d *DiscordClient) HandleMatrixReactionRemove(ctx context.Context, removal } func (d *DiscordClient) HandleMatrixMessageRemove(ctx context.Context, removal *bridgev2.MatrixMessageRemove) error { - channelID := discordid.ParsePortalID(removal.Portal.ID) + channelID := discordid.ParseChannelPortalID(removal.Portal.ID) messageID := discordid.ParseMessageID(removal.TargetMessage.ID) return d.Session.ChannelMessageDelete(channelID, messageID) } @@ -177,7 +177,7 @@ func (d *DiscordClient) HandleMatrixReadReceipt(ctx context.Context, msg *bridge // TODO: Support threads. guildID := msg.Portal.Metadata.(*discordid.PortalMetadata).GuildID - channelID := discordid.ParsePortalID(msg.Portal.ID) + channelID := discordid.ParseChannelPortalID(msg.Portal.ID) resp, err := d.Session.ChannelMessageAckNoToken(channelID, targetMessageID, discordgo.WithChannelReferer(guildID, channelID)) if err != nil { log.Err(err).Msg("Failed to send read receipt to Discord") @@ -202,7 +202,7 @@ func (d *DiscordClient) viewingChannel(ctx context.Context, portal *bridgev2.Por d.markedOpenedLock.Lock() defer d.markedOpenedLock.Unlock() - channelID := discordid.ParsePortalID(portal.ID) + channelID := discordid.ParseChannelPortalID(portal.ID) log := zerolog.Ctx(ctx).With(). Str("channel_id", channelID).Logger() @@ -233,7 +233,7 @@ func (d *DiscordClient) HandleMatrixTyping(ctx context.Context, msg *bridgev2.Ma _ = d.viewingChannel(ctx, msg.Portal) guildID := msg.Portal.Metadata.(*discordid.PortalMetadata).GuildID - channelID := discordid.ParsePortalID(msg.Portal.ID) + channelID := discordid.ParseChannelPortalID(msg.Portal.ID) // TODO: Support threads properly when sending the referer. err := d.Session.ChannelTyping(channelID, discordgo.WithChannelReferer(guildID, channelID)) diff --git a/pkg/connector/provisioning.go b/pkg/connector/provisioning.go index 5e9130b..442b7f1 100644 --- a/pkg/connector/provisioning.go +++ b/pkg/connector/provisioning.go @@ -164,7 +164,7 @@ func (p *ProvisioningAPI) guildsList(w http.ResponseWriter, r *http.Request, log // guild, as it recognizes the guild returned from this HTTP // endpoint and the actual space itself as separate "entities". // (Despite this, they point to identical rooms.) - ID: string(discordid.MakeGuildPortalID(guild.ID)), + ID: string(discordid.MakeGuildPortalIDWithID(guild.ID)), Name: guild.Name, AvatarURL: discordgo.EndpointGuildIcon(guild.ID, guild.Icon), Bridged: beingBridged, diff --git a/pkg/discordid/id.go b/pkg/discordid/id.go index 10a8b13..afe951c 100644 --- a/pkg/discordid/id.go +++ b/pkg/discordid/id.go @@ -72,11 +72,24 @@ func UserLoginIDToUserID(id networkid.UserLoginID) networkid.UserID { return networkid.UserID(id) } -func MakePortalID(channelID string) networkid.PortalID { +func MakeChannelPortalKey(ch *discordgo.Channel, userLoginID networkid.UserLoginID, wantReceiver bool) (key networkid.PortalKey) { + key.ID = MakeChannelPortalIDWithID(ch.ID) + if wantReceiver { + key.Receiver = userLoginID + } + return +} + +func MakeChannelPortalKeyWithID(channelID string) (key networkid.PortalKey) { + key.ID = MakeChannelPortalIDWithID(channelID) + return +} + +func MakeChannelPortalIDWithID(channelID string) networkid.PortalID { return networkid.PortalID(channelID) } -func ParsePortalID(portalID networkid.PortalID) string { +func ParseChannelPortalID(portalID networkid.PortalID) string { return string(portalID) } @@ -114,8 +127,8 @@ func MakeAvatarID(avatar string) networkid.AvatarID { // // To accommodate Discord guilds created before this API change that have also // never deleted the default channel, we need a way to distinguish between the -// guild and the default channel, as we wouldn't be able to bridge the guild -// as a space otherwise. +// guild and the default channel. Otherwise, we wouldn't be able to bridge both +// the channel portal as well as the guild space; their keys would conflict. // // "*" was chosen as the asterisk character is used to filter by guilds in // the quick switcher (in Discord's first-party clients). @@ -123,7 +136,7 @@ func MakeAvatarID(avatar string) networkid.AvatarID { // For more information, see: https://discord.com/developers/docs/change-log#breaking-change-default-channels:~:text=New%20guilds%20will%20no%20longer. const GuildPortalKeySigil = "*" -func MakeGuildPortalID(guildID string) networkid.PortalID { +func MakeGuildPortalIDWithID(guildID string) networkid.PortalID { return networkid.PortalID(GuildPortalKeySigil + guildID) } @@ -140,16 +153,3 @@ func ParseGuildPortalID(portalID networkid.PortalID) string { return "" } - -func MakePortalKey(ch *discordgo.Channel, userLoginID networkid.UserLoginID, wantReceiver bool) (key networkid.PortalKey) { - key.ID = MakePortalID(ch.ID) - if wantReceiver { - key.Receiver = userLoginID - } - return -} - -func MakePortalKeyWithID(channelID string) (key networkid.PortalKey) { - key.ID = MakePortalID(channelID) - return -} diff --git a/pkg/msgconv/formatter_tag.go b/pkg/msgconv/formatter_tag.go index 3d93039..e75193d 100644 --- a/pkg/msgconv/formatter_tag.go +++ b/pkg/msgconv/formatter_tag.go @@ -285,7 +285,7 @@ func (r *discordTagHTMLRenderer) renderDiscordMention(w util.BufWriter, source [ return // } case *astDiscordChannelMention: - if portal, _ := node.portal.Bridge.GetPortalByKey(ctx, discordid.MakePortalKeyWithID( + if portal, _ := node.portal.Bridge.GetPortalByKey(ctx, discordid.MakeChannelPortalKeyWithID( strconv.FormatInt(node.id, 10), )); portal != nil { if portal.MXID != "" { diff --git a/pkg/msgconv/from-discord.go b/pkg/msgconv/from-discord.go index 4288065..da45d87 100644 --- a/pkg/msgconv/from-discord.go +++ b/pkg/msgconv/from-discord.go @@ -194,9 +194,9 @@ func (mc *MessageConverter) tryAddingReplyToConvertedMessage( // The portal containing the message that was replied to. targetPortal := portal - if ref.ChannelID != discordid.ParsePortalID(portal.ID) { + if ref.ChannelID != discordid.ParseChannelPortalID(portal.ID) { var err error - targetPortal, err = mc.Bridge.GetPortalByKey(ctx, discordid.MakePortalKeyWithID(ref.ChannelID)) + targetPortal, err = mc.Bridge.GetPortalByKey(ctx, discordid.MakeChannelPortalKeyWithID(ref.ChannelID)) if err != nil { log.Err(err).Msg("Failed to get cross-room reply portal; proceeding") return @@ -316,7 +316,7 @@ func (mc *MessageConverter) forwardedMessageHTMLPart(ctx context.Context, portal forwardedHTML := mc.renderDiscordMarkdownOnlyHTMLNoUnwrap(portal, msg.MessageSnapshots[0].Message.Content, true) msgTSText := msg.MessageSnapshots[0].Message.Timestamp.Format("2006-01-02 15:04 MST") origLink := fmt.Sprintf("unknown channel • %s", msgTSText) - if forwardedFromPortal, err := mc.Bridge.DB.Portal.GetByKey(ctx, discordid.MakePortalKeyWithID(msg.MessageReference.ChannelID)); err == nil && forwardedFromPortal != nil { + if forwardedFromPortal, err := mc.Bridge.DB.Portal.GetByKey(ctx, discordid.MakeChannelPortalKeyWithID(msg.MessageReference.ChannelID)); err == nil && forwardedFromPortal != nil { if origMessage, err := mc.Bridge.DB.Message.GetFirstPartByID(ctx, source.ID, discordid.MakeMessageID(msg.MessageReference.MessageID)); err == nil && origMessage != nil { // We've bridged the message that was forwarded, so we can link to it directly. origLink = fmt.Sprintf( diff --git a/pkg/msgconv/from-matrix.go b/pkg/msgconv/from-matrix.go index c7a3c4e..d6bf5a3 100644 --- a/pkg/msgconv/from-matrix.go +++ b/pkg/msgconv/from-matrix.go @@ -101,14 +101,14 @@ func (mc *MessageConverter) ToDiscord( if msg.ReplyTo != nil { req.Reference = &discordgo.MessageReference{ - ChannelID: discordid.ParsePortalID(msg.ReplyTo.Room.ID), + ChannelID: discordid.ParseChannelPortalID(msg.ReplyTo.Room.ID), MessageID: discordid.ParseMessageID(msg.ReplyTo.ID), } } portal := msg.Portal guildID := msg.Portal.Metadata.(*discordid.PortalMetadata).GuildID - channelID := discordid.ParsePortalID(portal.ID) + channelID := discordid.ParseChannelPortalID(portal.ID) content := msg.Content convertMatrix := func() {