Skip to content

Commit f10d004

Browse files
bidahclaude
andcommitted
πŸ› fix(x-bot): extract parent tweet data in webhook route
The webhook route processed tweets without fetching parent tweet text, images, or author β€” causing the executor to only receive raw mention text instead of the full context. Now both webhook and poll routes extract parent data before calling processMention(). Also added diagnostic logging across the pipeline to trace data flow. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 1b86cce commit f10d004

3 files changed

Lines changed: 54 additions & 1 deletion

File tree

β€Žapps/web/app/(app)/api/x-bot/generate/route.tsβ€Ž

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ export async function POST(request: NextRequest) {
6363
}
6464

6565
console.log(`[X-Bot Generate] Starting generation for tweet ${tweetId}, project ${projectId}`)
66+
console.log(`[X-Bot Generate] App description (first 200 chars): "${appDescription?.substring(0, 200)}"`)
67+
console.log(`[X-Bot Generate] Image URLs: ${imageUrls?.length || 0}`, imageUrls)
6668

6769
try {
6870
// Update xBotReplies status to generating

β€Žapps/web/app/(app)/api/x-bot/route.tsβ€Ž

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,48 @@ export async function POST(request: NextRequest) {
102102

103103
const mediaUrls = extractMediaFromWebhookTweet(tweet)
104104

105+
// Fetch parent tweet data if this is a reply
106+
let parentTweetText: string | undefined
107+
let parentMediaUrls: string[] | undefined
108+
let parentAuthorId: string | undefined
109+
110+
const parentTweetId = tweet.in_reply_to_status_id_str
111+
if (parentTweetId) {
112+
console.log(`[X-Bot Webhook] Tweet ${tweetId} is a reply to ${parentTweetId}, fetching parent tweet...`)
113+
try {
114+
const parentTweet = await client.tweets.findTweetById(parentTweetId, {
115+
'tweet.fields': ['author_id', 'text', 'attachments'],
116+
'media.fields': ['url', 'type', 'media_key', 'preview_image_url'],
117+
expansions: ['attachments.media_keys'],
118+
})
119+
120+
if (parentTweet.data) {
121+
parentTweetText = parentTweet.data.text || undefined
122+
parentAuthorId = parentTweet.data.author_id || undefined
123+
124+
// Extract parent tweet media
125+
const parentMediaKeys = parentTweet.data.attachments?.media_keys || []
126+
const parentMediaIncludes = parentTweet.includes?.media || []
127+
if (parentMediaKeys.length > 0) {
128+
parentMediaUrls = []
129+
for (const key of parentMediaKeys) {
130+
const media = parentMediaIncludes.find((m: any) => m.media_key === key)
131+
if (media && media.type === 'photo' && media.url) {
132+
parentMediaUrls.push(media.url)
133+
}
134+
}
135+
}
136+
137+
console.log(`[X-Bot Webhook] Parent tweet text: "${parentTweetText?.substring(0, 50)}..."`)
138+
console.log(`[X-Bot Webhook] Parent tweet images: ${parentMediaUrls?.length || 0}`)
139+
}
140+
} catch (error) {
141+
console.error(`[X-Bot Webhook] Failed to fetch parent tweet ${parentTweetId}:`, error)
142+
}
143+
}
144+
105145
const result = await processMention(
106-
{ tweetId, text, authorId, mediaUrls },
146+
{ tweetId, text, authorId, mediaUrls, parentTweetText, parentMediaUrls, parentAuthorId },
107147
client,
108148
baseUrl
109149
)

β€Žapps/web/lib/x-bot/process-mention.tsβ€Ž

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,16 @@ export async function processMention(
180180
): Promise<{ action: string; projectId?: string; error?: string }> {
181181
const { tweetId, text, authorId, mediaUrls: mentionMediaUrls, parentTweetText, parentMediaUrls, parentAuthorId } = mention
182182

183+
console.log(`[X-Bot] processMention called for tweet ${tweetId}:`, {
184+
textPreview: text?.substring(0, 100),
185+
authorId,
186+
mentionMediaCount: mentionMediaUrls?.length || 0,
187+
hasParentText: !!parentTweetText,
188+
parentTextPreview: parentTweetText?.substring(0, 100),
189+
parentMediaCount: parentMediaUrls?.length || 0,
190+
parentAuthorId,
191+
})
192+
183193
// Merge parent + mention media URLs
184194
// Parent images come first (they provide the design context)
185195
// Reply images are included only if the reply author is the same as the parent author
@@ -288,6 +298,7 @@ export async function processMention(
288298
}
289299
} else {
290300
console.log(`[X-Bot] Classifier disabled β€” treating tweet ${tweetId} as app request`)
301+
console.log(`[X-Bot] Parent tweet text present: ${!!parentTweetText}, fallback description (first 200 chars): "${fallbackAppDescription?.substring(0, 200)}"`)
291302
}
292303

293304
// Check subscription/credits before generation

0 commit comments

Comments
Β (0)