This document covers various examples to help you use the Apps-Engine UI blocks so you can create meaningful user interactions in your apps. The UI blocks are triggered by an action or a condition. In these examples, the UI blocks will be triggered when a message is starred. First, we will see how to create a single block and then we will add more elements to create complex visual layouts.
Create a section block
Let’s create a basic section that contains some text. This will be displayed in a room when a message is starred. The main app class looks like this:
import {
IAppAccessors, IConfigurationExtend, ILogger, IHttp, IModify, IPersistence, IRead, IMessageBuilder, IMessageRead
} from '@rocket.chat/apps-engine/definition/accessors';
import { App } from '@rocket.chat/apps-engine/definition/App';
import { IAppInfo } from '@rocket.chat/apps-engine/definition/metadata';
import { UIKitInteractionType, IUIKitInteractionHandler, UIKitSurfaceType } from '@rocket.chat/apps-engine/definition/uikit';
import { OpenCtxBarCommand } from './contextbar';
import { uiKitMessage } from '@rocket.chat/ui-kit';
import { IMessage, IMessageStarContext, IPostMessageSent, IPostMessageStarred } from '@rocket.chat/apps-engine/definition/messages';
export class uiblocksApp extends App implements IPostMessageStarred {
async executePostMessageStarred(context: IMessageStarContext, read: IRead, http: IHttp, persistence: IPersistence, modify: IModify): Promise<void> {
const messageCreator = modify.getCreator().startMessage();
messageCreator.setBlocks([
{
type: 'section', // the type of block
text: {
type: 'plain_text',
text: 'Message starred! :)',
emoji: true
}
},
])
messageCreator.setRoom(context.message.room);
await modify.getCreator().finish(messageCreator);
}
}
Whenever a message is starred, the app bot returns the text message as shown in this screenshot:
Stack multiple blocks
In the same example, we are going to add more blocks and elements to demonstrate how you can create complex UI layouts.
Add an image block
async executePostMessageStarred(context: IMessageStarContext, read: IRead, http: IHttp, persistence: IPersistence, modify: IModify): Promise<void> {
const messageCreator = modify.getCreator().startMessage();
messageCreator.setBlocks([
{
type: 'section', // section block
text: {
type: 'plain_text',
text: 'Message starred! :)',
emoji: true
}
},
{
type: 'image', // image block
imageUrl: 'https://cdn0.iconfinder.com/data/icons/new-year-holidays-set/200/NewYearIcon7-01-1024.png',
altText: 'test image'
},
])
//messageCreator.setText('Message starred! :)');
messageCreator.setRoom(context.message.room);
await modify.getCreator().finish(messageCreator);
}
Add a divider block and an action block
Now, instead of the image, we will add a divider and an action block. The action block contains a button element.
async executePostMessageStarred(context: IMessageStarContext, read: IRead, http: IHttp, persistence: IPersistence, modify: IModify): Promise<void> {
const messageCreator = modify.getCreator().startMessage();
const appId = this.getID();
messageCreator.setBlocks([
{
type: 'section', // the section block
blockId: 'section_1',
text: {
type: 'plain_text',
text: 'Message starred! :)',
emoji: true
}
},
{
type: 'divider', // the divider block
appId: appId,
blockId: 'divider_block_1'
},
{
type: 'actions', // the action block
appId: appId,
blockId: 'action_block_1',
elements: [ // the elements parameter contains the action element details, in this case, a button element
{
type: 'button',
actionId: 'button_action_1',
appId: appId,
blockId: 'button_action_block_1',
text: {
type: 'plain_text',
text: 'Learn more!'
},
style: 'primary',
value: 'Button element'
}
]
},
])
//messageCreator.setText('Message starred! :)');
messageCreator.setRoom(context.message.room);
await modify.getCreator().finish(messageCreator);
}
The following screenshot shows the UI:
Add an input block
We will define an input block containing the static menu element type:
async executePostMessageStarred(context: IMessageStarContext, read: IRead, http: IHttp, persistence: IPersistence, modify: IModify): Promise<void> {
const messageCreator = modify.getCreator().startMessage();
const appId = this.getID();
messageCreator.setBlocks([
{
type: 'section', // the section block
blockId: 'section_1',
text: {
type: 'plain_text',
text: 'Message starred! :)',
emoji: true
}
},
{
type: 'divider', // the divider block
appId: appId,
blockId: 'divider_block_1'
},
{
type: 'actions', // the action block
appId: appId,
blockId: 'action_block_1',
elements: [ // the elements parameter contains the action element details, in this case, a button element
{
type: 'button',
actionId: 'button_action_1',
appId: appId,
blockId: 'button_action_block_1',
text: {
type: 'plain_text',
text: 'Learn more!'
},
style: 'primary',
value: 'Button element'
}
]
},
{
type: 'input', // the input block
appId: appId,
blockId: 'input_block',
label: {
type: 'plain_text',
text: 'static_input'
},
element: { // the "element" object contains the definition of the type of input block you want to use, in this case, a static select menu
type: 'static_select',
actionId: 'static_select_action_1',
appId: appId,
blockId: 'static_select_block_1',
placeholder: {
type: 'plain_text',
text: 'Select an option:',
},
options: [
{
value: 'option_1',
text: {
type: 'plain_text',
text: 'This is your first option'
}
},
{
value: 'option_2',
text: {
type: 'plain_text',
text: 'This is your second option'
}
}
]
}
}
])
//messageCreator.setText('Message starred! :)');
messageCreator.setRoom(context.message.room);
await modify.getCreator().finish(messageCreator);
}
The following screenshot shows the blocks returned by the app bot:
Add a context block
To the previous code snippet, we will add a context block definition as follows:
{
type: 'context', // the context block
appId: appId,
blockId: 'context_block',
elements: [
{
type: 'plain_text',
text: 'This is a context block'
}
]
},
])
//messageCreator.setText('Message starred! :)');
messageCreator.setRoom(context.message.room);
await modify.getCreator().finish(messageCreator);
}
The following screenshot shows what the context block looks like:
Add a preview block
To this example, we will now add a preview block as follows:
{
type: 'preview', // the preview block
description: [
{
type: 'plain_text',
text: 'Description of preview'
}
],
title: [
{
type: 'plain_text',
text: 'Title of preview'
}
]
},
])
//messageCreator.setText('Message starred! :)');
messageCreator.setRoom(context.message.room);
await modify.getCreator().finish(messageCreator);
}
The following screenshot shows how the preview block appears in the UI: