diff --git a/keyserver/src/fetchers/message-fetchers.js b/keyserver/src/fetchers/message-fetchers.js
--- a/keyserver/src/fetchers/message-fetchers.js
+++ b/keyserver/src/fetchers/message-fetchers.js
@@ -879,6 +879,33 @@
   return SQLResult.map(item => item.rawMessageInfo);
 }
 
+async function rawMessageInfoForRowsAndRelatedMessages(
+  rows: $ReadOnlyArray<Object>,
+  viewer?: Viewer,
+): Promise<$ReadOnlyArray<RawMessageInfo>> {
+  const parsedResults = await parseMessageSQLResult(rows, new Map(), viewer);
+  const rawMessageInfoMap = new Map<
+    string,
+    RawComposableMessageInfo | RawRobotextMessageInfo,
+  >();
+  for (const message of parsedResults) {
+    const { rawMessageInfo } = message;
+    if (isMessageSidebarSourceReactionOrEdit(rawMessageInfo)) {
+      continue;
+    }
+    invariant(rawMessageInfo.id, 'rawMessageInfo.id should not be null');
+    rawMessageInfoMap.set(rawMessageInfo.id, rawMessageInfo);
+  }
+
+  const rawMessageInfos = parsedResults.map(item => item.rawMessageInfo);
+  const rawRelatedMessageInfos = await fetchRelatedMessages(
+    viewer,
+    rawMessageInfoMap,
+  );
+
+  return [...rawMessageInfos, ...rawRelatedMessageInfos];
+}
+
 export {
   fetchCollapsableNotifs,
   fetchMessageInfos,
@@ -891,4 +918,5 @@
   fetchLatestEditMessageContentByID,
   fetchPinnedMessageInfos,
   fetchRelatedMessages,
+  rawMessageInfoForRowsAndRelatedMessages,
 };