Botsquad documentation logo

Content management

Now that we know how we can store data inside our bot, without it touching our bot’s code directly, you might want to give technically skilled people access to these files, in order for them to edit them.

However, some people can be afraid of “code” views, even if it is just a YAML file. And they risk breaking the bot by entering incorrect data, or destroying the entire file.

To address this, Botsquad incorporates a basic content management system (CMS). It is possible to invite users into the studio, giving them just the editor access role. With this role, they cannot see or edit a bot’s code, and they also cannot edit any data files directly.

The CMS lives in a dedicated tab on the editor page, called Content. It is composed of multiple parts, called Content sections. Each section has a descriptive title and an icon, to indicate its purpose.

Content sections

When you have created your first content definition, a new content tab is enabled in the bot editor, showing the available content sections. It looks like this:


On the left side, there are the various content sections; in this case there is only one, named “Configuration”. In the middle, it shows the actual configuration form. Any data you enter in this form, gets saved in a YAML file in the bot’s scripts.

When you change the content, you can try it out directly in the bot by clicking the Run button.

You’ll notice that, as soon as you change any data, you’ll see the publish box pop up. Click Publish to put the changes live, or revert to undo any changes to the data.

Editors only see this “Content” tab, not the Files or Published tabs.

Content definition YAML

Every content section is represented by a single content definition file: a special YAML script which is part of your bot.

To create a content section like the one above, start by creating a Content definition YAML file in your bot:


Then, hit publish, and immediately the Content section becomes visible in the studio.

The content definition you added looks like the following:

# This is an example "Content Definition" YAML file.
# Files like these define sections of the bot's CMS. Each section
# creates either a form or a data table, which can be edited by users
# (editors) that do not have access to this bot's code.
# For more information about the CMS feature:
type: form # or 'table'

# Define where the content gets stored
  type: script # stored inside a script file
  script_title: config  # Please create a YAML file with this title!

# title of the CMS section
title: Configuration

# see for possible icon names
icon: cog

# Optional extra description / help text
description: This is a configuration form

# The form definition, defines the data that can be edited
  # the JSON schema, describing the form
    type: object
        type: string
        title: Account name
        type: boolean
        title: Enable advanced features
        type: boolean
        title: Enable ludicrous mode
    # specifies the ordering of the fields
      - account_name
      - "*" # all the others

It is heavily commented and should be pretty much self explanatory. A content definition like this defines a section in the CMS part of the bot, with a title, an icon, a possible description, and the definition of the actual form. The storage section defines where the content should be stored. For now, content is always stored in a script, so you need to make sure that there is a data script with the same name as given in the storage.script_title key.

JSON Schema

The form.schema key is the most important key of the content definition: the schema defines the shape of the content. For this, we use JSON schema, which is a way to describe how data looks. And in our case, it also describes how the form looks that will be shown in the CMS.

For composing the form, we use the React JSON Schema Form library. So most options described there are functional and usable in the content definition. The Form customization section especially, goes into detail on the available customization options.

Specialized content widgets in forms

By using ui:widget in the UI schema, it is possible to use form widgets that are specialized for editing a specific type of content. The following are supported:

OAuth tokens

It is possible to render an OAuth connect button inside a form, to be able to configure a bot’s OAuth connection to an integration provider from within a CMS form.

For this to work, you need to set up an integration with an OAuth provider in the integrations.yaml file (See API / OAuth integrations on how to set that up).

Specify integration_token as ui:widget, and add the alias to the integration provider to the ui:options, like below:

      ui:widget: integration_token
        alias: google

In this example we assume that you have an integration configured under the alias “google”.

When you have set all of this up, you will see a “Request Authorization” button rendered inline in the form, which triggers the start of the OAuth flow.

Translatable content

By using the ui:field: i18n option in the form’s UI schema definition, fields are marked as being translable.

  # the JSON schema, describing the form
    type: object
        type: string
        title: Account name
      ui:field: i18n # mark the account_name as translatable

Next to each field that is translateable, a flag will appear like this:

translatable content

Language flags are semi-transparent when the corresponding string is still empty.

It is also possible to combine ui:widget with ui:field: i18n; so in that way it is possible to create a multilingual location, file or image picker.

CSV / spreadsheet data

Besides defining forms, there is also a second content management option, which is used to edit CSV files. By specifying type: table in the content definition, the content section presents an Excel-like spreadsheet data:


The contents of the spreadsheet is fully editable, and the data itself is stored in a CSV file in your bot’s scripts.

The names of the columns are stored in the content definition file, as you don’t want content editors to change these names.

The corresponding content definition file looks like this:

type: table
  type: script
  script_title: users
title: Users
icon: people
  - id
  - first_name
  - last_name
  - age