App Settings

Your app may need settings that users must configure after installing it, such as tokens. The settings are displayed on the administration interface for the workspace admin to configure and launch the app. Everything under the Settings menu of the app belongs under the app configuration. This tab contains various fields and instructions that can be filled out. If you have a workspace, you can look at the Settings tab of existing apps on the Marketplace to see different app settings.

Define app settings

In this section, we will look at the available configuration details.

Here are some key terms you need to familiarize yourself with:

  • ID - for identifying the settings.

  • Type - the type of value that will be saved.

  • Required - whether or not configuring the app is required.

  • Package value - the default value before the administrator can configure anything.

  • I18n label - the translated name or description of an app.

You can find further details for these properties in the ISetting interface.

Additionally, here are some categories of configurations that Rocket.Chat supports. Each of these will appear differently within the Settings tab of the app in the marketplace.

  • Boolean

  • Code

  • Color

  • Font

  • Number

  • Select

  • String

  • Multi-select

You can create a distinct file containing the configuration settings, in which everything is defined as a basic object. In this file, define each setting separately. In the configurationExtend method, you simply read the file. For each setting, call the provideSetting method, so that each defined setting is read, called, and displayed in the user interface.

This is equivalent to executing the command:

configuration.settings.provideSetting ({
})

Since your app may have multiple settings, it is preferable to organize them all in a separate file and reference them as required in the app's main file.

Every time the administrator modifies the app's configuration via the Settings panel, the onSettingUpdated method is invoked each time. The method will use the new value to make adjustments as necessary. For instance, you can inform an external service that the parameters have changed and the values have been updated. With onPreSettingUpdate, you will receive both the old and updated settings values.

Example to define app settings

Let’s use an example to see how this works. We will add settings to a sample app.

  1. First, we will create a folder called config at the app’s root level.

  2. In this folder, we will create a TypeScript file called Settings.ts. In this file, we will define the app settings.

  3. In the settings file, we will begin by defining the list of settings we want the app to have in an enumeration. The file looks something like this:

import { ISetting, SettingType} from '@rocket.chat/apps-engine/definition/settings';

export enum AppSetting {
    AppDemoOutputChannel = 'appdemo_outputchannel', // here, "AppDemoOutputChannel" is the the setting ID. "appdemo_outputchannel" is the key that can be used to define i18n values.
    AppDemoString = 'appdemo_string_id',
    AppDemoBoolean = 'appdemo_boolean',
    AppDemoCode = 'appdemo_code',
    AppDemoSelect = 'appdemo_select'
}
  1. After this, we will add the settings definition, including the type, descriptions, and other properties for each setting.

export const settings: Array<ISetting> = [
    {
        id: AppSetting.AppDemoOutputChannel, // referring to the setting ID
        section: "AppDemo_FeatureSettings", // the name of the section to put this setting under
        public: true, // Whether this setting is a public setting or not - administrators can see ones which are not public but users can't.
        type: SettingType.STRING, // the category of the setting
        value: "#General", // initial value
        packageValue: "", // the default value
        hidden: false, // whether this setting must be hidden from the admin. Note that a setting cannot be hidden and required at the same time.
        i18nLabel: 'AppDemo_OutputChannel', // this is the name of the setting that will appear in the UI
        i18nDescription: 'AppDemo_OutputChannel_Desc', // you can add a description for the setting to provide additional information to users
        required: false, // specify whether the setting is a mandatory field or not
    },
    {
        id: AppSetting.AppDemoBoolean,
        section: "AppDemo_DemoSection",
        public: true,
        type: SettingType.BOOLEAN, // the boolean cateogory will be displayed as a toggle button on the UI
        value: true,
        packageValue: '',
        hidden: false,
        i18nLabel: 'AppDemo_Boolean',
        required: false,
    },
    {
        id: AppSetting.AppDemoCode,
        section: "AppDemo_DemoSection",
        public: true,
        type: SettingType.CODE, // the code category will be displayed as a code block in the UI
        value: "some code goes here",
        packageValue: "", 
        hidden: false,
        i18nLabel: 'AppDemo_Code',
        required: false,
    },
    {
        id: AppSetting.AppDemoSelect,
        section: "AppDemo_DemoSection",
        public: true,
        type: SettingType.SELECT, // the select category will appear as a drop-down menu containing the values
        values: [{"key": "option1", "i18nLabel": "option_1_label"},{"key": "option2", "i18nLabel": "option_2_label"}], // the list of selectable values when the setting type is "select" or "multi_select"
        packageValue: "",
        hidden: false,
        i18nLabel: 'AppDemo_Select',
        required: false,
    },
    {
        id: AppSetting.AppDemoString,
        section: "AppDemo_DemoSection",
        public: true,
        type: SettingType.STRING,
        value: "this is a value string",
        packageValue: "",
        hidden: false,
        i18nLabel: 'AppDemo_String',
        required: false,
    },
]

Refer to the ISetting interface definition. Here, you will find details on additional properties and whether they are required.

  1. Once we have defined the settings, we will call this file from the app’s main class like this:

// ...import files...
import { settings} from './config/Settings'; // import the settings file that we created

export class SampleApp extends App {
    constructor(info: IAppInfo, logger: ILogger, accessors: IAppAccessors) {
        super(info, logger, accessors);
    }

    public async extendConfiguration(configuration: IConfigurationExtend, environmentRead: IEnvironmentRead): Promise<void> {
        await Promise.all(
            settings.map((setting) =>
                configuration.settings.provideSetting(setting)
            )
        );
    }
}
  1. Now deploy the app and access it on your workspace. Go to the App Info page and select the Settings tab. You will find the settings that we defined.

Additionally, check the logs after updating any settings and saving the changes. Each time a setting is updated, you will find the onSettingUpdated and onPreSettingUpdate methods in the logs.

By default, the logs show the debug method for an instance.

We can also use the onSettingUpdated and onPreSettingUpdate methods in our app to modify the logs as necessary. After the main class, add the method as follows:

public async onSettingUpdated(setting: ISetting, configurationModify: IConfigurationModify, read: IRead, http: IHttp): Promise<void> {
        let list_to_log = ["Some Setting was Updated. SUCCESS MESSAGE: ", setting]

        this.getLogger().success(list_to_log);
        this.getLogger().info(list_to_log);
        this.getLogger().debug(list_to_log);
        this.getLogger().warn(list_to_log);
        this.getLogger().error(list_to_log);

        return super.onSettingUpdated(setting, configurationModify, read, http);
    }

Now, when a setting is updated, the logs will include the messages we have added. In this example, we have defined the success, info, debug, warn, and error methods. The logs will list all these under the onSettingUpdated tab for the same instance. This shows how you can modify your app's settings and logs according to your needs.

Additional example for your reference: Consider the Jitsi app for Rocket.Chat. The settings.ts file contains the various app settings. These settings are called iteratively in the main app file with extendConfiguration. Here, the onSettingUpdated method is also used to update the app configurations.

Configure security protocols

It is common in integrations to transmit certain security protocols for API requests. In the case of the Rocket.Chat REST API, these headers are X-Auth-Token and X-User-Id. See the authentication endpoints for more information. It would be desirable if these headers were always set when making API queries. In such situations, it is customary to generate a personal access token in Rocket.Chat and adding configuration parameters to the app makes sense. These are configured in the extendConfiguration method of the app's primary class.

The client ID and client secret are routinely generated by one of the mechanisms for the app settings. You can see this implemented in the settings file of the Notion app integration with Rocket.Chat.

Furthermore, along with defining the app configurations, you can create internationalization files for different languages. Let's look at the details in the next topic.