diff --git a/lib/shared/markdown.js b/lib/shared/markdown.js
--- a/lib/shared/markdown.js
+++ b/lib/shared/markdown.js
@@ -257,6 +257,42 @@
 const stripSpoilersFromNotifications = (text: string): string =>
   text.replace(replaceSpoilerRegex, spoilerReplacement);
 
+const stripSpoilersFromMarkdownAST = (
+  ast: SingleASTNode[],
+  isTextASpoiler: boolean,
+): SingleASTNode[] => {
+  return ast.map(node => {
+    return {
+      ...node,
+      content: replaceSpoilersFromMarkdownAST(node, isTextASpoiler),
+    };
+  });
+};
+
+const replaceSpoilersFromMarkdownAST = (
+  node: ASTNode,
+  isTextASpoiler: boolean,
+): string => {
+  if (Array.isArray(node)) {
+    return node
+      .map(n => replaceSpoilersFromMarkdownAST(n, isTextASpoiler))
+      .join('');
+  }
+
+  const { content, items, type } = node;
+  const isTypeASpoiler = type === 'spoiler';
+  const isSpoiler = isTypeASpoiler || isTextASpoiler;
+
+  if (content && typeof content === 'string') {
+    return isTextASpoiler ? spoilerReplacement : content;
+  } else if (items) {
+    return replaceSpoilersFromMarkdownAST(items, isSpoiler);
+  } else if (content) {
+    return replaceSpoilersFromMarkdownAST(content, isSpoiler);
+  }
+  return '';
+};
+
 export {
   paragraphRegex,
   paragraphStripTrailingNewlineRegex,
@@ -278,4 +314,5 @@
   parseList,
   matchMentions,
   stripSpoilersFromNotifications,
+  stripSpoilersFromMarkdownAST,
 };
diff --git a/lib/shared/messages/text-message-spec.js b/lib/shared/messages/text-message-spec.js
--- a/lib/shared/messages/text-message-spec.js
+++ b/lib/shared/messages/text-message-spec.js
@@ -20,6 +20,7 @@
   type ASTNode,
   type SingleASTNode,
   stripSpoilersFromNotifications,
+  stripSpoilersFromMarkdownAST,
 } from '../markdown';
 import { threadIsGroupChat } from '../thread-utils';
 import { stringForUser } from '../user-utils';
@@ -89,8 +90,10 @@
   messageTitle({ messageInfo, markdownRules }) {
     const { text } = messageInfo;
     const parser = SimpleMarkdown.parserFor(markdownRules);
-    const ast = parser(text, { disableAutoBlockNewlines: true });
-
+    const ast = stripSpoilersFromMarkdownAST(
+      parser(text, { disableAutoBlockNewlines: true }),
+      false,
+    );
     return getFirstNonQuotedRawLine(ast).trim();
   },