Skip to content

Linking Conversations to Leads ​

By default, an inbound message creates a thread keyed by the raw provider id (e.g. whatsapp:447700900000). The thread is anonymous in the sense that it has no application context. Linking ties it to a parent or a lead so the message history shows alongside the application record.

Three ways a thread gets linked ​

  1. Automatic by phone match — WhatsApp inbound from a phone we already have on a parent's profile (E.164-normalised). The new message lands on the existing parent's thread.
  2. Automatic by Page-Scoped ID — Messenger inbound from a Page-Scoped ID (PSID) we've seen before for that same Page. Threaded by PSID.
  3. Manual link — you click Link to lead in the thread header, search the roster, pick a parent or applicant.

Once linked, the conversation key flips from whatsapp:447700900000 to whatsapp:42 (where 42 = the parent's id). All future inbound from that phone, on that channel, joins the same thread.

Linking creates parents ​

Manually linking to a lead that has no parents rows yet will:

  • Create a parents row from the lead's parent fields (lead.parent_name, parent_email, parent_phone).
  • Link the new parent into the lead's family via family_members.
  • Bind the conversation to that parent.

This is the same dedupe logic forms use, so a parent who fills out a form and later WhatsApps you ends up as a single record either way.

Unlinking ​

The same header has an Unlink option (for admins). Unlinking reverts the conversation key to the raw provider id. The history of past messages doesn't move — only future inbound starts a new thread.

The parent isn't deleted; just the conversation binding is removed.

"Create enquiry from this conversation" ​

For brand-new contacts who came in cold via WhatsApp, the thread header offers a shortcut: Create enquiry. This:

  1. Creates a new enquiry (lead with roster_type = enquiry) using the parent's name + phone.
  2. Auto-links the conversation to the new lead.
  3. Drops you on the new lead's page with the conversation visible in the side rail.

The fields auto-fill from whatever the conversation already knows (sender name, profile picture, phone). You can edit them on the new lead's page.

How does the inbox find the right thread? ​

For each incoming webhook, the channel handler:

  1. Normalises the sender identity (E.164 for phone-based; openid for WeChat; psid for Messenger; igid for Instagram).
  2. Calls ParentService::findOrCreate(<email-or-phone>) — match-or-create.
  3. Builds a ConversationKey('<channel>', <parent_id-or-raw>).
  4. Inserts the inbound row.
  5. Bumps the unread count + fires push notifications.

All five steps happen inside the webhook handler — there's no separate background reconciliation job to wait on.

Multiple channels for the same parent ​

Once a parent is linked across channels, the inbox shows all their threads as siblings under the same parent header. Each channel keeps its own thread (replies fan out per-channel, as enforced by platform rules) — but the application context (linked lead, family, notes) is shared.

Kinderpedia Admissions Help Center