mirror of
https://github.com/prosolis/gogobee.git
synced 2026-09-14 10:51:09 +00:00
dm: stop creating a duplicate DM room on every restart
GetDMRoom's lookup chain could never hit. The in-memory cache died with the process, and the m.direct account data it fell back on was never written by the bot -- room creation only ever populated the map. As an appservice user there is no /sync to populate it either, so after each restart the first DM to a user fell through both checks and created a fresh room. Persist the mapping in a new dm_rooms table and read it before anything else. Creation now also publishes m.direct, so clients label the room as a DM. A stored room is checked for liveness before reuse, counting the user as present while merely invited -- they often never accept, and treating that as gone would recreate the room on every send, which is the original bug wearing a different hat. The same check now guards the m.direct path, which previously took the last entry on faith. Two adoption paths keep existing rooms from being orphaned: user-initiated DM invites are claimed on join, and a room the user is already talking in is adopted on first message (negative-cached so group rooms cost one member lookup, not one per message). For users predating the table, a one-shot sweep of joined rooms runs only on the path that would otherwise create a duplicate. The sweep cannot rank duplicates -- without /sync there are no timestamps, so it takes the newest by room-list order. First message from the user corrects any wrong pick.
This commit is contained in:
@@ -255,6 +255,9 @@ func main() {
|
||||
|
||||
// ---- Set up event handlers ----
|
||||
|
||||
// Minimal Base used only for DM-room bookkeeping from the event handlers.
|
||||
dmLearner := &plugin.Base{Client: client}
|
||||
|
||||
// Auto-join on invite + moderation member tracking
|
||||
sess.OnEventType(event.StateMember, func(ctx context.Context, evt *event.Event) {
|
||||
defer func() {
|
||||
@@ -277,6 +280,11 @@ func main() {
|
||||
slog.Error("failed to join room", "room", evt.RoomID, "err", err)
|
||||
} else {
|
||||
slog.Info("joined room", "room", evt.RoomID)
|
||||
// A user-initiated DM invite: claim it now, before any
|
||||
// outbound DM has a chance to create a rival room.
|
||||
if mem.IsDirect {
|
||||
dmLearner.RecordDMRoom(evt.Sender, evt.RoomID)
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
@@ -325,6 +333,10 @@ func main() {
|
||||
body = strings.TrimSpace(body[idx+2:])
|
||||
}
|
||||
}
|
||||
// Adopt the room the user is talking in if it's their DM room, so the
|
||||
// bot replies there instead of opening a second one.
|
||||
dmLearner.LearnDMRoom(evt.Sender, evt.RoomID)
|
||||
|
||||
msgCtx := plugin.MessageContext{
|
||||
RoomID: evt.RoomID,
|
||||
EventID: evt.ID,
|
||||
|
||||
Reference in New Issue
Block a user