Release announcements, helpful tips, and community discussion


Cerb (8.0) is a platform upgrade released on June 8, 2017. It contains over 114 new features and improvements from community feedback.

To check if you qualify for this release as a free update, view Setup » Configure » License. If your software updates expire on or after May 26, 2017 then you can upgrade without renewing your license. Cerb Cloud subscribers will be upgraded automatically.

Important Release Notes


Conversational Bots

Improved the experience of interacting with conversational bots

Previously, workers clicked on the floating Cerb icon in the lower right of the browser to start a bot conversation. An arbitrary bot answered the request. The worker was able to switch between bots using @mentions. Each bot could only have one conversational behavior, which had to be manually configured before the bot was available. This required each bot to have one massive conversational behavior that tried to do everything. Additionally, workers could only interact with bots using simple text messages.

The process of building and using conversational bots has been completely revamped in 8.0.

Now, workers no longer directly start conversational behaviors. Instead, there are several “interaction points” throughout Cerb’s user interface. The floating Cerb icon in the lower right is one, and a new Cerb icon on profile pages and card popups are others. Any element can serve as an interaction point, and plugins can introduce new ones. Conversational behaviors can even have interaction points in their responses.

Bots register specific interactions with these interaction points. An interaction is a label (e.g. “Show my tickets”), a name (e.g. “”), a target behavior to handle the interaction, and any number of optional parameters to send to that behavior (e.g. “owner:me”). Each interaction point gives some additional information to the bot, such as info about the current worker, current record, etc. A single bot can contribute any number of interactions to any number of interaction points.

Interactions are registered using a new event, so conditional logic and placeholders can be used to determine when to add an interaction and how to label it.

For instance, a bot can now contribute a specific interaction only to open ticket records that have no owner, and another interaction only when the owner is the current worker. Interactions can also be added only for specific workers, based on their group memberships or any other criteria.

Previously, custom behaviors were added to every record of the same type, and a bot had no control over who could see the behaviors aside from the ownership of the behavior. Additional, running a custom behavior from a profile page had no interactivity, wasn’t able to error check input, and wasn’t able to report errors or give any other feedback.

When a worker clicks on an interaction point, they are presented with a menu of all available interactions grouped by bot. When an interaction is selected, its associated behavior is triggered with information about the interaction.

When keyboard shortcuts are enabled, the " key will open the global bot interaction menu.

The interaction behavior is responsible for starting the appropriate conversational behavior. Most commonly, a decision would be used to start a behavior based on the interaction name. When the behavior finishes, the interaction behavior could then start another behavior that acts as a main menu, asking if the worker would like to perform another related action.

Interactions completely replace the “custom behavior” macro functionality on profiles. These custom behaviors still exist, but they can only be accessed by bots rather than workers. They should be wrapped with conversational bot interactions after you upgrade.

Chat window improvements

Each bot’s name and profile image is now displayed in the titlebar of the chat window. This removes the need to display the current bot’s name on each message, which makes more room for chat messages.

Prompted input

The chat window no longer displays a fixed text input prompt. Specialized types of prompts are now displayed by bots based on what information they want at a given time.

Prompted actions now automatically pause the behavior and resume at the same point after user input is received. Previously, a bot’s creator had to add their own ‘Exit/Pause’ actions every time.

Prompt for text

Conversational bots can prompt workers for textual input. Each prompt can include its own placeholder value with hints (e.g. “enter an email address:”).

Prompt with quick response buttons

Conversational bots can now prompt using quick response buttons.

For instance, rather than making a worker type yes or no, they can just click the appropriate option. Bots can present a menu of common choices to save time.

In surveys, emoji can be used for star ratings, etc.

The ‘Prompt with buttons’ action also allows arbitrary CSS styling on the buttons. For example, the font-size of Emoji buttons can be increased, or the background color can be changed.

Prompt with image buttons

Conversational bots can prompt for input using image buttons. These images are stored within the behavior and do not require external storage. Each image has an associated text label that is sent as a reply when the image is clicked.

For instance, a smiley face could reply “happy” and a frowning face could reply “unhappy”. Image buttons display the same on every platform, where Emoji may vary significantly between operating systems and devices.

Prompt for wait

Conversational bots can now prompt workers with a ‘wait’ that resumes a conversation after a short delay without requiring the worker to type anything.

For instance, if a worker asks for a potentially complex search, the bot can quickly respond with, “Let me check on that for you…“, run the search, and then respond with, “Here’s what I found”.

The wait prompt is also a great way to keep the worker informed about asynchronous operations. For instance, a bot can offload an intensive operation to a cloud-based service like Amazon Lambda, and then give the worker intermittent status updates while checking on the status of the remote job.

Typing indicator and delay for conversational bots

The ‘Respond with message’ action can now specify a typing delay for each message. This provides a realistic typing indicator during a sequence of messages. which makes the conversation feel more natural. Previously, multiple messages were delivered instantly at exactly the same time.

Combine multiple conversational behaviors

A single conversational bot interaction can now seamlessly utilize any number of conversational behaviors. When this happens, the calling behavior can specify whether it intends to wait for the new behavior to finish and then resume, or if it wants to exit and hand over control to the new behavior.

For instance, a ‘main menu’ type behavior could wait for the child behavior to finish and then display the menu again.

A new interaction_behavior_has_parent condition and placeholder specifies whether the behavior was called directly from an interaction (with no parent), or by another behavior (its parent). This is useful when a behavior with no parent wants to offer a worker the chance to return to a main menu, but a child behavior would simply return and let the parent handle that.

Added conversational interactions to all cards and profiles

On record profiles and cards, macros have been replaced with conversational bot interactions. Interactions address the shortcomings of the previous macro functionality: custom behaviors couldn’t display output, report errors, or prompt for additional input. They also couldn’t be easily restricted to specific workers (app-owned behaviors were visible to everyone), or only display on specific records. Custom behaviors are no longer directly accessible by workers.

Added conversational interactions when composing messages

Added conversational bot interactions to the mail compose popup (interaction point mail.compose). This allows conversational bots to interact with workers for retrieving information from external APIs, interactive snippets, etc.

Added conversational interactions when replying to messages

Added conversational bot interactions when replying to messages (interaction point mail.reply). Bots will be given information about the message being replied to, its ticket, etc.

This deprecates the ‘[UI] During reply by worker’ macros. They are no longer called now, and will be removed in version 8.1. You should convert these behaviors to interactions and conversational behaviors.

Portals for customer-facing conversational bots

Added a new ‘Conversational Bot Portal’ community portal type. This enables Cerb-powered conversational bots to be embedded on any public website with a single <script> tag. Conversational bots can also be used directly from the portal.

Conversational bots are triggered by “interactions”. The default interaction is the floating Cerb bot button in the bottom right of every web page. By adding an data-cerb-bot-interaction attribute, any web page element can start an interaction (e.g. help buttons, signup forms, surveys, troubleshooters, etc). Any number of data-cerb-bot-param- attributes can pass additional parameters to the interaction.

Customer-facing bot behaviors have the same capabilities as worker-facing bots, and they are created the same way. Behaviors on the ‘Conversation handle interaction with portal visitor’ event receive interactions and are responsible for returning the proper ‘Conversation with portal visitor’ behavior. Conversational behaviors are able to use a variety of prompts to request input from the visitor.

Public conversational bots can prompt for input using buttons. Buttons can display Emoji, use custom CSS styles, and have custom colors (including an interpolated color range for surveys, etc).

Public conversational bots can prompt for input with a numeric rating. For instance, (very unlikely) 0-10 (extremely likely) for a Net Prompter Score (NPS) survey. The range, labels, and colors are configurable.

Public conversational bots can prompt for arbitrary textual input. The placeholder text is configurable.

Conversational bots can prompt with a ‘wait’ action that instructs the client’s browser to check for new messages after a given amount of time.

Public conversational bots can respond with messages formatted in plaintext, HTML, or Markdown.

Public conversational bots can respond with arbitrary HTML, CSS, and Javascript.

Conversational bot interactions in the mobile interface

Added conversational bot interactions to the mobile interface.

Conversational bots are triggered by “interactions”. This makes it very efficient to accomplish common tasks using the mobile UI. The default mobile interaction is the bot button in the footer navigation.

Bots contribute interactions with behaviors on the ‘Conversation get interactions for mobile worker’ event. Behaviors on the ‘Conversation handle interaction with mobile worker’ event receive interactions and are responsible for returning the proper ‘Conversation with mobile worker’ behavior.

Conversational behaviors are able to use a variety of prompts to request more input from the worker.

The conversation history for each bot interaction is preserved if you navigate away and then click the ‘back’ button. This allows the bot to display records and search results.

The old form-style mobile bot behaviors have been removed.

Improved resumable behaviors

When conversational behaviors are suspended and resumed, list-based variables are now properly reconstituted as key-expandable dictionaries. Previously, dictionaries were reconstituted as arrays and key expansion was no longer available.


Code editor for bot scripting

In bots, all scripting is now handled in a proper code editor (Ace). This provides syntax highlighting (colorization), tab indent/outdent, code folding, contextual autocompletion, editor auto-sizing, soft wrapping, and much more. This makes it much easier to work with script-heavy bot behaviors.

Persistent storage for bots

Bot behaviors now have persistent storage for arbitrary data with ‘Get/set persistent key’ actions. This enables many new workflows.

For instance, a bot can remember per-worker preferences and past interactions without having to store everything in custom fieldsets.

When setting a key, an optional ‘expires at’ field controls its time-to-live (TTL).

Each bot has its own persistent key/value scope – meaning two bots can store data using the same key name without interfering with each other. In order to share persistent storage between bots, one bot should act as a delegate for getting/setting data.

For example, consider a conversational bot that collects satisfaction surveys from customers. It needs to refer to their past conversation (ticket_id, message_id, worker_id, address_id) with a secure, unique, survey ID (much like a ticket mask). A ‘Survey Bot’ could allow have behaviors to allow bots to save/retrieve information from its scope. That way, a key like ‘survey:9ce914be’ will always refer to the same survey scope.

Calculate worklist metrics from bot behaviors

Added a ‘Get worklist metric’ action to bot behaviors. This allows bots to use any worklist to compute a count, average, sum, min, or max for any record field (including custom fields). Unlike worklist-based behavior variables, these metric calculations don’t have a record limit.

This action is particularly useful in combination with the new bot-driven dashboard widget datasources. For instance, to compute a Net Promoter Score (NPS) a bot can SUM the number of ratings from a custom fieldset, SUM the promoters, SUM the detractors, then calculate %promoters-%detractors, and then return the result. These kinds of calculations weren’t possible before without writing plugins.

Improved event configuration on bots

When creating or editing bot behaviors, the selection of the ‘Event:’ field is now handled with submenus. This groups related events together and makes them easier to find. Previously the events were listed in a long dropdown list.

Improved variable configuration on bot behaviors

When editing bot behaviors, variables are now added using nested submenus. This groups all the list-based variables together to improve readability/usability. Previously everything was in one big list.

New behavior variable type for generic lists

Added a new ‘List:(Mixed Records)’ variable type to bot behaviors. This can store any kind of records (which may not be known until the behavior is running).

For instance, this allows a reminder behavior to add a comment to any list of records as a variable, where that may be tasks, tickets, or something else depending on the interaction. Previously, a list variable of each type had to be added, which created a lot of clutter.

Added placeholders for behavior and bot to all events

Every bot behavior now has placeholders for itself (behavior_*) and its parent bot (behavior_bot_*). These records can also be used as ‘On:’ targets in actions.

Behaviors can share bot-level configuration settings

On bot records, a ‘Configuration’ section is now provided where a JSON object can be defined. This object is accessible to all of a bot’s behaviors. This is very useful for sharing configuration values between multiple behaviors on the same bot. For instance, if a bot accesses an external API, the URL base path can be a bot configuration value. Even if that value is used in a dozen places, it can be changed in a single place by editing the bot.

Private behaviors

When bot behaviors are marked as ‘private’ they are now only visible to that bot. Public behaviors are visible to other bots based on the ownership permissions policy. Now that custom behaviors are no longer directly accessible by workers, this makes it much easier to clean up the shared behavior list.

Bot-owned custom fieldsets are private

When editing records, bot-owned custom fieldsets are no longer editable by workers. Nor are custom fieldsets owned by other workers. These fields are still visible to everyone on worklists, dashboards, etc.

When importing records on a worklist, bot-owned custom fieldsets are no longer displayed.

Infinite loops

Bot behaviors can now specify infinite loop nodes with the following JSON: ["*"]. This is mainly useful for resumable behaviors like conversational bots. In this situation, the loop could have a prompt like “Is there anything else I can help you with?”. While these loops continue indefinitely, they pause for user input each iteration and can be abandoned at any time. Any other use of an infinite loop should have explicit exit conditions.

Loop counters

When using loop nodes in bot behaviors, a __counter suffix placeholder (e.g. “attempts__counter”) is now created to keep track of how many iterations have occurred. This is particularly useful for infinite loops in conversational behaviors.

Shuffle arrays

Added a new shuffle() function to bot scripting for randomizing the contents of an array.

Improved the ‘Before message sent from worker’ event

The ‘Before message sent from worker’ event now includes a placeholder for the Message-ID header. When this event runs, the internal ID for the message doesn’t exist yet. The Message-ID can be used instead. For instance, when sending a CSAT survey link on an outgoing worker message.

Use worker-based variables when running or scheduler behaviors

The ‘Run/Schedule Behavior’ actions can now use worker-based variables when setting worker-based custom fields.

Set custom fields on message records

Bots can now read and write custom fields on message records.

Improved placeholders on outcomes and actions

Fixed an issue on outcomes and actions where the ‘Insert Placeholder’ menu could be deleted along with the condition or action it was attached to.

Fixed an issue with adding actions. If you added one action, saved it, reopened the action editor, and added a second action, then you would end up with two copies of the same action.

Import Packages

Import bots, custom fieldsets, dashboards, and portals as a single unit

Added a new Setup » Configure » Import Package page.

This enables admins to import a collection of related records while maintaining their dependencies and allowing for pre-import customization. This first release of the feature can import and fully configure: custom fieldsets, bots, behaviors, workspaces, workspace tabs, dashboards, dashboard widgets, community portals, saved searches, calendars, calendar recurring events, classifiers, classifications, and classifier training data.

When importing, a package can specify requirements (Cerb version, plugins) and prompt for configuration details – prompts with text input and choosers that customize the package before it is imported.

Packages can also specify automatic placeholders; for instance, a ‘random’ placeholder can generate a random value for passwords, secret keys, etc. This improves security by making sure packages don’t use default secrets everywhere they are imported.

A major limitation of the import/export functionality in bots is that local IDs for workers/behaviors don’t exist in other Cerb installations. This required behaviors to be imported in a specific order, with prompts linking them together.

The ‘Customer Satisfaction Bot’ example conversational bot has 16 behaviors, which made this approach untenable. Now that entire bot can be imported as a single unit, along with its 3 custom fieldsets, dashboard with 3 tabs and two dozen widgets, and community portal. All of the newly created records are properly linked to each other.

After importing a package, a summary of created records is displayed with links to cards and profiles for each one.


Bot-powered widgets

Added a new ‘Bot behavior’ widget type that can use a bot to render any kind of output using HTML/Canvas/Javascript from any datasource. For instance, a bot could load a worklist or pull from an external API and then display the data with a special visualization. This allows nearly anything to be added to dashboards without having to write plugins.

Bot-powered datasources for counters and gauges

Single metric widgets (e.g. counters, gauges) can now use ‘bot behaviors’ as a datasource. The behavior can do anything to load and calculate the metric (connect to external APIs, run stats on worklists, etc). This opens up a huge amount of reporting that wasn’t easily possible before.

Improved gauge rendering

Gauges now render as an arch rather than a semi-circle. This makes them less overpowering and easier to read.

Labels for min/max on gauges

Gauges now have labels for their minimum and maximum values.

Gauge widgets can now specify a starting (minimum) value. This makes it possible to have gauges with negative values (like an NPS score from -100 to 100). It also allows an ‘Average response time’ gauge to start at a reasonable value like ‘5 minutes’ rather than an impossible ‘0 seconds’.

Interpolation for gauge colors

When configuring a gauge, threshold colors will now be automatically interpolated as a convenience. For instance, you can provide the first and last color and the colors in the middle will be generated. Or you can provide the first, middle, and last of 5 colors, and the missing colors will be generated.

Transparency and hex colors

When using a color picker, a HEX or RGB/RGBA color code can be directly entered.

Add up to 5 datasources to chart widgets

Line and bar charts, and scatterplots, can now have up to 5 series datasources (previously 3).

Customer Satisfaction Surveys

You can now build any kind of interactive survey (NPS, CSAT, CES) with conversational bots that chat with your users, and then track your results on bot-powered dashboards.

This entire workflow is built entirely in the browser with Cerb’s own tools.

Project Boards

A new plugin provides kanban-style project boards for organizing any record type (tasks, tickets, calls, leads, etc).

Any number of columns can be added to a project board (e.g. TODO, In Progress, In Testing, Completed, Document).

Records on the board are represented as cards that can be dragged between columns and rearranged within a column. The fields displayed on a card can be completely customized per project board and record type.

When cards are moved into a column, bot behaviors may also be triggered. For instance, when moving a task card into a ‘Completed’ column, a bot can automatically mark it as completed and send a room notification to Slack.

Project boards can also configure default search filters for each record type when adding cards. For instance, worker-owned project board for tasks can be configured to only show open tasks owned by that worker when adding a new task card to the board. Project boards are visible/editable based on ownership.

Board can be accessed from Search » Project Boards.

Add project boards to workspaces

Added a new ‘Project Board’ workspace tab type. This can be used to display any number of related project boards on the same workspace.

Saved searches

Added ‘Saved Searches’ for worklist quick search. You can define a saved search from Search » Saved Searches, which then becomes available from the quick search menu for worklists of that type. When selecting a saved search, its query is inserted into the quick search bar. This way minor modifications can be made to the saved search, and it can be combined with other filters or saved searches.


Webhook portals

Added a new ‘Webhook Portal’ community portal type. This responds to HTTP requests using a webhook-based bot behavior. This allows entirely new types of portals to be created entirely within bots. It’s also a way to expose a new API.

Set HTTP status from webhook behaviors

Added a ‘Respond with HTTP status’ action to simplify setting the HTTP response code (e.g. 403 Forbidden, 404 Not Found, 500 Server Error).

Use HTTP path in webhook behaviors

The ‘HTTP path’ is now available as a placeholder in outcome conditions and actions.


Filter custom fields by null or not null

When using quick search on a worklist, all custom fields can now be filtered by field:NULL (the field is not set) or field:!NULL (the field has any value).

When configuring custom worklists with ‘customize’, required filters can now be added using quick search. This allows the use of all quick search features, including AND/OR groups.

Negate deep searches

On worklists, deep searches can now be negated by prepending a ! to the filter group. For instance: group:!(support) returns all records where the group doesn’t match “support”.

Improved the header.messageId filter on message worklists

  • The header.messageId: filter now accepts the original Message-ID: value or a SHA-1 hash.

  • The header.messageId: filter can now do partial matches for SHA-1 hashes. This allows a smaller hash to be used when referring to a specific message (e.g. in surveys).

Improved worklist search popups

When worklists are opened from a search button (e.g. from cards), they are now always unique. Previously, search worklists of the same type shared an ID. So if you started with a behaviors worklist, opened a bot card, then opened the bots behaviors, the two behavior worklists would conflict.


Shortcut to a worker’s card

Added a ‘my card’ link to the worker menu in the top right.

Make the profile button more noticeable

On cards, moved the ‘Profile’ button to the far left of the toolbar to make it more obvious. Many people hadn’t noticed it.

Added a card button to all profiles

On profiles, added an ‘open card’ button to the top toolbar. This makes it easy to access some functionality that is only available from card popups.


Required filters on choosers

Choosers can now open a worklist with specific required filters (i.e. unable to be changed by the worker). Previously, such filters could only be displayed in quick search and were editable.


Dynamic @mentions

When using @mentions, saved worker searches can now be used to notify multiple workers at once. For instance @available-workers or @developers. Create a saved search from Search->Saved Searches using type ‘Worker’. The tag name will be what you @mention with.

Connected Accounts

Connected account authentication details can now be modified and relinked. Previously, accounts could only be linked during creation and then they had to be deleted and recreated to be modified. Adding a new connected account now uses the same editor instead of opening a different popup, which allows for easier input validation.

Admins can also set a connected account’s owner in a single step rather than having to create and then edit.


Removed recommendations from ticket records

Removed the recommendations feature from ticket records. The same thing can be handled within @mentions and comments. The recommendation feature was intended to train machine learning models before the recent introduction of classifiers and conversational bot behaviors.


Waiting status and reopen date for tasks

Added the ‘waiting’ status to task records. This allows tasks to be created that aren’t immediately actionable (more like reminders).

A ‘reopen’ date determines when the task will automatically switch back to the ‘open’ status.


In the mobile interface, searches can now use the full list of quick search filters (including AND/OR grouping).

Community Portals

Improved the built-in portal proxy

  • The deployable index.php file can now force SSL rewriting with the LOCAL_SSL option. This is useful during development when hosting the portal using PHP’s built-in web server and then SSL tunneling through something like ngrok.

  • The deployable index.php file now enforces SSL validation by default. This can be disabled from the REMOTE_SSL_VALIDATION option.

  • The deployable index.php file will now proxy HTTP requests with the OPTIONS method. This is useful when implementing CORS directly in bots.

  • The deployable index.php file now proxies all HTTP headers from the origin to the client.

  • The deployable index.php file now proxies all cookies from the origin to the client. It no longer sets its own GroupLoginPassport cookie. If you’re using the index.php files to deploy community portals, you must deploy a new version of the file for them to work properly.

  • The deployable index.php file now proxies the HTTP status code from the origin/backend.

  • The deployable index.php file no longer proxies the Connection: header.

Support Center

Configurable login authenticators on the Support Center

When configuring a Support Center community portal, login methods are now configurable. For instance, when using LDAP for authentication, each portal could use a different server and search context.


Cookies from Support Center portals will no longer conflict with worker cookies from Cerb when hosted on the same domain (e.g. and

Deprecated custom templates

Community portals now only show the ‘Custom templates’ tab for the legacy Support Center. This feature is deprecated and will be removed in favor of the upcoming modular Support Center. The ability to override templates in the Support Center routinely causes problems after upgrades.


Added Composer

Added Composer to the project for dependency management.

Added Ace code editor library

Added the Ace Code Editor javascript library to Devblocks. This is far more usable than editing code in textarea elements.

Updated dependencies

  • Upgraded Smarty template engine from 3.1.21 to 3.1.31.

  • Upgraded Swiftmailer from 5.3.1 to 5.4.8.

  • Upgraded Twig template engine from 1.16.2 to 1.33.2.

  • Updated the jquery-minicolors library to the latest version. This includes swatches and alpha transparency.


Cerb will no longer send cookies and attempt to start sessions for stateless controllers: /cron, /portal, /resource.


  • Added a .cerbTemplateTrigger() helper to the Devblocks javascript library. This is useful when there isn’t sufficient room in a form to provide all the editor/placeholder functionality. A read-only text box displays the template and when clicked it opens the editor popup.

  • Added a .cerbQueryTrigger() helper to the Devblocks javascript library. This extends an text box, which becomes read-only and opens a worklist popup when clicked. This allows a quick search to be previewed in real-time. When saved, the quick search from the popup is automatically set in the text field.

  • Added a $.cerbBotTrigger() plugin to the Devblocks javascript library. This triggers bot interactions from any DOM element. The data-interaction attribute specifies the interaction point, and data-behavior-id optionally specifies which bot interaction handler behavior to use (this is how the global menu targets different bots). Optionally, any data-interaction-param-* attributes will be sent to the behavior as interaction parameters.

  • In the UI, when links on a profile or card are changed, a cerb-links-changed event is triggered on the links container.

  • Added a DevblocksPlatform::colorLerp() helper method. This generates interpolations between two hex color codes. This is useful for generating default color schemes on dashboards and portals, rating scales on surveys, etc.

  • Added a DevblocksPlatform::colorLerpArray($colors) helper method. This accepts an array of HEX color codes where any gaps in the series are interpolated.