From e686f661052dfbe08cdd8f269a352823d4f66b39 Mon Sep 17 00:00:00 2001 From: murtaza98 Date: Wed, 4 Oct 2023 21:41:28 +0530 Subject: [PATCH] new: Add omnichannel Quick reply button tests --- .gitignore | 1 + AppsRocketChatTesterApp.ts | 25 ++++++- app.json | 6 +- dist/appsrocketchattester_0.0.6.zip | Bin 0 -> 11250 bytes endpoints/SendQRBtnMsg.ts | 50 +++++++++++++ handler/ExecuteLivechatBlockActionHandler.ts | 71 +++++++++++++++++++ lib/Message.ts | 66 +++++++++++++++++ 7 files changed, 215 insertions(+), 4 deletions(-) create mode 100644 dist/appsrocketchattester_0.0.6.zip create mode 100644 endpoints/SendQRBtnMsg.ts create mode 100644 handler/ExecuteLivechatBlockActionHandler.ts create mode 100644 lib/Message.ts diff --git a/.gitignore b/.gitignore index 1d19979..9d8401a 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,4 @@ out/ Network Trash Folder Temporary Items .apdisk +.rcappsconfig diff --git a/AppsRocketChatTesterApp.ts b/AppsRocketChatTesterApp.ts index aad6f7f..c32afe0 100644 --- a/AppsRocketChatTesterApp.ts +++ b/AppsRocketChatTesterApp.ts @@ -1,20 +1,40 @@ -import { IAppAccessors, IConfigurationExtend, ILogger } from '@rocket.chat/apps-engine/definition/accessors'; +import { IAppAccessors, IConfigurationExtend, IHttp, ILogger, IModify, IPersistence, IRead } from '@rocket.chat/apps-engine/definition/accessors'; import { ApiSecurity, ApiVisibility } from '@rocket.chat/apps-engine/definition/api'; import { App } from '@rocket.chat/apps-engine/definition/App'; import { IAppInfo } from '@rocket.chat/apps-engine/definition/metadata'; import { SendMessageAsAppUserEndpoint } from './endpoints/SendMessageAsAppUser'; import { SendMessageAsUserEndpoint } from './endpoints/SendMessageAsUser'; +import { SendQRBtnMsgEndpoint } from './endpoints/SendQRBtnMsg'; + import { OpenContextualBarSlashcommand } from './slashcommands/OpenContextualBarSlashcommand'; import { TestArgumentsSlashcommand } from './slashcommands/TestArgumentsSlashcommand'; import { TestSlashcommand } from './slashcommands/TestSlashcommand'; import { TestVideoConfProvider } from './videoConfProviders/TestVideoConfProvider'; import { UnconfiguredVideoConfProvider } from './videoConfProviders/UnconfiguredVideoConfProvider'; +import { UIKitLivechatBlockInteractionContext, IUIKitResponse, IUIKitLivechatInteractionHandler } from '@rocket.chat/apps-engine/definition/uikit'; +import { ExecuteLivechatBlockActionHandler } from './handler/ExecuteLivechatBlockActionHandler'; -export class RocketChatTester extends App { +export class RocketChatTester extends App implements IUIKitLivechatInteractionHandler { constructor(info: IAppInfo, logger: ILogger, accessors: IAppAccessors) { super(info, logger, accessors); } + public async executeLivechatBlockActionHandler( + context: UIKitLivechatBlockInteractionContext, + read: IRead, + _http: IHttp, + _persistence: IPersistence, + modify: IModify, + ): Promise { + const handler = new ExecuteLivechatBlockActionHandler( + this, + context, + read, + modify, + ); + return await handler.run(); + } + public async extendConfiguration(configuration: IConfigurationExtend) { configuration.api.provideApi({ visibility: ApiVisibility.PUBLIC, @@ -22,6 +42,7 @@ export class RocketChatTester extends App { endpoints: [ new SendMessageAsAppUserEndpoint(this), new SendMessageAsUserEndpoint(this), + new SendQRBtnMsgEndpoint(this), ], }); diff --git a/app.json b/app.json index ad13d04..71cb87a 100644 --- a/app.json +++ b/app.json @@ -1,6 +1,6 @@ { "id": "bc4dd4a1-bf9b-408e-83a4-aba7eba0bf02", - "version": "0.0.5", + "version": "0.0.6", "requiredApiVersion": "^1.33.0", "iconFile": "icon.png", "author": { @@ -12,5 +12,7 @@ "nameSlug": "appsrocketchattester", "classFile": "AppsRocketChatTesterApp.ts", "description": "An app that provides endpoints to test Apps integration to Rocket.Chat", - "implements": [] + "implements": [ + "IUIKitLivechatInteractionHandler" + ] } \ No newline at end of file diff --git a/dist/appsrocketchattester_0.0.6.zip b/dist/appsrocketchattester_0.0.6.zip new file mode 100644 index 0000000000000000000000000000000000000000..571ba7f2975d00dab74c5f4bfe241904d51d8826 GIT binary patch literal 11250 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 { + const { userId, roomId } = request.query; + + const room = await read.getRoomReader().getById(roomId); + + if (!room) { + return { + status: HttpStatusCode.NOT_FOUND, + content: `Room "${ roomId }" could not be found`, + }; + } + + + const user = await read.getUserReader().getById(userId); + if (!user) { + return { + status: HttpStatusCode.NOT_FOUND, + content: `User with id "${userId}" could not be found`, + }; + } + + const text = 'This is a main message within Quick Reply Button Message'; + + const blocks = modify.getCreator().getBlockBuilder(); + blocks.addSectionBlock({ + text: blocks.newMarkdownTextObject(text), + }); + blocks.addActionsBlock({ + elements: Array.from({ length: 5 }, (_, i) => blocks.newButtonElement({ + actionId: `button-${i}`, + text: blocks.newPlainTextObject(`Button ${i}`), + value: `button-${i}`, + })), + }); + + const messageBuilder = modify.getCreator().startMessage() + .setRoom(room) + .setSender(user) + .setBlocks(blocks); + + const messageId = await modify.getCreator().finish(messageBuilder); + return this.success(JSON.stringify({ messageId })); + } +} diff --git a/handler/ExecuteLivechatBlockActionHandler.ts b/handler/ExecuteLivechatBlockActionHandler.ts new file mode 100644 index 0000000..ead6073 --- /dev/null +++ b/handler/ExecuteLivechatBlockActionHandler.ts @@ -0,0 +1,71 @@ +import { + IModify, + IRead, +} from '@rocket.chat/apps-engine/definition/accessors'; +import { IApp } from '@rocket.chat/apps-engine/definition/IApp'; +import { ILivechatRoom } from '@rocket.chat/apps-engine/definition/livechat'; +import { + IUIKitResponse, + UIKitLivechatBlockInteractionContext, +} from '@rocket.chat/apps-engine/definition/uikit'; +import { UIKitIncomingInteractionContainerType } from '@rocket.chat/apps-engine/definition/uikit/UIKitIncomingInteractionContainer'; +import { IUser } from '@rocket.chat/apps-engine/definition/users'; +import { createLivechatMessage, deleteAllActionBlocks } from '../lib/Message'; + +export class ExecuteLivechatBlockActionHandler { + constructor( + private readonly app: IApp, + private context: UIKitLivechatBlockInteractionContext, + private read: IRead, + private modify: IModify, + ) {} + + public async run(): Promise { + try { + const interactionData = this.context.getInteractionData(); + const { + visitor, + room, + container: { id, type }, + value, + message, + } = interactionData; + + console.log('interactionData', message?.sender?.username); + + if (!value || !room) { + // most likely, this button has a url to open. So we don't need to do anything here. + return this.context.getInteractionResponder().successResponse(); + } + + if (type !== UIKitIncomingInteractionContainerType.MESSAGE) { + return this.context.getInteractionResponder().successResponse(); + } + + const { servedBy: { username = null } = {}, id: rid } = + room as ILivechatRoom; + + if (!username) { + return this.context.getInteractionResponder().successResponse(); + } + + const appUser = (await this.read + .getUserReader() + .getAppUser()) as IUser; + + await createLivechatMessage( + room, + this.modify, + { text: value }, + visitor, + ); + + const result = await deleteAllActionBlocks(this.modify, appUser, id); + + return this.context.getInteractionResponder().successResponse(); + } catch (error) { + this.app.getLogger().error(error); + return this.context.getInteractionResponder().errorResponse(); + } + } +} diff --git a/lib/Message.ts b/lib/Message.ts new file mode 100644 index 0000000..c12e956 --- /dev/null +++ b/lib/Message.ts @@ -0,0 +1,66 @@ +import { IRead, IModify } from "@rocket.chat/apps-engine/definition/accessors"; +import { IVisitor } from "@rocket.chat/apps-engine/definition/livechat"; +import { IMessageAttachment } from "@rocket.chat/apps-engine/definition/messages"; +import { IRoom } from "@rocket.chat/apps-engine/definition/rooms"; +import { BlockElementType, BlockType, IActionsBlock, IBlock } from "@rocket.chat/apps-engine/definition/uikit"; +import { IUser } from "@rocket.chat/apps-engine/definition/users"; + + +interface IMessageParam { + text?: string; + blocks?: IBlock[]; + attachment?: IMessageAttachment; +} + +export const createLivechatMessage = async ( + room: IRoom, + modify: IModify, + message: IMessageParam, + visitor: IVisitor, +): Promise => { + if (!message) { + return; + } + + const msg = modify + .getCreator() + .startLivechatMessage() + .setRoom(room) + .setVisitor(visitor); + + const { text, attachment } = message; + + if (text) { + msg.setText(text); + } + + if (attachment) { + msg.addAttachment(attachment); + } + + return modify.getCreator().finish(msg); +}; + + +export const deleteAllActionBlocks = async ( + modify: IModify, + appUser: IUser, + msgId: string, +): Promise => { + const msgBuilder = await modify.getUpdater().message(msgId, appUser); + + const withoutActionBlocks: Array = msgBuilder + .getBlocks() + .filter( + (block) => + !( + block.type === BlockType.ACTIONS && + (block as IActionsBlock).elements.some( + (element) => element.type === BlockElementType.BUTTON, + ) + ), + ); + + msgBuilder.setEditor(appUser).setBlocks(withoutActionBlocks); + return modify.getUpdater().finish(msgBuilder); +};