Skip to main content

Branch Bot Response Logic — Customer/Contact Field

Product Requirements Document — ported from Confluence (last modified 2026-04-16) on 2026-07-27. Ported, not re-authored: the substance is the PM's. Two editorial changes were required and are both declared below — the source's two overlapping story sets were merged into one canonical §8 table, and stable composite story ids were assigned. Every conflict the merge exposed is recorded in Open Questions rather than silently resolved.

PM: Dimas Fauzi Hidayat · Designer: Wulan Febyazzahra Putri (Bulan) · QA: Muhammad Izzul · PMM: Yosephine Dhisaclara (Ocie) · Product module: Bot & Automation · Type of work: Feature Improvements · Confluence team field: Hadiningbot

Overview

Bot builders cannot branch conversation flows on Customer/Contact attributes, so every "validate this customer" use case forces a workaround — custom logic, or an External API node fetching from the CDP by hand. That blocks Qontak One migration and leaves the platform unable to comply with META's transition from raw phone numbers to BSUID.

This PRD extends Branch Bot Response with a new condition type, Customer Field. A bot builder picks a field from a CDP-driven schema, picks an operator appropriate to that field's type, and enters or selects a value — three clicks, no code. At runtime the bot maps the channel identifier to the contact's BSUID record, fetches their attributes from the Mekari CDP in real time, and evaluates the configured conditions, falling back safely to the default branch when the customer is unknown, a field is missing, or the CDP is slow.

Evidence gap (declared). sources: [] — no product-intelligence-hub checkout was available when this PRD was ported, so none of its research is cited here. The evidence the PM did record lives in the Confluence source and is reproduced under Supporting Evidence: 21 CIDs on legacy systems, a support-ops need to auto-route non-paying users, and one usability finding. None of it is linked to a hub research doc, so treat the quantitative claims as PM-supplied rather than research-verified, and wire sources: + the reverse informs: link if the hub is later checked out.

Goals

Business

  • Enable full migration to Qontak One — remove the custom-logic blocker keeping 21 CIDs on legacy systems (North Star: 100% customer migration).
  • Ensure META compliance — move all bot identification from raw phone numbers to BSUID before the platform mandate breaks existing WhatsApp automations.
  • Improve operational efficiency — validation by configuration instead of an engineering request per use case.
  • Ecosystem readiness — a schema-driven foundation the bot engine can later point at Jurnal and Talenta fields.

User

  • Let non-technical admins build VIP routing and status checks without a line of code.
  • Give support agents pre-validated customer identities, cutting context-digging and AHT.
  • Always act on current real-time CDP data, so an inactive or blocked customer is never routed to a live agent by stale data.

Success metrics

Metric typePrimary KPIDefinition & goal
Primary (migration)% of legacy CIDs migratedCIDs using custom validation logic that move to Qontak One. Goal: 100% of target CIDs.
Primary (compliance)BSUID adoption rateShare of active Branch Bot nodes using BSUID/Customer Field logic instead of raw phone-number workarounds. Goal: 100% by Q4.
Secondary (efficiency)Reduction in bot setup timeTime saved deploying a validation flow by configuration vs. custom logic / an engineering request.
Secondary (productivity)Average Handling Time (AHT)Reduction in agent time spent manually verifying customer identity at the start of a chat.
QualitativeBot-builder CSATAdmin satisfaction with the 3-step inline condition editor.

Non-goals

  • No caching layer — the feature relies solely on real-time Mekari CDP availability.
  • No write-back to CDP — the bot reads attributes to branch; it never updates customer fields from this node.
  • Complex data types excluded — no branching on GPS coordinates, Signatures, Multiple Selection lists, File Uploads, or Dates.
  • No cross-object branching (v1) — Customer/Contact fields only; Account, Deal, and Ticket fields are out of scope.
  • No historical analysis — branches evaluate the attribute's current state, not "changed in the last 30 days".
  • No automated data cleanup — no duplicate-contact merging or CDP hygiene tooling.

Scope Changes

  • Backend — read-only CDP attribute-fetch service (core fields + custom attributes); parameters accepted and persisted on the V2 branch create and update paths; type-aware operator evaluation engine; 3s timeout enforcement with fail-safe routing.
  • Frontend — 3-step inline condition editor; dynamic operator mapping by field type; type-aware input validation; schema-driven field selector with unsupported types filtered out; empty state when the CDP integration is unavailable.
  • Design — Figma for the inline condition editor: Bot & AI, node 18415-118628.

Problem Alignment

Problem statement

Bot builders cannot currently branch flows based on Customer/Contact attributes, which forces workarounds or custom logic to validate and route customers, and leaves Qontak One unable to handle customer validation or comply with META's transition from phone numbers to BSUID.

Why it matters

User impact. The current Branch Bot experience makes it unclear who a conversation is about. Agents dig through context or external systems to confirm the right contact, which slows them down and raises the chance of the wrong account, wrong person, or wrong branch. Consistent Customer/Contact field logic means agents see which contact is in focus immediately, less back-and-forth clarification, and lower risk of sharing information about the wrong person.

Business impact. Ambiguity about the contact raises handling time, error risk, and support load. Re-verifying identities and correcting mistakes costs productivity and customer trust. Standardising this behaviour reduces AHT, decreases mis-identification errors and rework, improves data consistency across systems, and enables reliable attribute-based reporting and routing.

Insight. 21 CIDs run this use case on their chatbot outside Qontak One. Since the goal is to migrate every company to Qontak One, this is a must-have enabler.

Problem frequency & severity

AreaDescriptionRationale
User frequencyHigh (daily)Bot builders create flows daily and hit custom logic for every "validate customer" case.
User severityCriticalWithout it, bots cannot comply with META's shift to BSUID, potentially breaking existing WhatsApp automations that use phone number as the identifier.
Ops impactHigh costIdentity ambiguity raises AHT and forces agents to verify identities across external systems.

Supporting Evidence

  • User research — "Validating new or recurring customer makes bot more smarter and reliable."
  • Product analytics — 21 CIDs currently on the legacy system for this use case.
  • Support & ops — Qontak Support needs this flow to automatically route customers who are not existing/paid users.

All three are PM-supplied in the Confluence source with no linked research doc; see the evidence-gap note in the Overview.

Target population

CategoryDefinition
Primary usersBot builders / admins designing conversation flows in Qontak One, who need branching without code.
Secondary usersSupport agents, who receive conversations already validated and correctly routed.
Roles impactedCS managers & QA (reporting accuracy, standardised data); engineers (fewer custom-logic requests).
Behavioural triggersBot setup in the Flow Builder; compliance migration off the legacy platform; validation failure needing a recovery branch for an inactive/unrecognised customer.

Decision type

Commitment (must deliver) — tied to a platform-mandated change (META BSUID) and a core company goal (migration).

Strategic alternatives considered

OptionDescriptionWhy not chosen
Status quo (workarounds)Keep requiring custom logic or external middleware to validate before routing.Unsustainable — blocks CID migration and fails the urgent BSUID requirement.
Hard-coded field supportBranch on a few fixed fields (Name, Phone) with no flexible schema.Not scalable — manual engineering work for every new CRM field.
External API node onlyForce an External API node to fetch from CDP manually in every flow.Poor UX — high friction and added latency; the goal is configuration alone.

Final recommendation

Extend Branch Bot Response with a Customer Field condition type: bot builders select core and custom CDP attributes, apply type-aware operators, and route in real time without code. Confidence: High — it is the only path to BSUID compliance, it removes the primary migration blocker, and the schema-driven approach lets Jurnal/Talenta fields be added later without engine work.

Requirements

1. New condition type: "Customer Field"

Appears in the Branch Bot Response condition selector alongside existing types, only for Qontak One (where the CDP exists). Selecting it opens a 3-step inline editor:

Field selector (dropdown) — backed by a schema of available fields from the Customer/Contact service, not hard-coded in the frontend.

  • Default fields: Full Name, Owner, Assignee, Phone Number, Email, Username, Date of Birth, Sex, Job title, Domicile (address picker — Province, City, District, Sub-District, Zip Code).
  • Custom fields of type single-line text and dropdown selection only. Custom fields typed GPS, Signature, Multiple Selection, File Upload, or Date must be filtered out.

Operator selector — depends on the selected field's data type; operators that aren't meaningful for the type are hidden.

  • string: is, is not, contains, does not contain, starts with, ends with, is empty, is not empty
  • enum / status: allowed-value dropdown with is, is not
  • array / tags: contains, does not contain, contains any of, contains all of

Value input — text input for free text; dropdown for enumerations; for phone/BSUID, hint text explaining the expected format and its relation to META's BSUID.

2. Runtime evaluation logic

  1. Identify customer context — map the channel identifier (WhatsApp, Instagram, …) to the stored Customer record, which adopts BSUID per META. If no customer is found, Customer Field conditions fail safely or use the configured fallback.
  2. Fetch attributes — read-only retrieval of core fields (phone/BSUID, name, email), status, tags, and custom attributes; lookups must be efficient when a flow holds many conditions.
  3. Evaluate conditions — read the selected field, apply the operator against the configured value, respecting existing branch order: first match executes; otherwise the default/else branch.
  4. Errors & edge cases — no customer context → treat as no match or route to the configured fallback branch. Missing field → is empty is true, all other operators do not match. Unexpected data type → log internally, treat as no match, never break the flow.

Technical requirements

Backend & API. A read-only service retrieving core fields and custom attributes from the Customer/Contact service in real time. Fetch must complete within a 2–3 second window to avoid bot-flow timeouts. A type-aware operator engine supporting string, number, enum, and array operators. Error handling: no customer context → safe fail to default/else; missing value → is empty true and others false; API timeout >3s → user-facing error message.

Schema & data. Field catalogue driven by schema configuration, not hard-coded in the frontend; the schema fetcher filters complex types (GPS, Signature, Multi-selection, File Upload, Date); channel identifiers correctly mapped to the BSUID record.

Frontend. The 3-step condition builder; numeric-only enforcement on number fields; email format validation when the Email field is selected.

Configuration & extensibility. The field catalogue is environment/vertical-configurable, so new CRM attributes need no Branch code change. The condition builder is designed so Account, Deal, and Ticket fields — and later computed fields such as Last Purchase Date or Total Revenue — can follow the same pattern.

Security & privacy

  • PII protection — CDP data is used only for runtime evaluation and is never logged or persisted in bot flow logs.
  • Read-only access — the bot service account holds strictly read-only permission on the Customer service, preventing accidental data corruption.

Key features

FeatureDescription
3-step inline condition editorSelect field → select operator → enter/choose value, inline in the Branch Bot node.
Dynamic operator mappingOperators adjust to data type (Contains for tags vs. >= for numbers) to prevent invalid logic.
Real-time CDP integrationNative connector fetching customer attributes at the moment the conversation reaches the branch.
Type-aware validationFrontend validation enforcing data integrity (numeric-only for Age/Balance, email format for Email).

Constraints & limitations

CategoryDetails
Data type limitsIntentionally excludes GPS, Signatures, Multiple Selection, File Uploads, and Dates.
Read-only scopeReading only; the node cannot write back to CDP fields.
Object limitationCustomer/Contact fields only; Account, Deal, and Ticket are out of scope.
Latency & timeout2–3 second timeout on real-time CDP fetch; exceeding it triggers error or fallback so conversations never hang.
Network dependency100% dependent on real-time Mekari CDP availability — no local caching layer in this version.
Platform availabilityQontak One users with CDP integration enabled only.

Launch Plan

GA — full global launch: available to all Qontak One customers by 2026-04-01; UI configuration follows after that date.

Instrumentation Plan

EventPropertiesPurpose
branch_condition_createdfield_name, operator_type, is_custom_fieldWhich attributes (BSUID vs. Tags) matter most to users.
branch_logic_savedtotal_conditions, logic_type (AND/OR)Complexity of the routing rules being built.
runtime_fetch_latencylatency_ms, status (Success/Timeout)Critical — is the real-time CDP fetch hitting the 2–3s SLA.
runtime_branch_executedmatch_found (True/False), used_fallbackHow often the bot fails to identify a customer or hits the else branch.
runtime_error_triggerederror_type (Timeout, API Down, Data Mismatch)Technical blockers around the 2026-04-01 go-live.

Product Narrative

Before — custom logic and ambiguity. To check whether a customer is "VIP" or "Active", a bot builder at a large enterprise has to ask an engineer for custom code or wire up complex External API nodes; the process takes days. At runtime, if the bot can't identify the customer quickly, everyone goes down the same generic flow. Agents manually verify identities, AHT climbs, and high-value customers who expect a personalised experience get friction instead.

After — instant, configuration-based intelligence. The bot builder opens the Flow Builder, adds a Branch Bot Response node, and in three clicks — "Customer Status", "is", "Active" — has a high-stakes routing rule. At runtime the bot checks the Mekari CDP in real time; a VIP customer is recognised via BSUID, seen as Active, and routed straight to Priority Support. The agent receives the chat already knowing who the customer is. No code was written, no compliance rule was broken.

Pain points solved

StakeholderBeforeAfter
Bot builderCustom logic or External API nodes to identify customers; slow deployment, engineer-dependent.Customer validation fully by configuration in a 3-step inline editor.
Support agentHigh AHT manually verifying identity and digging for context in external systems.Chats arrive accurately routed and validated.
End customerGeneric bot flows and repeated identity questions.Faster, personalised service based on their real-time profile.
OrganizationMETA BSUID compliance risk; legacy bots cannot migrate.META compliance achieved and target CIDs unblocked for migration.

User Experience Flow

  • Entry point — the user adds a Branch Bot Response node; in "Add Condition" they can now pick Customer Field, opening the 3-step inline editor (field → operator → value).
  • Multiple conditions — Customer Field conditions combine with AND/OR logic consistent with the existing Branch condition builder (e.g. Customer Status is Active AND Tags contains "VIP").
  • Validation & guidance — Email must be a valid format when the Email field is selected; numeric fields disallow non-numeric input; BSUID/phone shows inline helper text explaining the BSUID change; if no customer fields are available (integration misconfigured), show a warning with a link to integration setup / docs.

8. System Flow + User Stories + ACs

Legend. Jira = the Story under Epic BOT-3864 that implements the row; means the requirement was never filed as its own Story (it rode along on a sibling Story or a Task). Src cites the Confluence origin: §n = graded section n, T-x.y = row x.y of the 1.1–7.1 table.

User StoryImportanceJira · Src · NotesAcceptance Criteria
[BBC-S01] — Config: Field Discovery

As a Bot Builder, I want to load available CDP fields so I can select them in my rules.
Must HaveBOT-3928 (Done) · §1• AC-1: Given the condition builder UI is opened, then call GET https://api.mekari.com/internal/qontak/customer/v1/contacts/field_properties?page=1&per_page=50.
• AC-2: Given the schema response returns, then populate the field selector using the returned schema.
[BBC-S02] — Config: Single Text Input UX

As a Bot Builder, I want to input exactly one text value per condition so my rules remain explicit.
Must HaveBOT-4043 (Done) · §1• AC-1: Given a text or multi_line_text field is selected, then display a standard text input restricted to a single string.
• AC-2: Given the operator is is empty or is not empty, then disable the value input entirely.
[BBC-S03] — Config: Single Dropdown Input UX

As a Bot Builder, I want to select exactly one option per condition to maintain simple rules.
Must HaveBOT-4044 (To Do) · §1 + T-4.1• AC-1: Given a dropdown field is selected, then populate a single-select dropdown using the options array from the field_properties response.
• AC-2: Given the operator is is empty or isn't empty, then disable the selection.
[BBC-S04] — Config: AND/OR Logic Grouping

As a Bot Builder, I want to combine multiple single-value conditions using AND/OR logic to build complex routing.
Must Have (§1) / Should Have (T-4.1) — see OQ-1BOT-4045 (To Do) · §1 + T-4.1• AC-1: Given a user needs to evaluate multiple values for a field, then allow them to add new condition rows.
• AC-2: Given multiple rows exist, then link them using AND or OR operators.
• AC-3: Given two conditions joined by AND and both are true, when the branch is evaluated, then the branch executes.
• AC-4: Given two conditions joined by AND and only one is true, when the branch is evaluated, then evaluation moves to the next branch.
[BBC-S05] — Config: Max Conditions Limit

As a Bot Builder, I want to be limited to a maximum of 3 conditions per rule so my configuration stays simple and predictable.
Must HaveBOT-4046 (Done) · §1• AC-1: Given the condition builder is opened, when the user has already added 3 condition rows, then disable or hide the "Add condition" control.
• AC-2: Given the limit is reached, then show helper/validation text indicating the maximum is 3 conditions.
[BBC-S06] — Config: DB Persistence

As a System, I want to save the rule to the database with trimmed whitespace to ensure data consistency.
Must HaveBOT-4047 (To Do) · §1• AC-1: Given the user configures a field, operator, and a single value, then save the configuration to the database.
• AC-2: Given a string value is saved, then ensure it is whitespace-trimmed before storage.
[BBC-S07] — Type-Aware Operator UI

As a Bot Builder, I want operators to change based on field type to prevent invalid logic.
Must HaveBOT-4048 (To Do, UX & Configuration umbrella) · T-1.2• AC-1: Given a field is selected in the editor, when the field is a string type, then string operators are shown (is, is not, contains, does not contain, starts with, ends with, is empty, is not empty).
• AC-2: Given a dropdown/enum field is selected, then only is and is not are offered, against the allowed-value list.
• AC-3: Given any field is selected, then operators not meaningful for that field's type are hidden.
[BBC-S08] — Type-Aware Input Validation

As a QA, I want to prevent invalid data entry to ensure runtime stability.
Should Have— (no dedicated Story) · T-2.1 + T-2.2• AC-1: Given the Email field is selected, when a value without an "@" is entered, then show a validation error and prevent saving the node.
• ERR-1: Given a numeric field is selected, when alphabetic characters are typed into the value input, then the UI blocks the input or shows an immediate numeric-only error.
[BBC-S09] — Schema Filtering of Unsupported Types

As a Bot Builder, I should not see complex fields that the bot cannot yet process.
Must Have— (no dedicated Story) · T-5.1• AC-1: Given the field dropdown is browsed, when the CDP schema is fetched, then GPS, Signature, Multiple Selection, File Upload, and Date fields are filtered out/hidden.
[BBC-S10] — Empty-State UX for Broken CDP Integration

As a Bot Builder, I want to be notified if the CDP integration is broken.
Could Have— (no dedicated Story) · T-7.1• AC-1: Given the CDP integration is misconfigured or unavailable, when the Customer Field selector is opened, then show a warning/empty state with a link to integration settings.
[BBC-S11] — Single-line Text Evaluation

As a Bot Builder, I want to route users on how a single-line text field compares to my configured value.
Must HaveBOT-4049 (Done) · §2All comparisons are case-insensitive and whitespace-trimmed.
• AC-1: ismatch if the CDP field exactly equals the configured value.
• AC-2: is notmatch only if it does NOT equal.
• AC-3: containsmatch if it contains the value.
• AC-4: does not containmatch only if it does NOT contain.
• AC-5: starts withmatch if it starts with the value.
• AC-6: ends withmatch if it ends with the value.
• AC-7: is emptymatch if null, undefined, or empty; whitespace-only counts as empty.
• AC-8: is not emptymatch if any non-whitespace character is present.
[BBC-S12] — Multi-line Text Evaluation

As a Bot Builder, I want to route users on how a multi-line text block compares to my configured value.
Must HaveBOT-4050 (Done) · §3All comparisons are case-insensitive and whitespace-trimmed.
• AC-1: ismatch if the full text block equals the value.
• AC-2: is notmatch only if it does NOT equal.
• AC-3: containsmatch if the block contains the value across its lines.
• AC-4: does not containmatch only if it does NOT contain.
• AC-5: starts withmatch if the block starts with the value.
• AC-6: ends withmatch if the block ends with the value.
• AC-7: is emptymatch if null or empty; whitespace/newline-only blocks count as empty.
• AC-8: is not emptymatch if any non-whitespace character is present.
[BBC-S13] — Dropdown Selection Evaluation

As a Bot Builder, I want to route users on how their dropdown field compares to my selected option.
Must HaveBOT-4051 (Done) · §4 + T-1.1Comparisons are case-insensitive and whitespace-trimmed against the API-fetched option.
• AC-1: ismatch if the CDP dropdown value equals the configured option.
• AC-2: is notmatch only if it does NOT equal.
• AC-3: is emptymatch if the dropdown field is null or missing.
• AC-4: isn't emptymatch if it contains any valid selection.
• AC-5: Given "Status" is set to is "Active" (T-1.1's VIP-routing case), when an Active customer reaches the node at runtime, then the Active branch executes.
[BBC-S14] — META BSUID Mapping

As a Bot Builder, I want to identify customers via BSUID to remain compliant with META.
Must Have— (no dedicated Story; delivered across the BE branch tasks) · T-1.3• AC-1: Given a customer reaches out via WhatsApp/Instagram, when the bot reaches the branch node, then it maps the channel identifier to the BSUID record in the CDP before evaluation.
[BBC-S15] — System: Runtime Execution & Guardrails

As a System, I want to evaluate incoming messages against the configured logic and fail fast on slow CDP calls, so the correct path triggers and the bot never freezes.
Must HaveBOT-4052 (To Do) · §5 + T-3.1• AC-1: Given an incoming message triggers the chatbot, then fetch the contact's CDP data and evaluate it against the configured rules sequentially.
• AC-2: Given multiple conditions exist, then evaluate AND/OR logic and execute only the first true branch.
• AC-3: Given a runtime evaluation requires a CDP fetch, then enforce a maximum timeout of 3 seconds.
• ERR-1: Given the CDP response exceeds the 3s SLA, then immediately route the user to the default/fallback branch.
• ERR-2: Given the field's data type is unexpected, then log the error internally, treat it as no match, and do not break the flow.
[BBC-S16] — Missing Customer Record Fallback

As a System, I want to handle unrecognised customers (new leads) safely.
Must Have— (no dedicated Story) · T-3.2• AC-1: Given a user interacts who is not yet in the CDP, when the bot evaluates a Customer Field condition, then treat it as "no match" and execute the Default/Else branch.
[BBC-S17] — Empty Field Evaluation

As a Bot Builder, I want to identify customers with missing data fields.
Should Have— (no dedicated Story) · T-3.3• AC-1: Given a customer record exists but the Email field is null/empty, when the condition is "Email is empty", then evaluation returns True and follows that branch.
• AC-2: Given a field is missing and the operator is anything other than is empty, then the condition does not match.
[BBC-S18] — Read-Only CDP Access

As a Security Officer, I want the bot to have read-only access to prevent data corruption.
Must Have— (no dedicated Story) · T-6.1• AC-1: Given the bot service is processing a branch node, when the request is sent to the CDP, then only GET requests are performed.
• ERR-1: Given any POST/PATCH is attempted against the CDP from this node, then it is blocked.

Future Considerations

  • Mekari cross-product branching — extend the condition builder to Jurnal (invoice status, payment terms) and Talenta (department, leave balance) fields.
  • Account & Deal level branching — beyond Customer/Contact to Account (B2B) and Deal/Ticket.
  • Computed/aggregated fields — branch on Total Revenue, Last Purchase Date, and similar.
  • Proactive caching — if the 2026-04-01 launch shows CDP latency issues, investigate a high-speed cache for frequently read routing attributes.

Open Questions

  • OQ-1 — AND/OR priority conflict (BBC-S04). The source grades it Must in §1 but Should Have as table row 4.1. Recorded as Must (the §1 grade, since §1 is what became the Jira Story) — PM to confirm. Material because BOT-4045 is still To Do and its grade decides whether the tail is blocking.
  • OQ-2 — numeric fields are specified but out of scope. Table rows 1.2 and 2.2 require numeric operators (>, >=) and numeric-only input for fields like "Age"/"Balance", and the Technical Requirements name a number operator family — but the §1 field catalogue supports only single-line text and dropdown custom field types. Either numeric fields are in scope (and the catalogue is incomplete) or BBC-S08's ERR-1 and part of BBC-S07 are unbuildable as written. Not resolved here.
  • OQ-3 — array/tags operators have no story. contains any of / contains all of appear in the operator list and the product narrative uses Tags contains "VIP", but no §1–5 section, no table row, and no Jira Story covers tag/array evaluation, and tags are not in the field catalogue. Either a missing story or dead specification.
  • OQ-4 — "fail safely" is under-specified for BBC-S16. The source alternates between "treat as no match" and "use a configured fallback branch". Whether the fallback is configurable per node, or is always the default/else branch, is never stated.
  • OQ-5 — the 2–3s SLA is stated three ways. "2-3 second window", "maximum timeout of 3 seconds", and "if the API times out (>3s)". BBC-S15 records 3s as the enforced limit; the 2s figure is unexplained.
  • OQ-6 — no test specs exist. Nothing in tests/ covers these composite ids, so no covers_acceptance_criteria traceability exists. QA ran as board tasks only (see the initiative README's QA Lane section).