瀏覽代碼

Forward fill missing messages on startup

Max Sandholm 2 年之前
父節點
當前提交
ee5ea87e83
共有 3 個文件被更改,包括 47 次插入0 次删除
  1. 5 0
      database/message.go
  2. 40 0
      portal.go
  3. 2 0
      user.go

+ 5 - 0
database/message.go

@@ -70,6 +70,11 @@ func (mq *MessageQuery) GetLastInThread(key PortalKey, threadID string) *Message
 	return mq.New().Scan(mq.db.QueryRow(query, key.ChannelID, key.Receiver, threadID))
 }
 
+func (mq *MessageQuery) GetLast(key PortalKey) *Message {
+	query := messageSelect + " WHERE dc_chan_id=$1 AND dc_chan_receiver=$2 AND dc_edit_index=0 ORDER BY timestamp DESC LIMIT 1"
+	return mq.New().Scan(mq.db.QueryRow(query, key.ChannelID, key.Receiver))
+}
+
 func (mq *MessageQuery) DeleteAll(key PortalKey) {
 	query := "DELETE FROM message WHERE dc_chan_id=$1 AND dc_chan_receiver=$2"
 	_, err := mq.db.Exec(query, key.ChannelID, key.Receiver)

+ 40 - 0
portal.go

@@ -5,6 +5,7 @@ import (
 	"errors"
 	"fmt"
 	"reflect"
+	"sort"
 	"strconv"
 	"strings"
 	"sync"
@@ -1966,3 +1967,42 @@ func (portal *Portal) UpdateInfo(source *User, meta *discordgo.Channel) *discord
 	}
 	return meta
 }
+
+func (portal *Portal) ForwardBackfill(source *User) error {
+	portal.log.Debugln("Checking for missing messages to fill")
+	lastMessage := portal.bridge.DB.Message.GetLast(portal.Key)
+	if lastMessage == nil {
+		portal.log.Debugln("No last message in portal, can't forward backfill")
+		return nil
+	}
+
+	// Get up to 100 messages at a time until everything is fetched
+	for {
+		messages, err := source.Session.ChannelMessages(portal.Key.ChannelID, 100, "", lastMessage.DiscordID, "")
+		if err != nil {
+			portal.log.Debugln("Error getting messages to forward backfill", err)
+			return err
+		}
+		// Discord seems to return messages in reverse order,
+		// but no specific order is guaranteed by their API docs?
+		sort.Slice(messages, func(i, j int) bool {
+			return messages[i].Timestamp.Before(messages[j].Timestamp)
+		})
+
+		for _, msg := range messages {
+			portal.handleDiscordMessageCreate(source, msg, nil)
+		}
+
+		if len(messages) < 100 {
+			// Assume that was all the missing messages
+			break
+		}
+		lastMessage = portal.bridge.DB.Message.GetLast(portal.Key)
+		if lastMessage == nil {
+			portal.log.Debugln("No last message in portal, can't forward backfill")
+			return nil
+		}
+	}
+
+	return nil
+}

+ 2 - 0
user.go

@@ -728,6 +728,7 @@ func (user *User) handlePrivateChannel(portal *Portal, meta *discordgo.Channel,
 		}
 	} else {
 		portal.UpdateInfo(user, meta)
+		portal.ForwardBackfill(user)
 	}
 	user.MarkInPortal(database.UserPortal{
 		DiscordID: portal.Key.ChannelID,
@@ -842,6 +843,7 @@ func (user *User) handleGuild(meta *discordgo.Guild, timestamp time.Time, isInSp
 				}
 			} else {
 				portal.UpdateInfo(user, ch)
+				portal.ForwardBackfill(user)
 			}
 		}
 	}