Skip to content

Fix realtime updates for sidebar EmailsList and thread Conversations#32

Draft
Copilot wants to merge 3 commits into
mainfrom
copilot/fix-realtime-emails-list
Draft

Fix realtime updates for sidebar EmailsList and thread Conversations#32
Copilot wants to merge 3 commits into
mainfrom
copilot/fix-realtime-emails-list

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 1, 2026

Realtime was effectively broken in two places: the sidebar never reflected new threads or replies, and the open conversation view never showed incoming messages without a manual refresh.

Root causes

  • No thread UPDATE events fired on email receipt — the inbound webhook never updated the thread record when a new email arrived (unless it was reopening a closed thread). With no UPDATE event, the UPDATE_THREAD realtime handler had nothing to catch. For new threads, this also meant postgres_changes INSERT delivery was the only mechanism, which is unreliable without Realtime explicitly enabled per-table in Supabase.
  • No realtime subscription in Conversations — the thread detail view was fully static after SSR; new emails only appeared after a full page reload.
  • No UPDATE listener in EmailsList — only INSERT was subscribed, so status changes and last_message_created_at bumps were ignored.

Changes

app/api/webhooks/inbound-email/route.ts

Always update thread.last_message_created_at (and optionally status) in a single call after every email insert — new thread or reply:

const threadUpdate: { last_message_created_at: string; status?: 'open' } = {
  last_message_created_at: emailData.created_at,
};
if (thread.status === 'closed') threadUpdate.status = 'open';
await supabase.from('thread').update(threadUpdate).match({ id: thread.id });

This fires a reliable thread UPDATE event on every inbound email, making the UPDATE_THREAD handler the primary realtime path — bypassing the fragile per-table INSERT event delivery.

components/organization/sidebar/EmailsList.tsx

  • Added UPDATE listener alongside INSERT on the thread channel.
  • UPDATE_THREAD reducer handles: remove thread if status no longer matches the active filter, add it if it now does, otherwise update-in-place and re-sort by last_message_created_at desc.
  • INSERT_THREAD now deduplicates: if the thread was already added via the UPDATE path (or a reconnect replay), the INSERT is a no-op.

components/organization/conversation/Conversations.tsx

  • Conversations lifted into local useState (seeded from SSR prop).
  • Subscribes to email INSERT filtered by thread_id; new messages append in real time with deduplication.
  • Scroll-to-bottom effect now triggers on every conversations state change, not just on mount.
  • Cleanup nulls channelRef before calling unsubscribe() to avoid stale-callback races.

💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

@vercel
Copy link
Copy Markdown

vercel Bot commented Mar 1, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
answerify Ready Ready Preview, Comment Mar 1, 2026 1:14pm

…view

Co-authored-by: harshithpabbati <43822585+harshithpabbati@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix realtime updates for emails list and threads Fix broken realtime updates in sidebar EmailsList and thread Conversations Mar 1, 2026
…mail insert

Co-authored-by: harshithpabbati <43822585+harshithpabbati@users.noreply.github.com>
Copilot AI changed the title Fix broken realtime updates in sidebar EmailsList and thread Conversations Fix realtime updates for sidebar EmailsList and thread Conversations Mar 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants