Skip to content

Phone Line Labels

The phone line labels feature enriches SMS messages with display context for organizations that use multiple phone numbers. Outbound messages show a label identifying the sending line. Inbound messages reveal the receiving platform number on hover.

Both fields are computed server-side on every read — they are not stored in the database.

Two fields on the Message struct handle display enrichment:

src/mods/messaging/types/message_type.rs
/// Outbound SMS: org line friendly name, or formatted number.
#[serde(default)]
pub phone_line_label: Option<String>,
/// Inbound SMS: platform number that received the message.
#[serde(default)]
pub receiver_number_display: Option<String>,

These fields default to None in Message::from_model() and are populated by the enrichment service before the message reaches the client.

enrich_message_display_service.rs provides two entry points:

FunctionUse case
enrich_message_display(msg)Single message — used after send, webhook receipt, status update
enrich_messages_display(&mut msgs)Batch — used when loading a contact’s message history
// Pseudocode — src/mods/messaging/services/enrich_message_display_service.rs
fn apply_phone_display(msg: &mut Message, phones: &HashMap<Uuid, PhoneModel>) {
if msg.channel != Sms { return; }
match msg.direction {
Outbound => {
// Use friendly_name if set, otherwise format the raw number
msg.phone_line_label = phone.friendly_name
.filter(|s| !s.trim().is_empty())
.unwrap_or_else(|| format_e164_for_display(&phone.number));
}
Inbound => {
// Show which platform number received this message
msg.receiver_number_display = format_e164_for_display(&phone.number);
// Fallback: use msg.to_address if phone_number_id is missing
}
}
}

Batch optimization: enrich_messages_display collects unique phone_number_id values into a HashSet, runs a single SELECT * FROM phone_number WHERE id IN (...) query, then enriches all messages in memory. Query count is O(1) regardless of message count.

The enrichment service is called in these locations:

Call siteEnrichment type
get_contact_messages_serviceBatch — full conversation load
send_message_apiSingle — after creating outbound message
twilio_events_apiSingle — inbound SMS, status updates
resend_events_apiSingle — inbound email, status updates
update_message_status_serviceSingle — delivery status changes

format_e164_for_display() in src/shared/utils/format_e164_for_display.rs converts raw E.164 numbers into readable formats:

InputOutput
+17865551234+1 (786) 555-1234
7865551234(786) 555-1234
+442071838750+442071838750 (non-US passthrough)

publish_message_service.rs provides a shared helper that enriches a message before broadcasting it over WebSocket:

src/mods/messaging/services/publish_message_service.rs
pub fn publish_org_message_payload(
org_id: Uuid,
event_type: &str, // "messaging.message.new" or "messaging.message.status"
message: &Message,
)

All webhook handlers and the send endpoint call this function instead of manually serializing and publishing. The message payload includes phone_line_label and receiver_number_display so the frontend renders labels immediately without a re-fetch.

In message_entry_component.rs, the MessageEntry component renders enrichment data:

Outbound SMS — a small label appears below the chat bubble:

if let Some(ref line) = phone_line_label {
p {
class: "text-[10px] text-muted-foreground/75 truncate text-right mt-0.5 mr-1",
"{line}"
}
}

Inbound SMS — a tooltip wraps the bubble showing the receiving number on hover:

// Tooltip text: "Received on +1 (786) 555-1234"
Tooltip { side: TopLeft, "{tooltip_text}" }
FilePurpose
src/mods/messaging/types/message_type.rsphone_line_label and receiver_number_display fields
src/mods/messaging/services/enrich_message_display_service.rsSingle and batch enrichment
src/mods/messaging/services/publish_message_service.rsRealtime publish helper
src/shared/utils/format_e164_for_display.rsE.164 → display formatting
src/mods/messaging/components/message_entry_component.rsChat bubble label and tooltip
src/ui/tooltip_ui.rsTopLeft and TopRight tooltip variants