--- title: "Rocket Chat Slash Command Examples" slug: "slash-command-examples" description: "Explore examples of Rocket Chat slash commands. Build secure, custom workflows to enhance collaboration efficiency." updated: 2026-02-04T09:10:47Z published: 2026-02-04T09:10:47Z canonical: "developer.rocket.chat/slash-command-examples" --- > ## Documentation Index > Fetch the complete documentation index at: https://developer.rocket.chat/llms.txt > Use this file to discover all available pages before exploring further. # Slash Command Examples In this section, we'll look at two slash command examples: - Update user status value and text. - Extend messages to include an image attachment and a custom field. ## Example 1: Update user status To update the user status, we will create a new slash command that takes two parameters: - The first parameter is the status value - online, away, busy, etc. - The second contains the status text. We will refer to the status slash command as `st` to execute code such as: ```plaintext /st busy doing code :) ``` ### Step 1: Create the slash command To implement this, follow these steps: 1. Create a new class named `StatusUpdateCmd.ts` and place it in the same subdirectory `commands` that we created in the [previous section](/v1/docs/slash-commands). 2. Now, add the following code for the status update: ```typescript import {    IHttp,    IModify,    IPersistence,    IRead, } from '@rocket.chat/apps-engine/definition/accessors'; import { IRoom } from '@rocket.chat/apps-engine/definition/rooms'; import {    ISlashCommand,    SlashCommandContext, } from '@rocket.chat/apps-engine/definition/slashcommands'; import { IUser } from '@rocket.chat/apps-engine/definition/users'; export class StatusUpdateCmd implements ISlashCommand {   public command = 'st';   public i18nParamsExample: string = 'status_update_command_params_example';   public i18nDescription: string = 'status_update_command_description';   public providesPreview: boolean = false;     public async executor(context: SlashCommandContext, read: IRead, modify: IModify, http: IHttp, persis: IPersistence): Promise {       const user = context.getSender();       const params = context.getArguments();       const room: IRoom = context.getRoom();             if (!params || params.length == 0) {           return this.notifyMessage(room, read, user, "At least one status argument is mandatory. A second argument can be passed as status text.");       }             let status = params[0];       let statusText = params.length > 1 ? params.slice(1).join(' ') : '';             await modify.getUpdater().getUserUpdater().updateStatus(user, statusText, status);       await this.notifyMessage(room, read, user, "Status updated to " + status + " (" + statusText + ").");   }     private async notifyMessage(room: IRoom, read: IRead, sender: IUser, message: string): Promise {       const notifier = read.getNotifier();       const messageBuilder = notifier.getMessageBuilder();       messageBuilder.setText(message);       messageBuilder.setRoom(room);       return notifier.notifyUser(sender, messageBuilder.getMessage());    } } ``` Here, we are implementing the following: - Fetch the status value from the first argument. This argument is mandatory otherwise, the `notifyMessage` method informs the user that the argument is missing. - Fetch the status message from the second argument, joining the terms with a white space. If the second argument is not passed, the status message remains an empty string. - Update the status according to the value passed using `modify`. - Notify the user about the status update. ### Step 2: Register the slash command In the app's main class, register the new slash command as follows: ```typescript public async extendConfiguration(configuration: IConfigurationExtend) {        configuration.slashCommands.provideSlashCommand(new StatusUpdateCmd()); } ``` > [!WARNING] > You can only have one `extendConfiguration` method in your app's main class. Therefore, make sure to add all your slash commands to this method. Make sure to import the slash command class in the main class: ```typescript import { StatusUpdateCmd } from './commands/StatusUpdateCmd'; ``` All that remains is deployment and testing! ### Step 3: Deploy the app In the command line, go to the app folder and run: ```bash rc-apps deploy --url -u -p ``` - The `<server_url>` parameter is the URL of your Rocket.Chat server. - Replace the placeholders with the URL, username, and password for your server, respectively. After executing this command, your application will be deployed to the server. > **Packaging your app** > > Alternatively, you can execute the `rc-apps package` command. This gives you a compressed zip file of your app that you can upload as a private app to your Rocket.Chat server. ### Step 4: Test the app Send `/st <status> <message>` to any channel. You can see the change in the user status accordingly. The following screenshot shows the result when you enter `/st busy doing code :)`. ![](https://cdn.us.document360.io/27ca1fd4-36d7-4cde-b4eb-97fc1652954c/Images/Documentation/image(188).png) If we execute `/st` with no input, we receive the notification: ![](https://cdn.us.document360.io/27ca1fd4-36d7-4cde-b4eb-97fc1652954c/Images/Documentation/image(94).png) ## Example 2: Extend messages This example explains how to construct an app that is invoked via a slash command, sends a message, and is extended to include an image and a custom field. Rocket.Chat supports numerous attachments (with applicable customizations). For instance, you can attach images, documents, videos, and audio files to messages. ### Step 1: Create the slash command To implement this, follow these steps: 1. Create a new class named `ExtendMessageCommand.ts` and place it in the same subdirectory `commands` that we created in the [previous section](/v1/docs/slash-commands). 2. Now, add the following code: ```typescript import { IHttp, IModify, IPersistence, IRead, IMessageExtender } from '@rocket.chat/apps-engine/definition/accessors'; import { ISlashCommand, SlashCommandContext } from '@rocket.chat/apps-engine/definition/slashcommands'; import { IMessageAttachment } from '@rocket.chat/apps-engine/definition/messages'; class ImageAttachment implements IMessageAttachment {    imageUrl?: string;    constructor(imgUrl: string) {        this.imageUrl = imgUrl;    } } export class ExtendMessageCommand implements ISlashCommand {    public command = 'extend-message';    public i18nParamsExample = '';    public i18nDescription = '';    public providesPreview = false;    public async executor(context: SlashCommandContext, read: IRead, modify: IModify, http: IHttp, persis: IPersistence): Promise {        try {            // Send message [1]            const messageId = await this.sendMessage(context, modify, 'Sending a message!');                        // Get message extender [2]            const messageExtender = await this.getMessageExtender(context, modify, messageId);                        // Create and add image attachment [3]            const img = new ImageAttachment('https://test.rocket.chat/images/logo/logo.svg');            messageExtender.addAttachment(img); // [4]                        // Finish extending [5]            await modify.getExtender().finish(messageExtender);                        await this.notifyUser(context, read, 'Message extended successfully with image!');                    } catch (error) {            await this.notifyUser(context, read, `ERROR: ${error.message || error}`);        }    }    private async sendMessage(context: SlashCommandContext, modify: IModify, message: string): Promise {        const messageStructure = modify.getCreator().startMessage();        const sender = context.getSender();        const room = context.getRoom();        messageStructure            .setSender(sender)            .setRoom(room)            .setText(message);        return modify.getCreator().finish(messageStructure);    }    private async getMessageExtender(context: SlashCommandContext, modify: IModify, messageId: string): Promise {        const sender = context.getSender();        return modify.getExtender().extendMessage(messageId, sender);    }    private async notifyUser(context: SlashCommandContext, read: IRead, message: string): Promise {        const notifier = read.getNotifier();        const messageBuilder = notifier.getMessageBuilder();        messageBuilder.setText(message);        messageBuilder.setRoom(context.getRoom());        await notifier.notifyUser(context.getSender(), messageBuilder.getMessage());    } } ``` The main actions performed by the code above are: - [1] Sends a message and stores the sent message's ID in the `messageId` variable. - [2] Uses the sent message's ID. The `messageExtender` object is returned by the `getMessageExtender` method and stored in the `messageExtender` variable. - [3] Creates the attachment object as an instance of the `ImageAttachment` class. Here, the attachment is an image. - [4] Adds the image attachment to the message using the `addAttachment` method from the `messageExtender` object. Many attachments can be added all at once using the `addAttachments` method. - [5] Finishes the `modifyExtender` object, which is crucial to apply the extensions made to the message and make them visible to the user. **Method:** `sendMessage` The `sendMessage` method needs to return the message's ID after it has been sent. The method must return a `Promise<string>`. **Method:** `getMessageExtender` After obtaining the message's ID, we can get the `messageExtender` object, which enables the addition of custom fields and attachments. ### Step 2: Add image attachment class We will implement the `ImageAttachment` class in the same class: ```typescript import { IMessageAttachment } from '@rocket.chat/apps-engine/definition/messages'; export class ImageAttachment implements IMessageAttachment{    imageUrl?: string;    constructor(imgUrl: string){        this.imageUrl = imgUrl;    } } ``` Here, we use a class attribute with the same identifier and type as in the `IMessageAttachment` interface, which is required for your linked media to be visible to the user. This is because only the variables in your attachment class defined in the `IMessageAttachment` interface will be used to retrieve the attachment's media. You can also construct your own classes for video or audio attachments, or you can group them all into a single class that can accommodate all of these possibilities. Make sure to use the same attributes described in the `IMessageAttachment.d.ts` file. > [!NOTE] > The audio and video formats that are supported in the Rocket.Chat message attachments are identical to HTML audio and video elements. ### Step 3: Register the slash command We must register the slash command in the app's main class, the project's root. ```typescript import { App } from '@rocket.chat/apps-engine/definition/App'; import { IAppInfo } from '@rocket.chat/apps-engine/definition/metadata'; import { ExtendMessageCommand } from './slashcommands/ExtendSlashcommand'; // [1] export class RocketChatTester extends App {    constructor(info: IAppInfo, logger: ILogger, accessors: IAppAccessors) {        super(info, logger, accessors);    }    public async extendConfiguration(configuration: IConfigurationExtend) {        configuration.slashCommands.provideSlashCommand(new ExtendMessageCommand()); // [2]    } } ``` Here, we import our new slash command class and register it in the app's configuration. ### Step 5: Deploy the app To deploy the app, follow [the deployment steps highlighted](/v1/docs/slash-command-examples#step-3-deploy-the-app) in the previous example. ### Step 6: Test the slash command After the app has been deployed, execute the slash command `/extend-message` in any channel. When you execute the registered slash command, a message is sent to the current channel and altered to include the image attachment. The attached image is visible in the message after editing. The following screenshot shows an example: ![](https://cdn.us.document360.io/27ca1fd4-36d7-4cde-b4eb-97fc1652954c/Images/Documentation/image(190).png)