Communications

Languages

← Back to Communications

Two questions matter for every outbound guest message:

  1. What language does the guest speak? — the detector
  2. What language do we reply in? — the outbound decision

Both are codified in one place in the codebase: server/services/operations/_helpers.ts (functions detectGuestLanguage, pickOutboundLanguage, resolveOutboundLanguageForReservation). The full reference doc is at docs/language-resolution.md. This page is the operator-facing summary.

Detecting the guest's language

In priority order (top wins):

# Signal Source
0 Operator override Auto (XX) dropdown on the reservation → reservations.languageOverride
1 Most recent inbound message's detected language messages.detectedLanguage (LLM-tagged at arrival)
2 Guest country Country → language map (SK→sk, BG→bg, UA→uk, RU→ru, …)
3 Phone-number prefix +421→SK, +49→DE, +33→FR, … then country → language
4 NULL Caller decides what to fall back to

What's NOT a signal (intentionally)

  • The host's recent reply language — REMOVED. The host writes in whatever language the operator chose; that shouldn't speak to what the guest speaks.
  • rawJson.guest.language from Booking.com directly — REMOVED. Booking.com reports the guest's UI language, not their actual spoken language. Country is the stronger signal.
  • Voting across many guest messages — REMOVED. Most-recent inbound wins.

These exclusions were learned from real incidents on 2026-05-08 (the "Marina Russian-bug" and the "Martina 1-EN-message bug").

Picking the outbound language

Inputs:

  • guestLang — output of the detector
  • teammateCommLang — the responsible teammate's language column (e.g. Peter has en)
  • noTranslateLanguages — the teammate's noTranslateLanguages JSON array (e.g. ["sk","cs"])

Rule (one sentence):

If the guest's language matches the teammate's comm language OR is in the teammate's noTranslateLanguages list → write in the guest's language. Otherwise → write in the teammate's comm language.

Worked examples (Peter as operator: teammateCommLang=en, noTranslateLanguages=['sk','cs'])

Guest language Reply in
en en (matches Peter's comm language)
sk sk (in noTranslate list)
cs cs (in noTranslate list)
de en (Peter's comm language)
ru en (Peter's comm language)
null en (falls back to teammate's comm language)

Settings sources

  • Per teammateteammates.language (string) + teammates.noTranslateLanguages (JSON array). Edit in Team & Account → Teammates.
  • Tenant default (when no teammate is assigned to the reservation) — tenant_default_target_language + tenant_no_translate_languages rows in configurations. Edit in Settings → Tenant Configuration.

Operator override

If you want to force a specific language for a guest — e.g. they've explicitly asked for English even though they're from Bulgaria — set the Auto (XX) → en override on the reservation. This becomes priority #0 in the detector and beats every other signal.


  • #156 — synthetic system messages no longer pollute language detection.
  • #182 — cleaner WA walkthrough mixed-language fix (was sending Slovak scaffolding + cleaner-language labels in one message).
Source: the FlatsBratislava operator manual.