apps-engine event handlers

apps-engine event handlers

  • 2020-4-21

Here we take creating a new livechat room closed event handler as an example.

Update AppMethod enum

The enum AppMethod maintains all the methods available to the app, thus we need to update this enum to the beginning.

  • Edit the file definition/metadata/AppMethod.ts, add EXECUTE_POST_LIVECHAT_ROOM_CLOSED = 'executePostLivechatRoomClosed' to the AppMethod enum.

Create IPostLivechatRoomClosed interface

Creating a new IPostLivechatRoomClosed interface so that apps can choose whether to implement this interface according their actual needs.

  • Create a new file IPostLivechatRoomClosed.ts under the directory definition/livechat

  • Define the interface IPostLivechatRoomClosed in this file, the content is something like below:

    IPostLivechatRoomClosed.ts
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    import { IHttp, IPersistence, IRead } from '../accessors';
    import { AppMethod } from '../metadata';
    import { ILivechatRoom } from './ILivechatRoom';

    /**
    * Handler called after a livechat room is closed.
    */
    export interface IPostLivechatRoomClosed {
    /**
    * Method called *after* a livechat room is closed.
    *
    * @param livechatRoom The livechat room which is closed.
    * @param read An accessor to the environment
    * @param http An accessor to the outside world
    * @param persistence An accessor to the App's persistence
    */
    [AppMethod.EXECUTE_POST_LIVECHAT_ROOM_CLOSED](data: ILivechatRoom, read: IRead, http: IHttp, persistence: IPersistence): Promise<void>;
    }

  • Export the new interface in the definition/livechat/index.ts file.

Update AppInterface enum

We maintain all interfaces that apps can implement via a enum AppInterface in the file AppInterface.ts under the directory definition/metadata. Notice that currently all items of AppInterface are exactly events' keys that we used them on the RocketChat side. In short, AppInterface maintains all the event handlers that apps can choose to implement.

  • Add the new interface we created above IPostLivechatRoomClosed = IPostLivechatRoomClosed to this enum.

Update AppListenerManager

Another essential step that we need to finish is to execute the new AppMethod executePostLivechatRoomClosed and the contextual data to it while receiving corresponding events. We do this work in the class AppListenerManager of the file AppListenerManager.ts in the directory server/managers.

  • Update the method executeListener's signature (params' data type and return value's data type) if needed

  • Add a new case branch to the method executeListener

    1
    2
    3
    4
    ...
    case AppInterface.IPostLivechatRoomClosed:
    return this.executePostLivechatRoomClosed(data as ILivechatRoom);
    ...

  • Define a new event handler method executePostLivechatRoomClosed

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    private async executePostLivechatRoomClosed(data: ILivechatRoom): Promise<void> {
    const cfLivechatRoom = Utilities.deepCloneAndFreeze(data);

    for (const appId of this.listeners.get(AppInterface.ILivechatRoomClosedHandler)) {
    const app = this.manager.getOneById(appId);

    if (!app.hasMethod(AppMethod.EXECUTE_LIVECHAT_ROOM_CLOSED_HANDLER)) {
    continue;
    }

    await app.call(AppMethod.EXECUTE_LIVECHAT_ROOM_CLOSED_HANDLER,
    cfLivechatRoom,
    this.am.getReader(appId),
    this.am.getHttp(appId),
    this.am.getPersistence(appId),
    );
    }
    }

    executePostLivechatRoomClosed is a manager method that is responsible for distributing the contextual data to each event handler app.call(AppMethod.EXECUTE_POST_LIVECHAT_ROOM_CLOSED, data) of apps who implemented the interface. As for the method app.call, it's a common wrapper. We need to logging, doing some checks before executing the real events handlers that apps implemented.