Bot Applet
Overview
The Bot applet is where a tenant builds the menu-based chatbot that answers inbound
conversations in the Unified Contact Center
before, or instead of, a human agent. It is a TNT-ADMIN applet with two menu items — Bot and
Conversation Flow — and its own title bar reads Menu-Based Chatbot. A bot is a name and a
code linked to exactly one conversation flow; a flow is a set of elements (send a message,
wait for a reply, branch on the reply, hand over to an agent, and so on) joined by element
sequences that may carry conditions. Skills — the same bl_alg_cc_skill_hdr rows the contact
centre routes tasks with — are attached to bots and to message elements so that a hand-over lands
with the right team.
Nothing here posts a journal or touches stock. The applet writes the alg_bot_* tables through the
…/alg/bot/ API family; the conversation itself is driven by the contact-centre backend, which
calls the bot’s automation endpoints when a message arrives on an endpoint that has a bot linked
to it. The bot is linked to an endpoint in the Unified Contact Center, not here — see
Configuration.
Measured 2026-09-16: 3 active catalogue links across 3 tenants. The bundle is served from a
bucket root of its own (ucc-applet-custom-element/bot/production/), the one the repository’s
bin/production/bot_applet_publish.sh writes to. The repository’s last commit is 2024-11-19.
ElementTypeFactory maps no processor to them, and
the queue insert that would run them rejects the null event code. A flow that reaches either
element stops there. Details under Lifecycle and effects and Troubleshooting.Where it fits
| Direction | What | Why |
|---|---|---|
| Upstream | Unified Contact Center → Configurations → Virtual Contacts → Endpoint → Bot tab | The endpoint-to-bot link (bl_alg_cc_endpoint_bot_link, DEFAULT or SECONDARY) is what makes a channel start this bot. Without it the flow never runs. |
| Upstream | Unified Contact Center → template messages (bl_alg_cc_template_message_hdr) | A Send Message element can send a template message instead of plain text; the template and its language lines come from there. |
| Upstream | Unified Contact Center → automation rules (bl_alg_cc_automation_rule_hdr) | Assign To Agent and Invoke Automation Rule pick a rule code from that table. |
| Shared | Skills (bl_alg_cc_skill_hdr) | Created and edited here under a bot’s Skill tab, read by the contact centre’s skill-based task assignment. |
| Downstream | Unified Contact Center inbox and task queue | Assign To Agent creates a bl_alg_cc_task_hdr row and enqueues SKILL_BASED_TASK_ASSIGNMENT_PROCESSOR; the agent then sees the conversation as a task. |
| Runtime | Contact-centre message handlers (BotHandler, SesBotDispatcher) and the tenant job queue | Every inbound message on a bot-linked endpoint is turned into a call to …/alg/bot/bot-cf-automation/bot-root-element or …/bot-next-element. |
Screens and menus
The applet mounts at applets/tnt/ailedger/bot (app.routing.ts L20) and redirects a bare visit
to Bot. Every list is an ag-grid with the standard search bar (main field = name; advanced search
by Name and Code), a paginator, and the two-column layout toggle.
Bot
| Screen | What is on it |
|---|---|
| Bot Listing | Columns Name, Code, Description, Creation Date, Updation Date (newest first). Click a row to edit; the add button opens Create Bot. |
| Create Bot | Bot Name, Bot Code, Bot Description, Master Bot checkbox, Conversation Flow drop-down. Create saves the bot and, if a flow was chosen, a MAIN bot-to-flow link. |
| Bot Edit — Main tab | The same fields (the flow drop-down is labelled with an asterisk here but is not validated), a created-by/updated-by block, SAVE (enabled once the form is dirty) and a red Delete button with no confirmation dialog. |
| Bot Edit — Skill tab | The skills linked to this bot (Name, Code), each row with a delete icon that removes the bot-skill link. The add button opens the skill picker. |
| Skill (picker) | Every skill in the tenant that is not yet linked to this bot, with checkbox selection; ADD creates one bot-skill link per ticked row. Its own add button opens Create Skill; clicking a row opens Skill Edit. |
| Create Skill | Skill Name, Skill Code, Skill Description. Creates the skill only — it is not linked to the bot until ticked and added from the picker. |
| Skill Edit | Name, code, description, a Parent Skill drop-down (required) and Delete. Deleting a skill removes its link rows first (SkillHdrController.java L147), unlike deleting a bot. |
Conversation Flow
| Screen | What is on it |
|---|---|
| Conversation Flows listing | Name, Code, Description, Creation Date, Updation Date. |
| Create Conversation Flow | Conversation Flow Name, Conversation Flow Code, Conversation Flow Description. |
| Conversation Flow Edit — Main | The three fields, created-by block, Delete. |
| Conversation Flow Edit — Elements | The flow’s elements (Name, Element Type, Link Type), ordered ROOT → NODE → LEAF and then by update date. Search by name, code or element type. Add opens Create Conversation Flow Element; a row opens Edit Conversation Flow Element. There is no delete — the grid’s delete handler is commented out (cf-element.component.ts L204–L206). |
| Conversation Flow Edit — Elements Sequence | The flow’s edges (From Element, Element Type, To Element, Element Type), oldest first. Add and edit only; no delete (cf-element-sequence.component.ts L1596–L1598). |
| Conversation Flow Edit — Messages Flow | A tree editor (ngx-graph, top-to-bottom) of plain-text messages: Fit View, Create a New Message (the first message needs no parent; every later one needs a selected parent node), Edit the Message, Delete the Message (removes the node and every descendant). The tree is held in the browser until the flow’s SAVE, which creates, renames or deletes alg_bot_cf_message_dfn rows and rewrites the alg_bot_cf_message_link / alg_bot_cf_messages_sequence edges. This tree is separate from the Elements model: nothing in the runtime reads it (no processor queries the messages-sequence tables). |
A Message menu item and its listing/create/edit screens exist in the code but are commented out
of both the routes and the menu (app.routing.ts L34–L37, menu-items.ts L20–L25); the message
definitions are reached only through the Send Message element forms.
Settings and personalization
Settings opens the shared settings shell with the applet’s own group System Configuration → Field Settings, Default Selection, plus the shell’s hard-coded links. Of those, Applet Access, Permission Set, User Permission, Team Permission, Role Permission and Triggers (webhooks) have routes; Role Pricing Scheme Linking, Permission Wizard, Release Notes, Applet Log and Reset Applet State do not and land on the 404 page. Personalization lists Field Settings (no such route under personalization → 404), Default Selection, Sidebar, and three links that go straight to 404 (Preset Themes, Color Assist, Easy Navigation).
Configuration
Before you can use it
| You need | Where it is set | Why |
|---|---|---|
| A virtual contact with an endpoint for the channel, and that endpoint linked to the bot | Unified Contact Center → Configurations → Virtual Contacts → Endpoint → Bot tab (Add Bot writes a SECONDARY link; Edit has a Default checkbox that turns it into the one DEFAULT link — bot-edit.component.ts L95–L111 in the UCC repository) | BotHandler.handleIncomingMessage runs a bot only for a DEFAULT link on the endpoint the message arrived on, and only when the session is new or already in the BOT state (BotHandler.java L44–L47). SECONDARY links are consulted on the outbound path (L77–L80). |
A conversation flow with one element flagged First Element (link type ROOT) | This applet → Conversation Flow → Elements | The root query (BotCFAutomationService.java L32–L43, L94–L103) finds the element with link_type = 'ROOT' in the bot’s MAIN flow; no root, no queue row, and the start call returns an empty element. |
| The bot linked to that flow | This applet → Bot → Conversation Flow drop-down | The same query joins through alg_bot_conversation_flow_link with link_type = 'MAIN'. |
| The bot’s job processors registered | Backend (JobProcessorClassName.java L470–L476, L648, L666) | BOT_CF_ELEMENT_PROCESSING_QUEUE_PROCESSOR and the seven element processors are built into the API; nothing per tenant enables them. BOT_CF_EXPIRED_TASKS_PROCESSOR is a separate processor that sweeps expired wait states — how it is scheduled per tenant was not traced this run. |
| Template messages, automation rules and skills | Unified Contact Center (templates, rules); this applet or the contact centre (skills) | Picked from drop-downs on the element forms; the drop-downs are empty until those exist. |
Server-side permissions on the alg_bot_* tables, or tenant owner/admin | Tenant Admin → permission sets | Every controller checks isUserOwnerOrAdmin first, then an OWNER/ADMIN/CREATE (or UPDATE, DELETE, READ) triple from TntAlgPermissions (BotHdrController.java L71–L76). |
Applet settings
Settings here are the applet-local Field Settings and Default Selection screens; the applet
does not embed the shared FieldConfigurationComponent and has no inline settings gear.
No setting passes the four proofs. Routes and settings components were checked at commit
77754d6af6d8c4e1c27b739a83a72141ac2fc93e:
- Field Settings renders eight
mat-slide-toggles (Unit Discount, SST/VAT/GST, WHT, Blanket Order, Segment, G/L Dimension, Profit Center, Project) with no form binding and a SAVE button with no handler (field-configuration.component.htmlL2, L14–L46;field-configuration.component.tshas no store dispatch). Copied from a document applet; nothing in the bot reads any of them. - Default Selection (and Personalization → Default Selection) writes
DEFAULT_BRANCHandDEFAULT_LOCATIONinto anappletContainerthat is declared as an@Input()on a component the router creates directly (default-settings.component.tsL83–L94). The input is never bound, so the first change of either drop-down throws onthis.appletContainer.bl_applet_exts, and SAVE emits to nobody. Even if it saved, no component or service in the applet reads either key.
No runtime read of bl_applet_ext for this applet was found in the backend (getValue_json().containsKey(
grep over javasdk and akaun-api), and no app_cfg_main code for it.
Settings in other applets that control this applet
| Setting | Where it is set | Effect here |
|---|---|---|
Endpoint-to-bot link type DEFAULT / SECONDARY | Unified Contact Center → Virtual Contacts → Endpoint → Bot | Decides whether an inbound message on that endpoint starts this bot (see above). |
| Template message and its language lines | Unified Contact Center → template messages | A Send Message element of type Template Message requires a template; if the template has language lines, a language choice becomes mandatory on the element form. |
| Automation rule codes | Unified Contact Center → automation rules | The rule the Assign To Agent / Invoke Automation Rule element writes into the task (TaskService.java L500; default SKILL_BASED_TASK_ASSIGNMENT_AUTOMATION_RULE when absent). |
Feature visibility and permissions
bl_applet_client_side_perm_dfn holds no rows for applet code Bot (queried 2026-09-16), so
the Applet Access screen has nothing to grant and no menu item, tab or button in the applet is
hidden by a client-side permission.
Access is decided by the backend, per table, with the owner/admin bypass. The permission families
(each with OWNER, ADMIN, CREATE, UPDATE, DELETE, READ; ALG_BOT_HDR also has MEMBER) are
API_TNT_DM_ALG_BOT_HDR, …_ALG_BOT_CONVERSATION_FLOW, …_ALG_BOT_CONVERSATION_FLOW_LINK,
…_ALG_BOT_CF_ELEMENT_HDR, …_ALG_BOT_CF_ELEMENT_LINK, …_ALG_BOT_CF_ELEMENT_SEQUENCE,
…_ALG_BOT_SKILL_LINK, …_BL_ALG_CC_SKILL_HDR, …_ALG_BOT_CF_ACTION, …_ALG_BOT_CF_MESSAGE_DFN,
…_ALG_BOT_CF_MESSAGE_LINK, …_ALG_BOT_CF_MESSAGES_SEQUENCE, …_BL_ALG_CC_ENDPOINT_BOT_LINK and
…_ALG_BOT_TO_BOT_LINK (TntAlgPermissions.java L492–L576; 103 rows seeded in app_perm_dfn,
all ACTIVE). Listings return a row the caller may not read as a stub whose status is
PERMISSION_DENIED (BotHdrController.java L49–L58), so a user with partial rights sees blank
rows rather than an error. The automation endpoints (bot-root-element, bot-next-element,
bot-handover, handover/agent-to-bot) require ALG_BOT_HDR OWNER, ADMIN or CREATE
(BotCFAutomationController.java L38–L44); the message handlers call them with a
platform-generated token, not the agent’s.
Fields
Bot (Create Bot / Bot Edit → Main)
| Field | Meaning | Required | Notes |
|---|---|---|---|
| Bot Name | Display name | Yes | alg_bot_hdr.name |
| Bot Code | Short code | Yes | alg_bot_hdr.code; not checked for uniqueness by the DCO (BotHdrDataConsistencyObject.java validates guid and revision only) |
| Bot Description | Free text | No | |
| Master Bot | Checkbox | No | Saved to alg_bot_hdr.master_bot. No backend code reads the column (grep over javasdk and akaun-api); the alg_bot_to_bot_link table and its master/slave permissions exist but no screen writes them. |
| Conversation Flow | Drop-down of flows (name, code; server-side search) | No on create; asterisk on edit but not validated | One MAIN link per bot. On edit, choosing a flow updates the existing link if there is one, otherwise creates one (bot.effects.ts L95–L117). Clearing the field does not delete the link. |
Skill (Create Skill / Skill Edit)
| Field | Meaning | Required | Notes |
|---|---|---|---|
| Skill Name | Yes | bl_alg_cc_skill_hdr.name | |
| Skill Code | Yes | ||
| Skill Description | No | ||
| Parent Skill | Drop-down of skills (edit only) | Yes on edit | bl_alg_cc_skill_hdr.parent_guid. A skill created here has no parent until it is edited, and the edit form will not save without one. Sub-skills of the From Element Skill are what the sequence form offers as To Element Skill. |
Conversation Flow (Create / Edit → Main)
| Field | Meaning | Required |
|---|---|---|
| Conversation Flow Name | Yes | |
| Conversation Flow Code | Yes | |
| Conversation Flow Description | No |
Element (Create / Edit Conversation Flow Element)
The common fields first; the element type then adds its own block. Creating an element writes an
alg_bot_cf_element_hdr row and an alg_bot_cf_element_link row for this flow (name and code are
both set to the Element Name; cf-element-create.component.ts L146–L158). The type-specific
values go into the link’s property_json.
| Field | Meaning | Required | Notes |
|---|---|---|---|
| Element Type | One of the nine types below | Yes | Read-only on edit. |
| Element Name | Yes | Also used as the code. | |
| First Element | Checkbox, shown only for Send Message, Send Message And Wait Reply and Starting Point | No | Ticking it writes link_type = 'ROOT' and demotes the previous root to NODE (element.effects.ts L646–L669). A flow may have one root. |
| Element Description | No |
| Element type | Its own fields | property_json written | What the runtime does with it |
|---|---|---|---|
| Starting Point | None (the component has no controls) | {messageGuid} pointing at nothing — the create screen calls the Send Message sub-form, which is not rendered for this type (cf-element-create.component.ts L502–L509, template L698–L705) | Records the event and queues every next element; sends nothing (BotCfElementStartingPointProcessor.java L41–L53). |
| Send Message | Message Name*, Message Code*, Message Description, Message Type* (Text / Template Message); Text* for the first, Template Message drop-down* plus a language choice (required when the template has language lines) and a preview for the second | {messageGuid}; the message is an alg_bot_cf_message_dfn row (message_type, value_string or template_message_guid + language_code) | Sends the text or template on the conversation’s channel, records the event, queues every next element (BotCfElementSendMessageProcessor.java L61–L100). |
| Send Message And Wait Reply | The Send Message fields plus Timeout* and Unit* (Days / Hours / Minutes / Seconds) | {messageGuid, timeoutValue, timeoutUnit} | Sends, then queues only the first next element with an expiry of now + timeout and stops until the customer replies (…SendMessageAndWaitReplyProcessor.java L117–L127). |
| Split Control | Default Message If No Condition Match*, Timeout Message* | {defaultCondition, timeoutMessage} | Compares the customer’s reply with each outgoing sequence’s conditions; queues the matches; if none match, sends the default message and waits again; on expiry sends the timeout message (…SplitControlProcessor.java L65–L115). |
| Time Condition | Timeout Message* | {timeoutMessage} | Evaluates each outgoing sequence’s time condition against the clock in Asia/Kuala_Lumpur and queues the matches (…TimeConditionProcessor.java L76–L88; BotCfConditionMatchService.java L111–L158). |
| Assign To Agent | Assignment Type* (Skill Based / Random Assignment), Automation Rule* (rule codes) | {assignmentType, automationRule} on create; {assignment_type} only on edit (cf-element-edit.component.ts L959–L965) | Looks up the skill of the latest message element in this conversation and creates a task carrying SKILL_GUID, ASSIGNMENT_TYPE and AUTOMATION_RULE_CODE, then enqueues skill-based assignment (…AssignToAgentProcessor.java L48–L59; TaskService.java L488–L500). |
| Invoke Automation Rule | Automation Rule* | Nothing type-specific is written on create (the create switch has no case for this type, L453–L510), and the edit screen has no block for it | Same as Assign To Agent (…InvokeAutomationRuleProcessor.java L47–L56); the rule falls back to SKILL_BASED_TASK_ASSIGNMENT_AUTOMATION_RULE. |
| Execute Action | Action Name*, Action Code*, Action Description | {actionGuid}; an alg_bot_cf_action row holds the name, code and description and nothing else | No processor — see Lifecycle. |
| Move To Another Flow | Conversation Flow drop-down* (the current flow is excluded) | {cfGuid} | No processor — see Lifecycle. |
Element Sequence (Create / Edit Element Sequence)
| Field | Meaning | Required | Notes |
|---|---|---|---|
| From Element | Drop-down of this flow’s elements, minus Assign To Agent; while the flow has no sequence yet, only the root element is offered, and the form shows Please Set An Element As Root Element First if there is none (cf-element-sequence-create.component.ts L1760–L1786, template L2015–L2017) | Yes | |
| To Element | Drop-down fed by GET …/bot-cf-element-sequence/availableNextElementsGuids: every element of the flow not already a target of From, plus any Send Message / Send Message And Wait Reply ancestor (loops back to a message are allowed; BotCfElementSequenceUow.java L288–L330). The drop-down then filters: from a Send Message And Wait Reply only Split Control or Time Condition may follow; from any other non-split element, Split Control may not follow (cf-element-dropdown.component.ts L1336–L1370) | Yes | |
| From Element Skill | Skill drop-down, shown when From is a message element; on create also for Starting Point | Yes when shown | Saved into the from element link’s property_json.skillGuid (element.effects.ts L671–L694). This is the only place a skill is attached to an element. |
| To Element Skill | Skill drop-down, shown when To is a message element; offers the sub-skills of the chosen From Element Skill plus that skill itself | Yes when shown | Saved the same way on the to element. |
| Conditions | Shown when From is Split Control or Time Condition: one or more rows of Operator, Type (Text / Numeric / Datetime / Time) and Value; New Condition adds a row, the bin removes one (a lone row cannot be removed) | Each row’s three fields when shown | Saved as condition_json.conditions[] with left_hand_side (the from element), operator, right_hand_side_value_type (upper-cased type) and right_hand_side_value. Operators offered: Equal, Not Equal, Contains; for a Time Condition source: AFTER, BEFORE, AFTER_OR_EQUAL, AFTER_AND_BEFORE, with a time picker and AM/PM. |
Saving a sequence sets the from element’s link type to NODE (unless it is ROOT) and the to
element’s to LEAF if it has no outgoing sequence of its own (BotCfElementSequenceService.java
L66–L74). The sequence’s name, code and description are generated from the two element names.
Lifecycle and effects
This is a master-data and automation applet: no generic document, no *DataConsistencyObject
signums, no journal, no stock, no open queue. The DCOs for the bot tables validate presence of
guid and revision and the existence of referenced rows (bot, flow, element, skill), nothing
more.
What each screen writes
| Action | Endpoint(s) | Backend effect |
|---|---|---|
| Create bot | POST …/alg/bot/bots; POST …/bot-cf-link when a flow is chosen | alg_bot_hdr row; one alg_bot_conversation_flow_link row with link_type = 'MAIN'. |
| Edit bot | PUT …/bots; PUT or POST …/bot-cf-link | The link is updated in place when one exists, created otherwise. |
| Delete bot | DELETE …/bots/{guid} | The bot row only (BotHdrService.java L60–L66 → BotHdrUow.delete, L90–L105, which deletes the alg_bot_hdr rows it is given). Bot-to-flow links, bot-skill links and the contact centre’s endpoint-bot links survive and still point at the deleted guid. |
| Add / remove skill | POST …/bot-skill-link (one per ticked skill, failures swallowed — skill.effects.ts L867–L884); DELETE …/bot-skill-link/{guid} | alg_bot_skill_link rows. |
| Create / edit / delete skill | POST/PUT/DELETE …/skills | Delete removes the skill’s link rows first (SkillHdrController.java L147–L149). |
| Create / edit / delete flow | POST/PUT/DELETE …/conversation-flow | On edit, the Messages Flow tree is reconciled message by message (cf.effects.ts L345–L444). |
| Create element | POST …/bot-element-hdr, then POST …/bot-cf-element-link; PUT on the old root’s link when First Element is ticked | Header + link; root swap. |
| Edit element | PUT …/bot-cf-element-link, then PUT …/bot-element-hdr with the link’s name/code/description copied over (element.effects.ts L541–L566) | The Send Message / Execute Action sub-forms also PUT their message or action row. |
| Create / edit sequence | POST/PUT …/bot-cf-element-sequence; PUT …/bot-cf-element-link for each skill chosen | Sequence row; link-type promotion; property_json.skillGuid on the elements. |
How a conversation runs
- Start. An inbound message reaches the contact-centre message handler.
BotHandler.handleIncomingMessageloads the endpoint-bot links for the endpoint; if one isDEFAULTand the session is new (or already in stateBOT), it calls…/bot-cf-automation/bot-root-elementfor a new session, else…/bot-next-elementwith the received text, and marks the conversationBOT(BotHandler.javaL40–L70). For e-mail on Amazon SES,SesBotDispatchermakes the root call for a new thread whose endpoint has aDEFAULTlink (SesBotDispatcher.javaL35–L91). - Root.
bot-root-elementinserts the flow’sROOTelement intoalg_bot_cf_element_processing_queue(priority 1, 3 retries, expiry 9999-01-01), with the conversation, session, endpoint, channel and header inevent_properties; creates analg_bot_cf_conversation_instance_hdrrow; and enqueuesBOT_CF_ELEMENT_PROCESSING_QUEUE_PROCESSORon the tenant queue withlimit = 1(BotCFAutomationService.javaL53–L125;BotCFAutomationController.javaL31–L80). The event code comes fromElementTypeFactory, which maps seven of the nine types to a processor (ElementTypeFactory.javaL17–L44). - Step. The processing-queue processor selects the due rows for that conversation (
FOR UPDATE SKIP LOCKED) and calls each row’s element processor over HTTP with a platform token (BotCfElementProcessingQueueProcessor.javaL36–L64). Each element processor records analg_bot_cf_conversation_instance_eventsrow, does its work, then inserts its next element(s) into the same queue and enqueues the processing-queue processor again withlimit = number of next elements. Send Message And Wait Reply inserts only its first successor, stamped withelement_expire_time, and does not re-enqueue: the flow now waits. - Reply. The next inbound message goes to
bot-next-element, which stampsreceivedMessageinto the waiting queue row’sevent_propertiesand re-enqueues the processing-queue processor (BotCFAutomationController.javaL82–L118;BotCFAutomationService.javaL403–L419). The waiting element — normally a Split Control or Time Condition — now runs against the reply. - Branch. Split Control matches the reply against every outgoing sequence’s conditions
(
BotCfConditionMatchService.javaL19–L75):TEXTEqual / Not Equal (case-insensitive) / Contains;NUMERICEqual / Not Equal (unparseable reply → no match);DATETIMEEqual / Not Equal on the patternyyyy-MM-dd'T'HH:mm:ss.SSSX; aTIMEtype is not evaluated here and never matches. Any other operator on a known type counts as a match (default -> true). No match → the default message is sent and the element re-queued with its expiry. Time Condition uses the clock:AFTER,BEFORE,AFTER_AND_BEFORE(start-end),EQUAL,AFTER_OR_BEFORE,DATE(L116–L158); the UI’sAFTER_OR_EQUALis not among the backend’s cases and falls tofalse. - Hand over. Assign To Agent / Invoke Automation Rule find the latest event in this
conversation whose element is a message element and take that element link’s
property_json.skillGuid(SkillHdrUow.javaL298–L323); with a skill in hand they create abl_alg_cc_task_hdr(statusCREATED) and enqueueSKILL_BASED_TASK_ASSIGNMENT_PROCESSOR. With no skill,ifPresentdoes nothing and the conversation stays inBOTstate. An agent taking the conversation calls…/bot-handover, which deletes the conversation’s bot-queue rows and task-queue rows and assigns (or creates) the task to that agent (BotCFAutomationService.javaL440–L456);…/handover/agent-to-botrestarts the flow at the root. - Expiry.
BOT_CF_EXPIRED_TASKS_PROCESSORlocks queue rows whoseelement_expire_timehas passed, follows any outgoing sequence whose condition matches the literal texttimeout, then deletes the row (BotCfExpiredTasksProcessor.javaL79–L124).
Sending. Outbound text goes through SendMessageChannelEndpointFactory, which knows
WHATSAPP, WEB, TELEGRAM, LAZADA, FB_MESSENGER, SHOPEE and INSTAGRAM_CHAT
(SendMessageChannelEndpointFactory.java L40–L48). Template messages are expanded line by line,
media lines included, by BotCfElementHdrService.sendTemplateMessage (L67 onward).
The two dead element types. ElementTypeFactory.getElementProcessor returns null for
EXECUTE_ACTION and MOVE_TO_ANOTHER_FLOW. Every processor that queues a successor builds its
parameter map with ImmutableMap.Builder.put("eventCode", …) (BotCFAutomationService.java
L229–L231, L296–L298), which rejects a null value, so the preceding element’s processor fails at
the point of queuing either of these types; as a root they are refused by the UI and, if forced,
skipped (L105–L107). The alg_bot_cf_action row and the target-flow guid are stored and never
read by any processor.
Related applets
- Unified Contact Center — owns the endpoint the bot is linked to, the template messages and automation rules the elements pick from, the task queue a hand-over lands in, and the inbox where an agent sees the bot’s transcript. The bot is a configuration object of the contact centre; this applet is its editor.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| The bot never answers a new conversation | The endpoint has no DEFAULT bot link (a link added from the UCC endpoint’s Bot tab is SECONDARY until its Default box is ticked); or the bot has no MAIN flow; or the flow has no element flagged First Element. bot-root-element then inserts nothing and returns an empty element (BotCFAutomationController.java L49–L56). | Tick Default on the endpoint-bot link; pick a flow on the bot; tick First Element on a message or starting-point element. |
| The bot answered once and now ignores replies | The session is no longer in BOT state (an agent took it), or the waiting queue row expired and was deleted by the expired-tasks processor. | Use agent-to-bot hand-over to restart; give Send Message And Wait Reply a longer timeout. |
| The flow stops after a Send Message And Wait Reply even though the customer replied | Only the first sequence out of that element is queued (…SendMessageAndWaitReplyProcessor.java L124). If that successor is not a Split Control / Time Condition, nothing evaluates the reply. | Route the wait element to a single Split Control (the sequence form enforces this on new sequences) and put the branches after it. |
| Split Control always sends the default message | Condition type or value does not match what the backend evaluates: a TIME type never matches on a split; DATETIME must be an ISO timestamp with milliseconds and zone; NUMERIC needs a parseable number on both sides; text comparison is case-insensitive but exact for Equal. | Use Text with Contains for menu replies; reserve Time for Time Condition elements. |
Time Condition with AFTER_OR_EQUAL never branches | The backend recognises AFTER, BEFORE, AFTER_AND_BEFORE, EQUAL, AFTER_OR_BEFORE and DATE only (BotCfConditionMatchService.java L116–L158). | Use AFTER or AFTER_AND_BEFORE. |
| Assign To Agent creates no task | No skill on the latest message element: a skill is only written to an element by choosing From Element Skill / To Element Skill on the Element Sequence form, and the bot’s own Skill tab does not do this. The processor’s ifPresent silently skips (…AssignToAgentProcessor.java L50–L59). | Edit the sequence into the message element that precedes the hand-over and pick a skill. |
| An edited Assign To Agent element loses its rule and assignment type | The edit screen writes {assignment_type} while create writes {assignmentType, automationRule} and TaskService reads the create-time keys (cf-element-edit.component.ts L959–L965; TaskService.java L495–L500). | Delete and recreate the element rather than editing it (there is no element delete in the grid, so create a new one and re-point the sequences). |
| The flow dies at an Execute Action or Move To Another Flow element | No processor exists for either type (ElementTypeFactory.java L17–L44) and the queue insert rejects the null event code. | Do not use these two types; model a jump as a duplicate of the target’s first elements. |
| The bot sends nothing on SMS, e-mail, voice, LINE or Instagram feed | SendMessageChannelEndpointFactory has no sender for those channels (L40–L48); sendMessageChannelEndpoint dereferences a missing map entry. | Use the bot on WhatsApp, web chat, Telegram, Lazada, Facebook Messenger, Shopee or Instagram chat. |
| A conversation on an endpoint errors instead of reaching an agent after a bot was deleted | Deleting a bot leaves the endpoint-bot link; BotHandler then reads a null bot header (BotHandler.java L48–L52). | Remove the bot from the endpoint’s Bot tab in the UCC before deleting it here. |
| Settings → Default Selection throws on the first change; several settings links show the 404 page | Unbound @Input() on a directly routed component; hard-coded links in the shared settings shell to routes this applet does not register. | Nothing to configure there — see Configuration. |
Related documentation
- Unified Contact Center — the applet this bot serves; its Configuration section covers endpoints and template messages.
- Contact-centre automation — how the task a hand-over creates is routed to a team or an agent.
- CRM & Digital module — the module hub.