Blog

Release announcements, helpful tips, and community discussion

In Development: 10.2

Cerb (10.2) is a feature upgrade in development as of January 11, 2022. It includes more than 121 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 April 30, 2021 then you can upgrade without renewing your license. Cerb Cloud subscribers will be upgraded automatically.

Important Release Notes

Release Notes

  • [Platform/PHP] PHP 8.0 compatibility.

  • [Search/Fulltext/Performance] When running a fulltext search, Cerb will now first check the total hit count for the given terms. If less than a lower threshold (default 1,000) the results will be returned as IDs rather than an IN(...) join. This reduces index contention in complex queries. The threshold can be configured with the APP_OPT_FULLTEXT_THRESHOLD_IDS constant.

  • [Search/Fulltext/Performance] When running a fulltext search, Cerb will now first check the total hit count for the given terms. If greater than the upper threshold (default 10,000) the results will be joined using EXISTS rather than IN. The EXISTS strategy is faster when there are fewer matches for non-fulltext filters than fulltext (e.g. searching a date range or a particular org’s history). The IN strategy is usually faster when there are fewer matches for fulltext filters than non-fulltext (e.g. searching all historical tickets for an uncommon phrase). The threshold can be configured with the APP_OPT_FULLTEXT_THRESHOLD_EXISTS constant.

  • [Automations] Automations now have an execution time limit (default 25s) rather than an operation limit. This still prevents infinite loops without inconsistently prohibiting functionality. The time limit can be override from the automation policy with the settings:time_limit_ms: key.

  • [Project Boards/Performance] Project boards now load up to 100 cards per column by default. Additional cards can be loaded with a ‘show more’ link at the bottom. This improves performance on heavily used boards; particularly in the ‘Completed’ column. One noteworthy client had over 23,000 completed cards and was experiencing memory issues while rendering the column.

  • [Data Queries/Availability] Added a new calendar.availability data query type. This aggregates any number of matching calenders to display availability over a date range by hour or day. For instance, this can be used to visualize when a group is most or least available for shift planning. The output formats are dictionaries and timeblocks. Thanks to 1Password for the feature request.

  • [Records/Search/Calendars] On calendar records, added a workerAvailability: search filter. This matches calendars configured for worker availability (opposed to calendars owned by workers).

  • [Automations] The cerb.data.records (sheet.data) automation now accepts a query: input (rather than required_query:) and a query_params: input for untrusted query placeholder substitution.

  • [Profiles/Performance] Profile tabs are now properly loaded from the cache rather than the database.

  • [Profiles/Performance] Profile widget configurations are now cached per profile tab, rather than loaded from the database on every request. The cache is properly invalidated on widget edits as well as reordering.

  • [Profiles/Tickets/Performance] Optimized database queries when loading ticket profiles: requesters, senders, workers, contacts, orgs, custom fields, headers, files, and toolbars. More data is bulk loaded in fewer queries, and previously loaded records are reused when possible.

  • [Automations/HTTP] In automations, the http.request: action can now directly stream large attachment/resource uploads for PUT and POST HTTP requests. Set the Content-Type: header to application/vnd.cerb.uri and set the HTTP body to a record URI like cerb:attachment:123. The automation will take care of streaming the bytes to the HTTP endpoint, which avoids memory issues with loading large attachment content into an automation variable.

  • [Automations] In automations, a new file.read: command can read chunks of bytes from an attachment or automation resource. For inputs:, the resource is provided as a uri: and the starting byte is offset:, with an optional length:. This allows automations to process large attachments without exhausting memory. The output: is a dictionary with keys: bytes, uri, name, offset_from, offset_to, mime_type, and size. If bytes contains binary it is base64-encoded and returned as a data: URI string. The command enables many new workflows, like automatically processing DMARC reports, bounces, iCal/ICS invites, etc. [#766] [#1477]

  • [Automations] In automations, when using the http.request: command, a large HTTP response body (>1MB) will now be returned as an automation resource record for further processing. These bytes are streamed directly to a file to avoid memory limitations in the automation (e.g. video processing). When this occurs, output:is_cerb_uri: is true, the output:content_type: key is replaced with application/vnd.cerb.uri, output:content_type_original: contains the original content type, and the HTTP body is a Cerb record URI (e.g. cerb:automation_resource:c10028f0-1cad-11ec-81e5-59d4c4af2d7). The new file.read: command can be used to process the file in chunks.

  • [Automations] In automations, when using the http.request: command, a binary HTTP response body is now automatically converted to a base64-encoded data: URI. This resolves issues with serializing automation states containing unprintable characters (e.g. simulation). You should always use the http.request:on_success: handler to verify an HTTP response. When this occurs, the output:is_data_uri: is true.

  • [Automations/Resources] Added ‘Automation Resource’ records for efficient handling of large binary objects within automations. For instance, the http.request: command can stream a GET request for a large video download directly into a temporary resource file and return its Cerb record URI rather than 100MB of bytes. This also protects the privacy of files that are uploaded in automations (e.g. interactions) which should never be treated like attachments.

  • [Security] Worker default passwords are created in the new password_hash format. Previously this used the old salt+SHA1 format and was automatically upgraded after the first login.

  • [Platform/Cache/Performance] When using Memcached for the cache service, consistent hashing is now enabled by default. When using a cluster that adds or removes nodes, consistent hashing reduces the number of keys that are rebalanced.

  • [UI/Styles/Themes] In the stylesheet, separated the colors (themes) from layout and condensed styles. This makes it easier to create alternative color schemes – like dark mode. [#1281]

  • [Mail/Routing/Automations] Automations on the mail.route event can now route directly to a specific bucket rather than just to a group inbox.

  • [Cards/Widgets] Timeseries chart widgets can now be added to cards.

  • [Queues] Added a new ‘queues’ service to the platform for distributing units of asynchronous work. Queues are identified with a unique name. Messages with arbitrary payloads can be pushed into a queue. Concurrent consumers can pop messages from the queue to process them. A message is always in one of four states: available, in flight, failed, or complete. For instance, every historical ticket can be reviewed by pushing sets of IDs into a queue as messages. The number of queue consumers can be scaled up to the desired throughput. [#481]

  • [Automations/Queues] In automations, added queue.push: and queue.pop: commands for adding and processing messages in queues.

  • [Dashboards/Time Blocks] Added a new ‘Chart: Time Blocks’ card widget for visualizing the intensity of hourly coverage over a range of days. This uses a data query (usually calendar.availability) with format:timeblocks. For instance, aggregating the availability calendars of a group’s members to display shift coverage for the current month.

  • [Dashboards/Time Blocks] Added a new ‘Chart: Time Blocks’ profile widget for visualizing the intensity of hourly coverage over a range of days.

  • [Dashboards/Time Blocks] Added a new ‘Chart: Time Blocks’ workspace widget for visualizing the intensity of hourly coverage over a range of days.

  • [Metrics/Platform] Added a new time-based metrics service to the platform. Metrics have a unique name like cerb.workers.active and store statistics in multiple resolutions: 5 mins, 1 hour, and 1 day. Samples collected within the same period are aggregated into a statistic set with the number of samples, sum, min value, and max value (the average is the sum divided by the number of samples). By default, 5 minute samples are retained for 1 day, 1 hour samples for 2 weeks, and daily samples are stored indefinitely. Metrics may be further partitioned with optional key/value pairs called “dimensions”. For example, the cerb.automation.invocations metric has dimensions for the ‘automation’ and ‘event’; which allows for reporting across all automations, specific automations, specific events, or any combination thereof. Dimensions may have the following types: extension, record type, or text. Metric samples are buffered until the end of the current request and then are efficiently enqueued for asynchronous processing by a new scheduler job. Metrics statistics can be retrieved with data queries. [#656]

  • [Metrics/Data Queries] Added a new metrics.timeseries type to data queries for fetching metric statistics over a date range. This can retrieve multiple series each with a different metric and function (avg, sum, min, max, count). A series can also be aggregated or filtered by any combination of metric dimensions.

  • [Metrics/Automations] Added a cerb.automation.invocations metric for tracking how often automations are executed. This includes dimensions for automation_id and trigger.

  • [Metrics/Automations] Added a cerb.automation.duration metric for tracking how long automations are executed. This includes dimensions for automation_id and trigger.

  • [Metrics/Webhooks] Added a cerb.webhook.invocations metric for tracking how often webhooks are executed. This includes dimensions for webhook_id and client_ip.

  • [Metrics/Records/Search] Added a cerb.record.search metric for tracking how often each worker searches for a given record type. This includes dimensions for record_type and worker_id.

  • [Metrics/Tickets] Added a cerb.tickets.open metric for tracking open ticket counts over time by group and bucket. This includes dimensions for group_id and bucket_id. The metric is sampled every 15 minutes.

  • [Metrics/Snippets] Added a cerb.snippet.uses metric for tracking snippet usage over time by worker. This includes dimensions for snippet_id and worker_id. This replaces the snippet_use_history table but imports its data.

  • [Data Queries/Metrics] On metrics.timeseries data queries, a new series.*:missing: key configures what to do with missing samples at a time interval. The options are null (default), zero (set to 0), or carry (carry the last sample).

  • [Metrics/Behaviors] Added a cerb.behavior.invocations metric for tracking how often behaviors are executed. This includes dimensions for behavior_id and event.

  • [Metrics/Behaviors] Added a cerb.behavior.duration metric for tracking how long behaviors are executed. This includes dimensions for behavior_id and event.

  • [Sheets] On sheets, selection: columns may now specify an optional params:label:, params:label_key:, or params:label_template:. This displays a text label next to the checkbox or radio button; avoiding the need for an extra column.

  • [Automations/Reminders] Added a reference cerb.reminder.remind.email automation for the reminder.remind automation event. This sends reminders by email to the target worker.

  • [Data Queries/Record Types] On record.types data queries, a new options: filter returns record types with one or more matching options: autocomplete, avatars, cards, comments, custom_fields, links, owner, records, search, snippets, va_variable, watchers, workspace

  • [Search/Interactions/Toolbars/Usability] Added a new global.search toolbar that adds interactions to the global search menu in the top right of every page. The most recently searched record types per worker are now automatically added to the menu as shortcuts. The existing ‘record type’ search favorites (from worker settings) are always pinned to the menu as shortcuts. The ‘show all record types’ menu item is now an interaction with a searchable list.

  • [Toolbars] In toolbars, divider: items draw a horizontal divider between menu item sections.

  • [Automations/Metrics] In automations, a new metric.increment: command adds samples to statistics for a metric. This has inputs: for metric_name:, dimensions:, values:, timestamp:, and is_realtime:. All inputs are optional except for metric_name:. By default, samples are queued for efficient background processing. The is_realtime@bool: yes option instantly records the metric at a slight performance penalty. For instance, this is used when generating the global search menu based on recent search activity, since this would be less useful to have delayed by several minutes.

  • [Automations/Events] Added a new worker.authenticated automation event that triggers after a worker successfully authenticates a new session. This receives inputs for the worker_* record, client_ip, client_browser_name, client_browser_version, and client_browser_platform. If an automation returns a deny: key, the login is denied with a custom error message. This event enables new workflows like: security audits on new sessions (compare historical browser, IP, location), worker browser metrics, deny old browser versions, IP-based firewalls per worker, etc.

  • [Automations/Events] Added a new worker.authenticate.failed automation event that triggers after a worker fails to authenticate a new session. This receives inputs for the worker_* record, client_ip, client_browser_name, client_browser_version, and client_browser_platform.

  • [Snippets/Bulk] In snippet worklists, bulk update can now delete multiple records. [#1282]

  • [Custom Records/Bulk] On custom record worklists, bulk update can now delete multiple records at once. [#1512]

  • [Tickets/Security] Added additional role permission checks when workers delete tickets from worklists or profile pages.

  • [Behaviors/Automations] In bot behaviors, added a new ‘Execute automation’ action which passes inputs to a behavior.action automation and returns the results. This helps with the gradual transition from behaviors to automations, and enables behaviors to use all the functionality from automations. Thanks to 1Password for the feature request!

  • [Metrics/Behaviors] Added a cerb.mail.transport.deliveries metric for tracking how many successful messages are sent through a mail transport. This includes dimensions for transport_id and sender_id (email address).

  • [Metrics/Behaviors] Added a cerb.mail.transport.failures metric for tracking how many unsuccessful messages are attempted through a mail transport. This includes dimensions for transport_id and sender_id (email address).

  • [Data Queries/Attachments] Added a new attachment.manifest data query type. This iterates and filters the manifest of attachment archives (e.g. ZIP). This can be combined with file.read: in automations to extract specific files from an archive.

  • [Mail/Drafts/Commands] Implemented the #start comment command for multiple line comments in drafts for compose and replies.

  • [Records/Search] On draft worklists, added a ticket.id: filter.

  • [Mail/Parser] When threading inbound messages to existing conversations, the In-Reply-To: header is now prioritized, and all References: message-ids are checked in reverse order. This should resolve issues where a ticket is split, but replies to the split messages still thread to the original conversation.

  • [Profiles/Ticket/Usability] On ticket profiles, removed the attachments search button from the top right when hovering over a message. This can be reimplemented as an interaction on the mail.read toolbar. We had reports of the attachments and permalink buttons being confused for each other. [#1547]

  • [Automations/Events/Mail] Added the mail.reply.validate automation event. This enables interactive validators when a worker starts replying to a message on a ticket. Validations are interactions that can optionally abort the reply before a draft is created. If not aborted, the reply editor opens like normal. For instance, this can detect a duplication of effort when another worker starts a reply between the time the current worker viewed the ticket and started replying. This feature was previously built-in, but is now fully customizable as an automation. [#1500] [#1529]

  • [Automations/Attachments] In automations, the file.read: command has a new extract: option for extracting an individual file from a ZIP archive. This is used in conjunction with the new attachment.manifest data query type that lists the contents of an archive.

  • [Records/Custom Fields] Fixed an issue in record dictionaries when expanding the customfields key. This didn’t write a value to customfields in the dictionary, so subsequent requests could re-load fields and duplicate values for some types (e.g. record links).

  • [Interactions/Sheets] Fixed an issue with worker interactions with sheet prompts. If single selection is enabled, de-selecting a row still keeps its value until another option is selected. This meant someone could ‘Continue’ after de-selecting an option without selecting something else.

  • [Automations/Usability] When creating a new automation in the editor, new default content for the script and policy offers helpful tips about what to do next.

  • [Interactions/Sheets] In interactions using a form:await: continuation with a sheet: element, an __index key is now synthesized in the data: dictionaries. This is the index of the dictionary in the collection, which is often not otherwise available as a dictionary value. In many cases this would be a zero-based ordinal position. For instance, this allows a sheet: element to return the index of a dictionary, from which any key can be loaded by later logic.

  • [Sheets/Grid] In sheets, the layout: grid style has been significantly improved. The grid no longer shows checkboxes on each item for selection. Instead, the entire cell is toggled on and off by clicking anywhere in it. Cells use flexbox for arrangement, and sheet columns are displayed from top-to-bottom; allowing for enhancements like icons and descriptions. This makes it easier to show many options in a smaller space while retaining readability.

  • [Interactions/Editor] In interaction.worker automations, with an await:form: continuation, editor: form elements with a syntax: option will now properly control syntax highlighting and autocompletion in the editor. For instance, syntax: data_query will highlight and autocomplete data query syntax.

  • [Data Queries] Added a new data.query.types data query that returns metadata about the available types (name, description, etc). This can be used by functionality like interactions to assist in data query generation.

  • [Data Queries] Added a new autocomplete.completions data query that returns autocompletion suggestions data for a given automation key path. This can be used by functionality like interactions to inspect an automation at the current cursor to offer contextual suggestions.

  • [Automations/Editor/Usability] In the automation editor, improved autocompletion for values on the same line as their key (e.g. key: value). [#1476]

  • [Automations/Editor/Usability] In the automation editor, the value for uri: keys now autocompletes in commands.

  • [Automations/Editor/Usability] In the automation editor, the possible keys for inputs: are now autocomplete suggestions in the function: command.

  • [Automations/Editor/Usability] In the automation editor, the possible values for record_type: are now autocomplete suggestions in record.*: commands.

  • [Automations/Editor/Usability] In the automation editor, the possible keys for fields: are now autocomplete suggestions in record.*: commands.

  • [Automations/Editor/Usability] In the automation editor, the possible values for metric_name: are now autocomplete suggestions for metric.*: commands.

  • [Automations/Editor/Usability] In the automation editor, the possible keys for dimensions: are now autocomplete suggestions for metric.*: commands.

  • [Automations/Editor/Usability] In the automation editor, the possible values for queue_name: are now autocomplete suggestions for queue.*: commands.

  • [Automations/Editor/Usability] In the automation editor toolbar, the “add” menu button has been replaced with a “magic” interaction that provides contextual suggestions based on the current cursor position in the code. These suggestions may also launch helper interactions to build syntax.

  • [Automations/Editor/Usability] In the automation editor, improved the helper interaction for building data.query: commands.

  • [Automations/Editor/Usability] In the automation editor, improved the helper interaction for building http.request: commands.

  • [Automations/Editor/Usability] In the automation editor, possible values for icon: are now autocomplete suggestions in sheet: and submit: elements for await:form: continuations.

  • [Automations/Editor/Usability] In the automation editor, autocomplete suggestions are now ranked so the most common options are recommended first.

  • [Automations/Editor/Usability] In the automation editor, autocomplete suggestions now include descriptions.

  • [Automations/Editor/Usability] In the automation editor, autocomplete suggestions insert more complete code templates.

  • [Automations/Editor/Usability] In the automation policy editor, added an autocomplete suggestion for deny/type: to the data.query: command.

  • [Toolbars/Autocomplete] In the toolbar editor, possible values for uri: are now autocomplete suggestions in interaction: commands.

  • [Toolbars/Autocomplete] In the toolbar editor, possible values for icon: are now autocomplete suggestions in interaction: commands.

  • [Toolbars/Autocomplete] In the toolbar editor, possible keys for inputs: are now autocomplete suggestions in interaction: commands.

  • [Automations/Events/Records] Added the record.profile.viewed automation event. This can trigger actions when a worker views a record profile. For instance, metrics on ticket profile views. [#1550]

  • [Calendars] On calendars, ‘Easter’ is now a valid pattern for recurring events. Alone it will be evaluated as Easter day in the current year and timezone. It may also be used relatively, like “Easter -7 weeks Wednesday” and “Easter +3 days”. Thanks to 1Password for the request! [#1535]

  • [Automations/Scripting/Security] In automation scripting, the |markdown_to_html(is_untrusted=true) filter now uses ‘untrusted’ mode by default to allow Markdown formatting escape HTML tags. The optional argument can allow HTML tags for trusted input in special cases.

  • [Records/Custom Fields] When creating or updating records, URL-based fields now automatically truncate when over 255 characters in length. Previously these fields returned a validation error.

  • [Automations/Validation] Fixed an issue with validation on some automation commands (e.g. var.set:) where values didn’t allow pure numbers.

  • [Automations/Interactions/Sheets] In interactions, sheet: prompts now automatically continue when they’re in single selection mode and the only prompt. The continue button should be hidden to avoid requiring two clicks.

  • [Interactions/Sheets] In worker interactions, sheet: prompts have a new columns layout style that renders sheet items from top to bottom in a columns. Columns start from the left and responsively add/reduce based on the popup width. This is similar to the grid layout which arranges items in rows from left to right, top to bottom.

  • [Automations/Editor/Usability] In the automation editor, the helper for the record.create: command now automatically selects all of a record type’s required fields by default. Previously this had to be done manually.

  • [Data Queries/Records] In record.fields data queries, fixed an issue with the worker record type where keys weren’t returned for email,email_ids, and password.

  • [Interactions/Website] Fixed an issue with interaction.website automations when selecting sheet: items with the keyboard rather than the mouse.

  • [Data Queries] Added a new platform.extension.points data query type for filtering and paging through a list of platform extension points.

  • [Metrics/Dimensions] In metrics, added a number type to dimensions. This efficiently stores a positive whole number.

  • [Automations/Events] In the automation event editor, the interaction:uri: key now autocompletes with only suggestions from the current event trigger. Suggestions are also provided for interaction:inputs:.

  • [Automations/Metrics] In the automation builder, added a helper interaction for the metric.increment: command. This automatically defaults the available dimension key/values.

  • [Automation/Events/Usability] In the automation event editor, the (+) toolbar item now starts the interaction in a single click. Previously this showed a one item menu and required an extra click.

  • [Automation/Events] In the automation event editor, the (+) interaction now warns on invalid cursor placement. New automations can only be added at the top-level of the KATA script (no indentation).

  • [Dashboards/Maps] On profiles and dashboards, fixed an issue with ‘Map’ widgets where the Maps KATA was inserted in the wrong editor.

  • [Automations/Data Queries] Fixed an issue with data query query_params: dynamic bindings. Dynamic text values are now always enclosed in quotes. This affected functionality that converts tokens back to queries, where the values weren’t properly escaped.

  • [Portals/Interactions] interaction.website automations can now return:redirect_url: to redirect the portal visitor to a URL. For instance, after completing a survey the visitor can be redirected back to the project website or support portal.

  • [Sheets/UI] In sheets using layout:style:grid, a layout:params:width: option determines the width of grid cells. The default is auto where each cell can be a different width.

  • [Portals/Interactions] In ‘Website Interactions’ portals, it’s now possible to disable the floating icon when viewing the portal directly (rather than embedding on a website).

  • [Automations/Continuations] Added a maintenance cleanup task for automation continuations.

  • [Resources] Resource records may now store additional parameters based on their type. For instance, after validation, an ‘image’ resource can store the width, height, and MIME type.

  • [Resources/Portals] Added a new ‘Portal Image’ resource type for logos, icons, and artwork in portals. This improves security by avoiding using attachment records for this purpose.

  • [Portals] When saving a portal configuration, the ‘updated’ timestamp is now updated on its record.

  • [Records/Snippets] When editing snippet records, prompted placeholders now provide autocomplete suggestions.

  • [Portals/Interactions] In website interaction portals, the layout can now be customized. This includes a logo image, logo text, page title, favicon, navigation links, and the floating badge interaction. The layout is defined in KATA when configuring the portal. Logo and favicon images are provided as URIs to resource records.

  • [Portals/Interactions] When configuring website interaction portals, a copy/paste code snippet is provided for including an interaction widget on your website. Previously this syntax was buried in the documentation.

  • [Portals/Interactions] In website interaction portals, interactions open in wide mode when viewing the portal directly (rather than the widget on a third-party website).

  • [Portals/Interactions] In website interaction portals, styles are more easily configurable from third-party website stylesheets using CSS --var variables.

  • [Records/Usability] All record editors now support the warning when closing the popup before saving.

  • [Debug] In the /debug/status endpoint, a new scheduler section shows stats for all scheduler jobs, including the last run time. This simplifies monitoring and alerts.

  • [Automations/Logs] In Setup » Developers, a new Automation Logs page allows administrators to view and purge logs from all automations in one place. Thanks to @mryanb for the request!

  • [UI/Themes] Added a toggle for dark/light mode in the top right of every page, after the worker name. This instantly switches between themes and updates the worker preference.

  • [Resources/Images] Added a new ‘Image’ resource type for logos, icons, and other artwork in the worker interface. This supports PNG, JPEG, GIF, and SVG images. SVG images are sanitized.

  • [UI/Logo] SVG images can now be used for the UI logo.

  • [UI/Styles/Dark] In Setup->Branding, separate logos may be uploaded for light mode and dark mode. Logo images are now stored as ‘Resource’ records rather than in the storage filesystem. The 10.2 update will convert existing logos to a resource. The default Cerb logos now use SVG sources for sharper display on high-resolution screens.