Storing User Input Example
    • Dark
      Light
    • PDF

    Storing User Input Example

    • Dark
      Light
    • PDF

    Article summary

    This example will show how to manage the persistence of message-related data using Rocket.Chat Apps-Engine.

    Doing this involves creating a class MessagePersistence in the Apps root folder that interacts with Rocket.Chat persistence layer. This class will host static methods to add, remove, and query data associated with messages, rooms, and specific IDs.

    import { IPersistence, IPersistenceRead } from '@rocket.chat/apps-engine/definition/accessors';
    import { RocketChatAssociationModel, RocketChatAssociationRecord } from '@rocket.chat/apps-engine/definition/metadata';
    import { IRoom } from '@rocket.chat/apps-engine/definition/rooms';
    
    export class MessagePersistence {
        // add records
        public static async persist(persis: IPersistence, room: IRoom, id: string): Promise<boolean> {
            const associations: Array<RocketChatAssociationRecord> = [
                new RocketChatAssociationRecord(RocketChatAssociationModel.MISC, 'message'), 
                new RocketChatAssociationRecord(RocketChatAssociationModel.ROOM, room.id),
                new RocketChatAssociationRecord(RocketChatAssociationModel.MISC, id),
            ];
    
            try {
                await persis.updateByAssociations(associations, { id }, true);
            } catch (err) {
                console.warn(err);
                return false;
            }
    
            return true;
        }
    
        // query all records within the "scope" - message
        public static async findAll(persis: IPersistenceRead): Promise<Array<string>> {
            const associations: Array<RocketChatAssociationRecord> = [
                new RocketChatAssociationRecord(RocketChatAssociationModel.MISC, 'message'),
            ];
    
            let result: Array<string> = [];
            try {
                const records: Array<{ id: string }> = (await persis.readByAssociations(associations)) as Array<{ id: string }>;
    
                if (records.length) {
                    result = records.map(({ id }) => id);
                }
            } catch (err) {
                console.warn(err);
            }
    
            return result;
        }
    
        // query all records by room within the "scope" - message
        public static async findByRoom(persis: IPersistenceRead, room: IRoom): Promise<Array<string>> {
            const associations: Array<RocketChatAssociationRecord> = [
                new RocketChatAssociationRecord(RocketChatAssociationModel.MISC, 'message'),
                new RocketChatAssociationRecord(RocketChatAssociationModel.ROOM, room.id),
            ];
    
            let result: Array<string> = [];
            try {
                const records: Array<{ id: string }> = (await persis.readByAssociations(associations)) as Array<{ id: string }>;
    
                if (records.length) {
                    result = records.map(({ id }) => id);
                }
            } catch (err) {
                console.warn(err);
            }
    
            return result;
        }
    
        // remove all records by room within the "scope" - message
        public static async removeByRoom(persis: IPersistence, room: IRoom): Promise<boolean> {
            const associations: Array<RocketChatAssociationRecord> = [
                new RocketChatAssociationRecord(RocketChatAssociationModel.MISC, 'message'),
                new RocketChatAssociationRecord(RocketChatAssociationModel.ROOM, room.id),
            ];
    
            try {
                await persis.removeByAssociations(associations);
            } catch (err) {
                console.warn(err);
                return false;
            }
    
            return true;
        }
    
        // remove all records by id within the "scope" - message
        public static async removeById(persis: IPersistence, id: string): Promise<boolean> {
            const associations: Array<RocketChatAssociationRecord> = [
                new RocketChatAssociationRecord(RocketChatAssociationModel.MISC, 'message'),
                new RocketChatAssociationRecord(RocketChatAssociationModel.MISC, id),
            ];
    
            try {
                await persis.removeByAssociations(associations);
            } catch (err) {
                console.warn(err);
                return false;
            }
    
            return true;
        }
    
        // remove all records within the "scope" - message
        public static async clear(persis): Promise<boolean> {
            const associations: Array<RocketChatAssociationRecord> = [
                new RocketChatAssociationRecord(RocketChatAssociationModel.MISC, 'message'),
            ];
    
            try {
                await persis.removeByAssociations(associations);
            } catch (err) {
                console.warn(err);
                return false;
            }
    
            return true;
        }
    }

    The following was achieved from the code block above:

    • The persist method adds or updates a record in the persistence layer and associates it with a specific room and message Id.

    • findAll method fetches all records associated with 'message' and returns an array of their IDs.

    • The findByRoom method retrieves all message IDs associated with a specific room.

    • removeByRoom method removes all records associated with a specific room within the 'message' scope. It returns true if successful and false otherwise.

    • removeById deletes all records associated with a specific message ID within the 'message' scope.

    • clear Deletes all records in the "message" scope.

    To show the use case. The executePostMessageSent class defined while managing the internal state can be modified to the code below:

    import { IAppAccessors, IHttp, ILogger, IModify, IPersistence, IRead } from '@rocket.chat/apps-engine/definition/accessors';
    import { App } from '@rocket.chat/apps-engine/definition/App';
    import { IMessage, IPostMessageSent } from '@rocket.chat/apps-engine/definition/messages';
    import { IAppInfo } from '@rocket.chat/apps-engine/definition/metadata';
    import { IRoom } from '@rocket.chat/apps-engine/definition/rooms';
    
    // Import the MessagePersistence class
    import { MessagePersistence } from './MessagePersistence';
    
    export class MyRocketChatApp extends App implements IPostMessageSent {
        constructor(info: IAppInfo, logger: ILogger, accessors: IAppAccessors) {
            super(info, logger, accessors);
        }
    
        public async executePostMessageSent(
            message: IMessage,
            read: IRead,
            http: IHttp,
            persistence: IPersistence,
            modify: IModify
        ): Promise<void> {
            const room: IRoom = message.room;
            
            const messageId: string = message.id ?? 'default-id';
    
            // Example: Persist the message ID
            const success = await MessagePersistence.persist(persistence, room, messageId);
            if (success) {
                this.getLogger().log(`Message ID ${messageId} persisted successfully.`);
            } else {
                this.getLogger().error(`Failed to persist message ID ${messageId}.`);
            }
    
            // Example: Retrieve all message IDs
            const allMessageIds = await MessagePersistence.findAll(read.getPersistenceReader());
            this.getLogger().log(`All message IDs: ${allMessageIds.join(', ')}`);
    
            // Example: Remove all messages by room
            const removeSuccess = await MessagePersistence.removeByRoom(persistence, room);
            if (removeSuccess) {
                this.getLogger().log(`All messages in room ${room.id} removed successfully.`);
            } else {
                this.getLogger().error(`Failed to remove messages in room ${room.id}.`);
            }
        }
    }

    Here, the MessagePersistence class is imported, and the methods persist, findAll, and removeByRoom are called to store the message ID, get all the messages stored in the message scope, and delete all the messages associated with the room.

    Send a few messages in a channel to observe the code in action. Then, navigate to Marketplace > Private Apps. Select the app you deployed and access the logs. Among the various logs, locate the one labeled executePostMessageSent. Open it, and you should find a message that resembles the following:

    The image above shows the logs after sending messages in the “General” channel.


    Was this article helpful?

    Changing your password will log you out immediately. Use the new password to log back in.
    First name must have atleast 2 characters. Numbers and special characters are not allowed.
    Last name must have atleast 1 characters. Numbers and special characters are not allowed.
    Enter a valid email
    Enter a valid password
    Your profile has been successfully updated.
    ESC

    Eddy AI, facilitating knowledge discovery through conversational intelligence