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 withmessage
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 themessage
scope. It returns true if successful and false otherwise.removeById
deletes all records associated with a specific message ID within themessage
scope.clear
Deletes all records in themessage
scope.
The executePostMessageSent
class 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 to the general
channel.