Skip to content

Conversations & Threads ​

The inbox is a three-pane layout: a 60px channel rail on the left, a 320px conversation list in the middle, and the open thread + composer on the right.

Conversation key ​

Every conversation is identified by a key in the form <channel>:<id>:

  • whatsapp:447700900000
  • messenger:psid_1234567890
  • instagram:igid_abc
  • wechat:openid_xyz
  • telegram:chatid_789
  • viber:viberid_456

The <id> is the parent's id once we've linked the thread to a parent (so all channels for the same parent share that id), or the raw provider id otherwise. The conversation list de-duplicates against this key.

Statuses ​

A conversation is always in one of four states (chat_conversation_states.status):

StateWhat it meansHow to get there
OpenDefault — visible in the main view, contributes to unread countAuto-set on any inbound message
SnoozedHidden from the main view until snooze_until passesSnooze button on the thread header
ClosedResolved; archived from the main viewClose button — won't auto-reopen unless a new inbound message arrives
BlockedSender is on the school blocklistUse the Block button (admins only)

If a snoozed conversation passes its deadline, the inbox auto-reopens it on the next poll (or via the app:chat:reopen-snoozed cron for schools nobody's looking at). Reopens fire an audit-log entry with the row count flipped.

Filters ​

The top filter bar exposes:

  • Status — Open / Snoozed / Closed / Blocked (single-select)
  • Channel — All / WhatsApp / WeChat / Messenger / Instagram / Telegram / Viber (multi-select)
  • Assigned to — Anyone / me / specific staff member (placeholder for upcoming feature)
  • Search — full-text search over message body + parent name

The status filter remembers your last choice via chat_inbox_preferences so refreshing doesn't lose it.

Unread badge math ​

The header pill shows the count of conversations with at least one unread message in your permitted channels — not just total unread messages. A single WhatsApp thread with 15 unread bubbles counts as 1. Reading the thread marks all messages within it as read.

Message order ​

Each thread renders messages oldest → newest, with date separators (Yesterday, Mon 12 May). Long lists virtualise after 200 rows so very chatty conversations don't slow down the page.

Outbound bubbles you sent show:

  • A delivery indicator at the bottom-right of the bubble:
    • 🕐 Sending — accepted by Kinderpedia, queued to the platform
    • ✓ Sent — platform accepted
    • ✓✓ Delivered — the recipient's device acknowledged
    • ✓✓ blue Read — the recipient opened it (WhatsApp / Telegram only)
    • ⚠️ Failed — see the bubble's error tooltip; the message stays in the thread for you to retry

Failed outbound persists across page refresh so you don't lose context.

Deleting messages ​

A staff member with chat.manage can soft-delete an individual outbound bubble (it disappears from the thread but is retained for audit purposes). Inbound messages can't be deleted — only the entire conversation can be archived via "Close".

Kinderpedia Admissions Help Center