NAV Navbar
HTTP JavaScript
  • Introduction
  • Getting started
  • Data types
  • Bot API
  • Mainframe server API
  • Mainframe client UI
  • Support
  • Introduction

    Welcome to the Mainframe bots documentation!

    Mainframe is a cross-platform "work OS" available for Android, iOS, macOS and Windows allowing companies to organize their daily operations by providing live communications, simple task management and strong access control.

    Mainframe bots allow developers to use Mainframe as a platform they can leverage to provide rich interactions to users and companies, notably by sending and receiving messages, displaying rich UIs that will work across all platforms, and opening external URLs.

    This documentation will guide you through the process of creating a simple bot you will be able to use right away in all Mainframe clients.

    Getting started

    Registration

    Open the More Settings screen in the main menu

    Go to the bottom of the settings screen

    Go to the bottom of the  screen

    The first thing you will need is to register your bot with Mainframe, by opening the developer portal in the Mainframe client and creating a new bot.

    1. Open the main menu by clicking your avatar/name and press the MORE SETTINGS button to open the settings.

    2. At the bottom of the settings screen, find the DEVELOPER section and press the MY BOTS button.

    3. Go to the bottom of the screen and press the NEW BOT button.

    4. Fill the bot creation form.

    The username will be an unique identifier for your bot in Mainframe, if it is already used by a Mainframe user or another bot, the registration will fail and you will have to choose another username.
    The username can only contain lowercase alphanumeric characters and underscores.

    You will need to fill the entire BASIC section of the form and provide your bot WebHook URL in the the CONFIG section.

    Once you have completed the form, press the SAVE button and and copy the provided secret. Keep this secret safe, you will need it when communicating with the Mainframe API.

    Hello world

    // Import the server factory from the bot SDK
    const { startServer } = require('@mainframe/bot-sdk')
    
    // Start the server with the provided handlers
    startServer({
      // Add handler for bot being added to a conversation
      conversation_added(payload, context) {
        // Send a "Hello world" message to the conversation the bot has been added to
        context.sendMessage({
          conversation_id: payload.conversation_id,
          message: 'Hello world',
        })
      },
    })
    
    Event from Mainframe: your bot got added to a conversation
    
    POST https://bot-api.example.com/conversation_added HTTP/1.1
    Content-Type: application/json; charset=utf-8
    
    {
      "user_id": "<unique user ID>",
      "conversation_id": "<unique conversation ID>"
    }
    

    Let's get started by building a bot that simply sends a "Hello world" message when added to a conversation.

    To achieve this, your bot server will need to implement the /conversation_added endpoint.

    Once your bot is added to a conversation, the Mainframe server will call your service's /conversation_added endpoint with the payload presented on the side.

    Message from your bot
    
    POST https://api.mainframe.com/bots/v1/send_message HTTP/1.1
    Authorization: Mainframe-Bot <your bot secret>
    Content-Type: application/json; charset=utf-8
    
    {
      "conversation_id": "<conversation ID provided by Mainframe>",
      "message": "Hello world"
    }
    

    You can ignore the user_id for now, but we will need the conversation_id value to send a message by sending a POST request to https://api.mainframe.com/bots/v1/send_message, as presented on the side.

    That's it! Your bot will now send a "Hello world" message any time it is added to a conversation.

    Users

    All users interacting with your bot will be registered Mainframe users using one of the clients. As such, you can consider they are authenticated with Mainframe and uniquely identified by the user_id provided.

    Authentication

    If your service provides its own authentication and user data, you may want to associate Mainframe users with your own users.

    To achieve this, any /post request can return a response containing an AuthenticationData payload the client will use to open the provided URL.
    Once the authentication is complete, or if it fails or gets cancelled by the user, your server must bring the user back to the Mainframe client, either by using a specific web page on our domain, or open the Mainframe app directly by providing one of the following states:

    If your authentication does not have a dedicated page to redirect the user, you can use the one provided by Mainframe: https://mainframe.com/bots/auth/?state={state}&name={name}&logo_url={url}, with the following values:

    You can also decide to redirect directly to the Mainframe app, using the mainframe://bots/authentication/{state} URI, where state has a value of "cancel", "error" or "success" as presented above.

    If you provide a payload Object as part of the AuthenticationData, the client will perform a /post request to your bot server with this payload when the authentication is successful. When no payload is provided, no further action will be performed by the client once the user is back.

    By default, a generic message will be displayed in the client asking the user to authenticate. You can also provide a custom message using the message field of the BotResponse.

    Conversations

    Conversations are a core concept of Mainframe, they are the main context where users interact with other users and bots. When the user will initiate interactions with your bot in the context of a conversation, Mainframe will provide the unique conversation_id identifying this context.

    Subscriptions

    // Request from the Mainframe client
    
    POST https://bot-api.example.com/post HTTP/1.1
    Content-Type: application/json; charset=utf-8
    
    {
      "data": {
        "any": "data from subscriptionCreatePayload"
      },
      "context": {
        "user_id": "<unique user ID>",
        "conversation_id": "<unique conversation ID>",
        "subscription_token": "<unique token to use>"
      }
    }
    
    // Call to Mainframe API to setup the subscription
    
    POST https://api.mainframe.com/bots/v1/setup_subscription HTTP/1.1
    Content-Type: application/json; charset=utf-8
    Authorization: Mainframe-Bot <secret>
    
    {
      "subscription_token": "<provided token>",
      "label": "Alice's news feed"
    }
    
    // Response from Mainframe API
    
    HTTP/1.1 200 OK
    Content-Type: application/json; charset=utf-8
    
    {
      "subscription_id": "<unique subscription ID>"
    }
    
    // Response from the bot server to the Mainframe client
    
    HTTP/1.1 200 OK
    Content-Type: application/json; charset=utf-8
    
    {
      "success": true
    }
    

    Subscriptions allow bot users to define specific parameters about the bot behavior for a given conversation. This can notably be used by the bot to define what kind of messages it should sent, or when.
    A more advanced use case is also to allow a bot to leverage one user authentication in order to provide data from a remote server to a conversation, for example Alice could enable a "RSS bot" in a conversation and provide a RSS feed URL she has access to using her credentials, so that the RSS bot could read from the feed and send messages to the conversation associated with this subscription.

    In order to enable subscriptions the bot configuration must provide a subscriptionCreatePayload Object when registering a bot. This payload must be a valid JSON Object, and will be sent by the client by calling the /post endpoint when an user decides to setup a subscription in a conversation.
    If no further action is required, the bot server can return a BotResponse simply containing a {"success": true} payload, or it can initiate a client-side flow by providing a response containing an AuthenticationData or ModalData payload. When making these /post requests, the client will provide a subscription.token to the bot server in the request context. The bot server needs to make a /setup_subscription request to Mainframe's server in order to create the subscription with an human-readable label and retrieve the unique subscription_id generated.

    Bots can also allow users to edit an existing subscription by providing a subscriptionEditPayload in the bot configuration and making an /edit_subscription request to Mainframe's server.

    When providing a subscriptionCreatePayload in the configuration, the bot server must also ensure to implement the /delete_subscription endpoint that will be called by Mainframe when a subscription should be removed. The bot server must ensure all subscription data is cleared for the provided subscription_id when this endpoint is called. Furthermore, if somethings occurs in the bot domain to render a subscription invalid (for example, the resource subscribed to no longer exists), the bot server can inform Mainframe and have the subscription removed by making a /delete_subscription request.

    Receiving messages

    Messages can be received by your bot in two cases:

    In both cases, you can receive the messages sent by the user by implementing the /mention endpoint that will notably provide you the conversation_id you can then use to call the /send_message API to reply in the relevant conversation.

    You bot can register domains for URLs it supports in order to provide rich link previews attached to the messages the links are added to.

    In order to add link previews support, you need to register the relevant domains in your bot configuration, and implement the /preview endpoint.

    Custom interactions

    The Mainframe platform provides a lot of flexibility for bot developers to create the interactions they need with the Mainframe client and users, by providing three main UI contexts in the client:

    The Mainframe platform also provides a generic handler for the bot server to receive data from the Mainframe client by implementing the /post endpoint.

    Menu buttons screenshot

    Menus present a simple list of buttons your bot integration can leverage to allow the user to initiate specific flows. Some flows can be very simple, for example having a menu button with type "open_url" pointing to your website or a specific page, but it is also possible to initiate interactions within the Mainframe client, using the "open_modal" type and an associated payload that will be sent to the /post endpoint of your bot server, that can in return describe an UI to display in the modal.

    Messages

    Message buttons screenshot

    Messages are the primary asynchronous interaction between bots and users. They can be sent by the bots to any conversation they are added to, and will be visible by all users in this conversation.
    Messages can contain a simple text, a complex UI, or both. By using message buttons, they can notably allow the user to interact with the bot in the context of this message.

    Modals

    Modal buttons screenshot

    Modals provide the richest user experience a bot can implement in the Mainframe client.

    While some modals can be simple "alerts" only containing a message, and eventually some buttons, they can also be used to render a component tree, and notably use the Form component to ask for user input.

    Message Embeds

    Embed Gif from Giphy Bot

    The message embed action allows a bot to respond with Embed Data containing a UIPayload that can be inserted into a message as an attachment. For example, Giphy bot can allow the user to select a Gif to embed and respond with the appropriate embed payload.

    This action can only be used inside the context of a conversation.

    /post endpoint

    An example request initiated by an user from a menu button

    POST https://bot-api.example.com/post HTTP/1.1
    Content-Type: application/json; charset=utf-8
    
    {
      "data": {
        "action": "new_post_form"
      },
      "context": {
        "user_id": "<unique user ID>",
        "conversation_id": "<unique conversation ID>"
      }
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json; charset=utf-8
    
    {
      "success": true,
      "data": {
        "type": "modal",
        "ui": {
          "buttons": [
            {
              "type": "close_modal",
              "title": "Cancel"
            },
            {
              "type": "form_post",
              "title": "Create",
              "style": "primary",
              "payload": {
                "action": "new_post_submit"
              }
            }
          ],
          "render": {
            "type": "Form",
            "props": {
              "children": {
                "type": "TextInput",
                "props": {
                  "id": "title",
                  "label": "Title"
                }
              }
            }
          }
        }
      }
    }
    

    New request after the user submits the form

    POST https://bot-api.example.com/post HTTP/1.1
    Content-Type: application/json; charset=utf-8
    
    {
      "data": {
        "action": "new_post_submit",
        "form": {
          "title": "Hello world"
        }
      },
      "context": {
        "user_id": "<unique user ID>",
        "conversation_id": "<unique conversation ID>"
      }
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json; charset=utf-8
    
    {
      "success": true,
      "message": "Post successfully created!",
      "data": {
        "type": "modal",
        "ui": {
          "buttons": [
            {
              "type": "close_modal",
              "title": "Cancel"
            },
            {
              "type": "post_payload",
              "title": "Create another",
              "style": "primary",
              "payload": {
                "action": "new_post_form"
              }
            }
          ]
        }
      }
    }
    

    The /post endpoint can be provided by your bot server in order to receive requests initiated by user interactions with your bots from a menu, message or modal described above.

    All requests sent to the /post endpoint will have the shape described by the ClientRequest type and the bot server must return a valid BotResponse.

    Data types

    Whenever possible, the Mainframe client and server will provide strongly-typed payloads to the bot service, and expect responses of a certain shape.

    Context types

    The RequestContext is provided by the server as part of /post requests, in the context object of the payload.

    RequestContext

    type RequestContext = {
      user_id: string,
      conversation_id?: string,
      subscription_id?: string,
      subscription_token?: string,
    }
    
    Key Type Required
    user_id string yes
    conversation_id string when the request is sent from a conversation
    subscription_id string when editing a subscription
    subscription_token string when creating or editing a subscription

    UI types

    These types are the ones supported by the client to render custom UIs from the bots.

    UIButton

    type UIButton = {
      type: 'copy_url' | 'open_url' | 'open_modal' | 'close_modal' | 'form_post' | 'post_payload' | 'message_embed',
      title?: string,
      icon?: string,
      modalTitle?: string,
      payload?: Object,
      style?: 'primary' | 'secondary' | 'default',
      url?: string,
    }
    

    A generic type for buttons.

    Key Type Required Value
    type enum yes "copy_url", "open_url", "open_modal", "close_modal", "form_post", "post_payload" or "message_embed"
    title string if type is not "copy_url" or "open_url" displayed in UI
    payload Object when type is "open_modal", "message_embed" or "post_payload"
    url string when type is "copy_url" or "open_url"
    style enum no "primary" (main call to action), "secondary" or "default" (plain, default when not provided)
    icon string no icon URL
    modalTitle string no

    Form types

    type BasicValue = boolean | number | string
    type FormOption = string | {label: string, value: BasicValue}
    type FormValue = BasicValue | Array<BasicValue>
    type FormData = {[id: string]: FormValue}
    

    These types are used to describe the shape of the data defined and supported by the client when interacting with forms.

    Name Type
    BasicValue boolean, number or string
    FormOption string or {label: string, value: BasicValue}
    FormValue BasicValue or Array of BasicValue
    FormData Object with keys of type string and values of type FormValue

    Request types

    These types represent the shape of the payload sent by the client when making a /post request.

    RequestData

    type JSON = boolean | number | string | Array<JSON> | {[string]: JSON}
    type BotPayload = {[key: string]: JSON}
    type RequestData = {
      ...BotPayload,
      form?: FormData,
    }
    
    Key Type Required
    form FormData when triggered by button with type "form_post"
    (any string) other data provided by the bot using the payload property when "payload" is provided

    ClientRequest

    type ClientRequest = {
      data: RequestData,
      context: RequestContext,
    }
    
    Key Type Required
    data RequestData yes
    context RequestContext yes

    Response types

    These types represent the shape of the payload that must be provided by the bot server as a result of a /post request.

    UIPayload

    type UIPayload = {
      version: 1,
      buttons?: Array<UIButton>,
      render?: RootComponent,
    }
    
    Key Type Required Value
    version number yes 1 (only currently supported)
    buttons Array of UIButton no
    render RootComponent no

    AuthenticationData

    type AuthenticationData = {
      type: 'authentication',
      url: string,
      payload?: JSON,
    }
    
    Key Type Required Value Description
    type string yes "authentication"
    url string yes
    payload Object no when provided, the client will make a /post request containing this payload after a successful authentication

    EmbedData

    type EmbedData = {
      type: 'embed',
      ui: UIPayload,
    }
    
    Key Type Required Value
    type string yes "embed"
    ui UIPayload yes

    ModalData

    type ModalData = {
      type: 'modal',
      ui: UIPayload,
      title?: string,
    }
    
    Key Type Required Value
    type string yes "modal"
    ui UIPayload yes
    title string no

    The optional title field can be set to change the modal's title in the client.

    BotResponse

    type BotResponse = {
      success: boolean,
      message?: string,
      data?: AuthenticationData | EmbedData | ModalData,
    }
    
    Key Type Required
    success boolean yes
    message string no
    data AuthenticationData, EmbedData or ModalData no

    Bot API

    The Mainframe server will make HTTP calls to the following endpoints exposed by your bot API. Implementing these endpoints is optional, and only depends on the features you want to provide with your bot.

    The Mainframe server will provide the following headers when making these requests:

    Endpoint Required
    /enable no
    /disable when storing user data
    /conversation_added no
    /conversation_removed when storing conversation data
    /delete_subscription if you setup a subscription
    /post if you use custom UIs
    /preview when a user request a preview
    /mention when a participant mention the bot in a conversation

    /enable

    POST https://bot-api.example.com/enable HTTP/1.1
    Content-Type: application/json; charset=utf-8
    
    {
      "user_id": "<unique user ID>"
    }
    

    Called when an user enables your bot.

    Request parameters

    Key Type Required Description
    user_id string yes Unique Mainframe identifier for the user

    /disable

    POST https://bot-api.example.com/disable HTTP/1.1
    Content-Type: application/json; charset=utf-8
    
    {
      "user_id": "<unique user ID>"
    }
    

    Called when an user disables your bot. All user data must be removed from your bot.

    Request parameters

    Key Type Required Description
    user_id string yes Unique Mainframe identifier for the user

    /conversation_added

    POST https://bot-api.example.com/conversation_added HTTP/1.1
    Content-Type: application/json; charset=utf-8
    
    {
      "user_id": "<unique user ID>",
      "conversation_id": "<unique conversation ID>"
    }
    

    Called when your bot is added to a conversation.

    Request parameters

    Key Type Required Description
    user_id string yes Unique Mainframe identifier for the user
    conversation_id string yes Unique Mainframe identifier for the conversation

    /conversation_removed

    POST https://bot-api.example.com/conversation_removed HTTP/1.1
    Content-Type: application/json; charset=utf-8
    
    {
      "user_id": "<unique user ID>",
      "conversation_id": "<unique conversation ID>"
    }
    

    Called when your bot is removed from a conversation. All conversation data and subscriptions must be removed from your bot.

    Request parameters

    Key Type Required Description
    user_id string yes Unique Mainframe identifier for the user
    conversation_id string yes Unique Mainframe identifier for the conversation

    /delete_subscription

    POST https://bot-api.example.com/delete_subscription HTTP/1.1
    Content-Type: application/json; charset=utf-8
    
    {
      "subscription_id": "<unique subscription ID>"
    }
    

    Called when a subscription must be removed.

    Request parameters

    Key Type Required Description
    subscription_id string yes Unique Mainframe identifier for the subscription

    /post

    POST https://bot-api.example.com/post HTTP/1.1
    Content-Type: application/json; charset=utf-8
    
    {
      "data": {...},
      "context": {...}
    }
    

    Called when an user presses a button generated by your bot, to trigger a specific action. Requests will be of type ClientRequest and responses must be of type BotResponse

    Request parameters

    Key Type Required Description
    data RequestData yes Payload sent by the client
    context RequestContext yes Contextual data sent by the server

    /preview

    POST https://bot-api.example.com/preview HTTP/1.1
    Content-Type: application/json; charset=utf-8
    
    {
      "user_id": "<unique user ID>",
      "link": "<URL to preview>"
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json; charset=utf-8
    
    {
      "success": true,
      "data": {...}
    }
    
    

    Called when a user for which your bot has been enabled requests a preview of an URL matching a preview domains your bot has been registered with.

    Request parameters

    Key Type Required Description
    user_id string yes Unique Mainframe identifier for the user
    link string yes The URL to generate a preview for.

    Response parameters

    If your bot cannot generate a payload it should return a response without a data field.

    Key Type Required Description
    success boolean yes true if the request succeeded, false otherwise
    data UIPayload with a Message as the root component no The UIPayload of the preview.

    /mention

    POST https://bot-api.example.com/mention HTTP/1.1
    Content-Type: application/json; charset=utf-8
    
    {
      "user_id": "<unique user ID>",
      "conversation_id": "<Conversation ID>",
      "text": "<Message text>"
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json; charset=utf-8
    
    {
      "success": true
    }
    
    

    Called when a conversation participant has mentioned your bot.
    This can either be an explicit mention (someone types @yourbot in a conversation your bot is added to), or implicitly in the specific conversation between your bot and the user having your bot enabled (in this case this endpoint will be called with any message from the user).

    Request parameters

    Key Type Required Description
    user_id string yes Unique Mainframe identifier for the user
    conversation_id string yes The Mainframe conversation identifier.
    text string yes The complete text of the message containing the bot mention.

    Mainframe server API

    All HTTP requests to the Mainframe API must contain the following headers:

    /send_message

    POST https://api.mainframe.com/bots/v1/send_message HTTP/1.1
    Content-Type: application/json; charset=utf-8
    Authorization: Mainframe-Bot <secret>
    
    {
      "conversation_id": "<conversation ID>",
      "subscription_id": "<subscription ID>",
      "message": "<text message>",
    }
    

    https://api.mainframe.com/bots/v1/send_message

    Send a message in a conversation

    When calling this endpoint, the bot server should provide a subscription_id to indicate how the message is relevant to the conversation. While it is possible for the bot to send messages without a subscription_id, these messages might be rate-limited or even disabled to prevent abuse.

    To send a more discrete message and reduce noise, the bot can send a micro message by setting the type to "micro". Note that micro messages must use the TextMessage component as root in the UIPayload instead of Message.

    Request parameters

    Parameter Type Required Description
    conversation_id string yes Unique ID of the conversation to send the message to, provided by Mainframe
    subscription_id string if the message is related to a subscription Unique ID of the relevant subscription
    message string if data is not provided Text to display
    data UIPayload if message is not provided Custom message UI
    type string no Message type, can be "micro" or any future message types.

    /setup_subscription

    POST https://api.mainframe.com/bots/v1/setup_subscription HTTP/1.1
    Content-Type: application/json; charset=utf-8
    Authorization: Mainframe-Bot <secret>
    
    {
      "subscription_token": "<provided token>",
      "label": "Alice's news feed"
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json; charset=utf-8
    
    {
      "success": true,
      "subscription_id": "<unique subscription ID>"
    }
    

    https://api.mainframe.com/bots/v1/setup_subscription

    Create a subscription

    Request parameters

    Parameter Type Required Description
    subscription_token string yes Token provided by Mainframe
    label string yes Human-readable description for the subscription that will be displayed to users in the list of subscriptions in a conversation, and should briefly describe what kind of events will be provided via the subscription

    /edit_subscription

    POST https://api.mainframe.com/bots/v1/edit_subscription HTTP/1.1
    Content-Type: application/json; charset=utf-8
    Authorization: Mainframe-Bot <secret>
    
    {
      "subscription_token": "<provided token>",
      "label": "Bob's news feed"
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json; charset=utf-8
    
    {
      "success": true,
      "subscription_id": "<unique subscription ID>"
    }
    

    https://api.mainframe.com/bots/v1/edit_subscription

    Edit a subscription

    Request parameters

    Parameter Type Required Description
    subscription_token string yes Token provided by Mainframe
    label string no Human-readable description for the subscription that will be displayed to users in the list of subscriptions in a conversation, and should briefly describe what kind of events will be provided via the subscription; If provided, it will override the existing label

    /delete_subscription

    POST https://api.mainframe.com/bots/v1/delete_subscription HTTP/1.1
    Content-Type: application/json; charset=utf-8
    Authorization: Mainframe-Bot <secret>
    
    {
      "conversation_id": "<conversation ID>",
      "subscription_id": "<subscription ID>",
      "message": "<text message>"
    }
    
    HTTP/1.1 200 OK
    Content-Type: application/json; charset=utf-8
    
    {
      "success": true
    }
    

    https://api.mainframe.com/bots/v1/delete_subscription

    Delete a subscription

    Request parameters

    Parameter Type Required Description
    conversation_id string yes Unique ID of the conversation to remove the subscription from
    subscription_id string yes Unique ID of the relevant subscription
    message string no Optional message to post to the conversation (to explain the reason for removal)

    Mainframe client UI

    The Mainframe client is able to display custom UIs provided by your bot. These UIs are of two main types: buttons and components.

    Buttons

    Buttons are the basis of user interactions in the Mainframe client. They are used to trigger specific client-side behaviors based on their type. Buttons can be used in the following contexts, that affect their supported behavior and UI options:

    Some components can also act in a similar way as buttons to handle user interactions:

    Menu buttons screenshot

    Properties

    Name Type Required Description
    type enum yes one of "copy_url", "open_url", "open_modal", "message_embed", or "post_payload"
    title string yes displayed in UI
    icon string yes URL of the icon displayed in the UI
    payload Object if type is "open_modal", "message_embed" or "post_payload" data sent to the bot when making a request
    url string if type is "copy_url" or "open_url" URL to copy or open
    modalTitle string no optional title of the modal when type is "open_modal"

    Message button

    Message buttons screenshot

    Properties

    Name Type Required Description
    type enum yes one of "copy_url", "open_url", "open_modal" or "post_payload"
    title string if type is not "copy_url" or "open_url" displayed in UI
    payload Object if type is "open_modal" or "post_payload" data sent to the bot when making a request
    url string if type is "copy_url" or "open_url" URL to copy or open
    modalTitle string no optional title of the modal when type is "open_modal"

    Modal buttons screenshot

    Properties

    Name Type Required Description
    type enum yes one of "copy_url", "open_url", "close_modal", "post_payload", "message_embed", or "form_post"
    title string if type is not "copy_url" or "open_url" displayed in UI
    payload Object if type is "post_payload" or "message_embed" data sent to the bot when making a request
    url string if type is "copy_url" or "open_url" URL to copy or open
    style enum no one of "primary" (main call to action), "secondary" or "default" (plain, default when not provided)

    Components

    The UI can be described by "components" objects following React's model. These components can contain properties that are handled by the client in specific ways.

    The components can be separated in two main groups: "root" components that can only be used as root of the component tree, containing children, and "child" components that can only be used as children of other components.

    Root components

    These components must be used as the top-level component provided to the UIPayload:

    Dialog component

    Generic root container for modal dialogs that do not require user inputs. Use the Form component if you need the user to input data.

    Name Type Required Description
    children Author, AvatarList, IconTextGroup, Image, LinkPreview, List, MediaGallery, Text or VideoLinkPreview yes
    noPadding boolean no removes the padding inside the Dialog

    Form component

    Top level component to handle data from its supported children components.
    The Text component can be used to provide additional information to the user if needed.

    Properties

    Name Type Required Description
    children CheckboxGroup, CheckboxItem, Dropdown, MultiLineInput, MultiSelect, RadioButtonSelect, Text or TextInput yes
    payload Object no any additional to be included in the form submission
    data FormData no key-value pairs used to fill the displayed children, matching their id, see the form types for more information

    Message component

    Root container for the UI that goes inside bot messages and embeds, similar to how all form components get nested inside Form.
    For text-only messages, prefer using the TextMessage root component to render a simpler message UI.

    Name Type Required
    children Author, AvatarList, IconTextGroup, Image, LinkPreview, Text or VideoLinkPreview yes

    TextMessage component

    Root container for a text-only message, containing at least one child Text component. Use this container as an alternative to the Message root component to render a simpler message when sending "micro" messages.

    Properties

    Name Type Required
    children Text yes

    Child components

    These components can only be used as a child of another component, either a root component or another child component itself:

    Author component

    Author screenshot

    A component that can represent a user with simple user data.

    Properties

    Name Type Required Description
    displayName string yes renders the main text
    username string yes this is more subtle/italics
    avatarUrl string no to render an avatar
    isCircle boolean no if true then it will be circle avatar

    AvatarList component

    AvatarList screenshot

    A component that represents a horizontal row/list of images.

    Properties

    Name Type Required Description
    avatars Array of string yes the strings are the avatar URLs
    isCircle boolean no if true then avatars will be circles

    CheckboxGroup component

    A group of CheckboxItems but with a main label above the grouping, can only be used a a child of a Form and its children can only be CheckboxItems.

    Properties

    Name Type Required Description
    title string yes a label for the inputs, positioned directly above the checkboxes
    children CheckboxItem yes

    CheckboxItem component

    A text label with a checkbox positioned at the front of the label, can only be used a a child of a CheckboxGroup. The produced FormValue for this input will be a boolean based on the CheckboxItem being checked or not.

    Properties

    Name Type Required Description
    id string yes unique identifier for this form field
    label string yes a label for the checkbox, positioned directly to the right of the checkbox

    A component where users can only select a single option, can only be used a a child of a Form.

    Properties

    Name Type Required Description
    id string yes unique identifier for this form field
    label string yes a label positioned directly above component
    options Array of FormOption yes
    disabled boolean no if the component can be edited or not
    placeholder string no directly inside component, default is "Select an option…"

    IconTextGroup component

    IconTextGroup screenshot

    A component that renders a group of image, primary text and secondary text.
    The image provided by imageUrl will be resized to fit its square container, preserving aspect ratio.

    Properties

    Name Type Required Description
    primaryText string yes the primary text
    secondaryText string no secondary text
    imageUrl string no URL of the image

    Image component

    Image screenshot

    A component that renders an image.

    Properties

    Name Type Required Description
    imageUrl string yes the image URL
    height number yes height of the image
    width number yes width of the image
    allowOpenFullImage boolean no allow the image to be opened in full view
    fillContainer boolean no makes the image fill the container
    backgroundColor string no background color displayed while the image is loading

    LinkPreview component

    LinkPreview screenshot

    A component that represents a link on the web (but can be used in different ways also).

    Properties

    Name Type Required Description
    title string yes the primary text headline
    url string yes the link to open if user clicks
    excerpt string no text to show preview of link
    imageUrl string no URL of the image that represents the link
    domainIconUrl string no URL of the image that represents the domain
    domainName string no the domain

    List component

    Container for ListItem children.

    Name Type Required
    children ListItem yes

    ListItem component

    Item container to be used as a child of a List component.
    When its type property is set, the ListItem acts as a Button.

    Name Type Required Description
    children Author, AvatarList, IconTextGroup, Image, LinkPreview, Text or VideoLinkPreview yes
    type enum no one of "copy_url", "open_url", "open_modal", "message_embed", or "post_payload"
    payload Object if type is "open_modal", "message_embed" or "post_payload" data sent to the bot when making a request
    url string if type is "copy_url" or "open_url" URL to copy or open
    modalTitle string no optional title of the modal when type is "open_modal"

    MediaGallery component

    Container for a list of MediaItem children, supporting interactions on its children based on the provided type when provided.

    Name Type Required Description
    children MediaItem yes
    showSquareImages boolean no When true displays all the children MediaItem images in a square container, defaults to false

    MediaItem component

    A child of MediaGallery displaying an image and possibly supporting interactions based on the parent MediaGallery type when provided.

    Name Type Required Description
    imageUrl string yes the image URL
    height number if the parent MediaGallery showSquareImages is false or not provided height of the image
    width number if the parent MediaGallery showSquareImages is false or not provided width of the image
    type enum no one of "copy_url", "open_url", "open_modal", "message_embed" or "post_payload"
    payload Object when type is "open_modal", "message_embed" or "post_payload" data sent to the bot when making a request
    url string when type is "copy_url" or "open_url" URL to copy or open
    modalTitle string no optional title of the modal when the type is "open_modal"
    isSelected boolean no set to true if the item is selected, defaults to false
    selectedBorderColor string no border color used when isSelected is true
    backgroundColor string no background color displayed while the image is loading

    MultiLineInput component

    Text input for when you want the text to be wrapped and to display multiple lines, can only be used a a child of a Form.

    Properties

    Name Type Required Description
    id string yes unique identifier for this form field
    label string yes a label for the input, positioned directly above the text input
    errorFeedback boolean or string no if there is an error with the input, will highlight red border/red text and display the feedback text if a string is provided

    MultiSelect component

    A component where users can select multiple options, can only be used a a child of a Form. The produced FormValue will be an Array of BasicValue of the selected options.

    Properties

    Name Type Required Description
    id string yes unique identifier for this form field
    label string yes a label positioned directly above the component
    options Array of FormOption yes
    disabled boolean no if the component can be edited or not

    RadioButtonSelect component

    A selector displaying a list of radio buttons with a main label above the grouping.

    Properties

    Name Type Required Description
    id string yes unique identifier for this form field
    title string yes a label positioned directly above all the radio buttons
    options Array of FormOption yes

    Text component

    Text screenshot

    Basic text component, containing a text string or other text components.

    All text components (Text, TextLink, TextStyle...) are displayed inline by their wrapping Text parent. If you need to display text over multiple lines, make sure to adapt the component hierarchy accordingly, as shown in the examples.

    The following text message will be displayed in a single line

    {
      "type": "TextMessage",
      "props": {
        "children": {
          "type": "Text",
          "props": {
            "children": [
              "Hello ",
              {
                "type": "TextStyle",
                "props": {
                  "type": "bold",
                  "children": "bot"
                }
              }
            ]
          }
        }
      }
    }
    

    The following text message will be displayed over two lines

    {
      "type": "TextMessage",
      "props": {
        "children": [
          {
            "type": "Text",
            "props": {
              "children": "Hello "
            },
          },
          {
            "type": "Text",
            "props": {
              "children": {
                "type": "TextStyle",
                "props": {
                  "type": "bold",
                  "children": "bot"
                }
              }
            },
          }
        ]
      }
    }
    

    Properties

    Name Type Required Description
    children string, Text, TextButton, TextHighlight, TextLink, TextStyle or TextSubtle yes can be normal string to be rendered or one of the supported nested components: Text, TextButton, TextHighlight, TextLink, TextStyle and TextSubtle.

    TextButton component

    Text component acting as a button to handle interactions.

    Properties

    Name Type Required Description
    children string yes string to be rendered
    type enum no one of "copy_url", "open_url", "open_modal" or "post_payload"
    payload Object if type is "open_modal" or "post_payload" data sent to the bot when making a request
    url string if type is "copy_url" or "open_url" URL to copy or open
    modalTitle string no optional title of the modal when type is "open_modal"

    TextHighlight component

    A text with a custom color and highlight (background) color.

    Properties

    Name Type Required Description
    children string, TextLink or TextStyle yes this is the text rendered, can be string or one of these nested components: TextLink or TextStyle
    textColor string no Web color for the text
    highlightColor string no Web color for the background

    TextInput component

    A single line text input, can only be used a a child of a Form.

    Properties

    Name Type Required Description
    id string yes unique identifier for this form field
    label string yes a label for the input, positioned directly above the text input
    prefix string no show a string before the text input, like "@" for username input
    buttonTitle string no a small button at end of text input, like "Add" or "Invite" or "Check"
    buttonType enum if buttonTitle is set only possible value is "post_payload"
    buttonPayload Object if buttonType is "post_payload"
    errorFeedback boolean or string no if there is an error with the input, will highlight red border/red text and display the feedback text if a string is provided

    TextLink screenshot

    Text field which is a link to an external URL.

    Properties

    Name Type Required Description
    children string yes this is the text rendered, no other components can be nested in here
    url string yes external URL to open when user clicks on this text component
    noStyle boolean no if true then the UI will not make it super obvious that it’s a link i.e. underline, change color, etc
    noEmojify boolean no if true then it will not emojify the string. An example of when to use this would be if the string is an actual url format and we might want to preserve http://etc for if someone wants to copy URL, etc)

    TextLinks inside TextSubtle screenshot

    On the side is an example of TextLinks nested inside TextSubtle component where noStyle is applied. One links to the board, another to the list (which I know doesn’t actually exist in Trello but just an example):

    TextStyle component

    TextStyle screenshot

    Styled text field.

    Properties

    Name Type Required Description
    children string yes this is the text rendered, no other components can be nested in here
    type enum yes possible values are "bold", "code", "italic" and "strike"

    TextSubtle component

    TextSubtle screenshot

    Basic text field but less prominent (smaller font size, italics, gray, etc).

    Properties

    Name Type Required Description
    children string or TextLink yes can be normal string to be rendered or nested TextLink. Note, any TextLink components nested in here will automatically have noStyle prop.

    VideoLinkPreview component

    LinkPreview screenshot

    A component that represents a link of a video on the web (but can be used in different ways also).

    Properties

    Name Type Required Description
    title string yes the primary text headline
    url string yes the link to open if user clicks
    author string no text to show the author of the video
    imageUrl string no URL of the image that represents the link
    imageWidth number if imageUrl if provided Width of the image thumbnail
    imageHeight number if imageUrl if provided Height of the image thumbnail
    domainIconUrl string no URL of the image that represents the domain
    domainName string no the domain
    videoProvider enum no Currently the desktop app can embed Youtube or Vimeo videos, this prop accepts vimeo or youtube as valid values
    videoId string if videoProvider if provided Used along with videoProvider. Should contain the Youtube or Vimeo video ID, ex: The ID for this youtube url: https://www.youtube.com/watch?v=hhpK96Nkc1Y would be: hhpK96Nkc1Y; and for this vimeo url: https://vimeo.com/17382852 would be 17382852.
    videoWidth number if videoProvider if provided Width of the video player
    videoHeight number if videoProvider if provided Height of the video player
    noPlayButton boolean no When set to true, it will not show the play button overlaying the video thumbnail

    Support

    Get in touch directly with Mainframe developers by joining our support channel in Mainframe!

    If you see any error with this documentation or want to provide any other feedback about it, please open an issue or pull request in our GitHub repository.