From 340d652d27b2092e19b663849b9b12f641cd8684 Mon Sep 17 00:00:00 2001 From: Henit Chobisa Date: Fri, 31 Mar 2023 09:44:13 +0000 Subject: [PATCH 1/4] feat: Registered and Added Handler for Action Button --- github/GithubApp.ts | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/github/GithubApp.ts b/github/GithubApp.ts index 8659bde..90978f5 100644 --- a/github/GithubApp.ts +++ b/github/GithubApp.ts @@ -1,6 +1,7 @@ import { IAppAccessors, IConfigurationExtend, + IEnvironmentRead, IHttp, ILogger, IModify, @@ -12,6 +13,7 @@ import { IAppInfo } from "@rocket.chat/apps-engine/definition/metadata"; import { GithubCommand } from "./commands/GithubCommand"; import { IUIKitResponse, + UIKitActionButtonInteractionContext, UIKitBlockInteractionContext, UIKitViewCloseInteractionContext, UIKitViewSubmitInteractionContext, @@ -40,6 +42,9 @@ import { IJobContext } from "@rocket.chat/apps-engine/definition/scheduler"; import { IRoom } from "@rocket.chat/apps-engine/definition/rooms"; import { clearInteractionRoomData, getInteractionRoomData } from "./persistance/roomInteraction"; import { GHCommand } from "./commands/GhCommand"; +import { ModalsEnum } from "./enum/Modals"; +import { UIActionButtonContext } from "@rocket.chat/apps-engine/definition/ui"; +import { ExecuteButtonActionHandler } from "./handlers/executeActionButtonHandler"; export class GithubApp extends App { constructor(info: IAppInfo, logger: ILogger, accessors: IAppAccessors) { @@ -101,6 +106,24 @@ export class GithubApp extends App { return this.oauth2ClientInstance; } + public async executeActionButtonHandler( + context: UIKitActionButtonInteractionContext, + read: IRead, + http: IHttp, + persistence: IPersistence, + modify: IModify, + ) : Promise { + + const handler = new ExecuteButtonActionHandler( + this, + read, + http, + modify, + persistence + ) + return await handler.run(context) + } + public async executeBlockActionHandler( context: UIKitBlockInteractionContext, read: IRead, @@ -153,7 +176,7 @@ export class GithubApp extends App { } public async extendConfiguration( - configuration: IConfigurationExtend + configuration: IConfigurationExtend, ): Promise { const gitHubCommand: GithubCommand = new GithubCommand(this); const ghCommand: GHCommand = new GHCommand(this); @@ -189,6 +212,11 @@ export class GithubApp extends App { }, }, ]); + configuration.ui.registerButton({ + labelI18n: "open_issue_message", + actionId: ModalsEnum.NEW_ISSUE_ACTION, + context: UIActionButtonContext.MESSAGE_ACTION, + }) configuration.api.provideApi({ visibility: ApiVisibility.PUBLIC, security: ApiSecurity.UNSECURE, From 982f4ab5d43383b91e0f0cbf0504a167c51ac748 Mon Sep 17 00:00:00 2001 From: Henit Chobisa Date: Fri, 31 Mar 2023 09:44:53 +0000 Subject: [PATCH 2/4] feat: Modified Issues Modal to be compatible with Action Fields --- github/modals/newIssueModal.ts | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/github/modals/newIssueModal.ts b/github/modals/newIssueModal.ts index 18da9ee..d3a3271 100644 --- a/github/modals/newIssueModal.ts +++ b/github/modals/newIssueModal.ts @@ -18,6 +18,7 @@ import { storeInteractionRoomData, getInteractionRoomData, } from "../persistance/roomInteraction"; +import { IRoom } from "@rocket.chat/apps-engine/definition/rooms"; export async function NewIssueModal({ data, @@ -25,6 +26,8 @@ export async function NewIssueModal({ read, persistence, http, + user, + room, slashcommandcontext, uikitcontext, }: { @@ -33,13 +36,19 @@ export async function NewIssueModal({ read: IRead; persistence: IPersistence; http: IHttp; + user?: IUser, + room? : IRoom, slashcommandcontext?: SlashCommandContext; uikitcontext?: UIKitInteractionContext; }): Promise { const viewId = ModalsEnum.NEW_ISSUE_VIEW; const block = modify.getCreator().getBlockBuilder(); - const room = slashcommandcontext?.getRoom() || uikitcontext?.getInteractionData().room; - const user = slashcommandcontext?.getSender() || uikitcontext?.getInteractionData().user; + if (user == undefined && slashcommandcontext != undefined){ + user = slashcommandcontext?.getSender() || uikitcontext?.getInteractionData().user; + } + if (room == undefined && slashcommandcontext != undefined){ + room = slashcommandcontext?.getRoom() || uikitcontext?.getInteractionData().room; + } if (user?.id) { let roomId; @@ -88,7 +97,7 @@ export async function NewIssueModal({ }), }); } - + block.addInputBlock({ blockId: ModalsEnum.ISSUE_TITLE_INPUT, From fa23be6441e5f48f15e207947ea344386846a0a9 Mon Sep 17 00:00:00 2001 From: Henit Chobisa Date: Fri, 31 Mar 2023 09:45:04 +0000 Subject: [PATCH 3/4] feat: Added Action Handler --- github/handlers/executeActionButtonHandler.ts | 92 +++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 github/handlers/executeActionButtonHandler.ts diff --git a/github/handlers/executeActionButtonHandler.ts b/github/handlers/executeActionButtonHandler.ts new file mode 100644 index 0000000..dad2caa --- /dev/null +++ b/github/handlers/executeActionButtonHandler.ts @@ -0,0 +1,92 @@ +import { IRead, IHttp, IModify, IPersistence } from "@rocket.chat/apps-engine/definition/accessors"; +import { BlockType, IImageBlock, IImageElement, IUIKitResponse, UIKitActionButtonInteractionContext } from "@rocket.chat/apps-engine/definition/uikit"; +import { ModalsEnum } from "../enum/Modals"; +import { GithubApp } from "../GithubApp"; +import { NewIssueModal } from "../modals/newIssueModal"; + +export class ExecuteButtonActionHandler { + constructor( + private readonly app: GithubApp, + private readonly read: IRead, + private readonly http: IHttp, + private readonly modify: IModify, + private readonly persistence: IPersistence + ) { } + + public async run( + context: UIKitActionButtonInteractionContext + ): Promise{ + const data = context.getInteractionData(); + + try { + const { actionId } = data; + switch (actionId) { + case ModalsEnum.NEW_ISSUE_ACTION: { + const { message, user, room } = data; + + let modalData; + if (message && (message.text || message.attachments)){ + + // TODO We need to download and upload the files to github first, else rocket.chat won't allow accessing images like below + // const attachmentImageURLs: String[] = [] + // const attachmentVideoURLs: String[] = [] + // const settings = this.read.getEnvironmentReader().getServerSettings(); + // const Site_Url = await settings.getValueById("Site_Url"); + // if (message.attachments){ + // message.attachments.map((attachment) => { + // if (attachment.imageUrl){ + // attachmentImageURLs.push(`### ${attachment.description?.split("|").pop()}\n![image](${Site_Url}/${attachment.imageUrl})`) + // } + // if (attachment.videoUrl){ + // attachmentVideoURLs.push(`### ${attachment.description?.split("|").pop()}\n` + `${Site_Url}/${attachment.videoUrl}`) + // } + // }) + // } + + // if (message.blocks){ + // message.blocks.map((element) => { + // if (element.type === BlockType.IMAGE){ + // element = element as IImageElement + // attachmentImageURLs.push(`### ${element.altText}\n![image](${element.imageUrl})`) + // } + // }) + // } + + // Taking Repository and Body Seperated By Pipe Operator + let pieces = message.text ? message.text.split("|") : [""] + + if (message.text === '' && message.attachments){ + if (message.attachments[0].description){ + pieces = message.attachments[0].description.split("|") + } + } + + + modalData = { + repository: pieces.length === 2 ? pieces[0] : undefined, + template : pieces.length === 2 ? pieces[1] : pieces[0] + // template : (pieces.length === 2 ? pieces[1] : pieces[0]) + (attachmentImageURLs.length !== 0 ? "\n## Screenshots\n" + attachmentImageURLs.join("\n") : "") + (attachmentVideoURLs.length !== 0 ? "\n## Videos\n" + attachmentVideoURLs.join("\n") : "" ) + } + } + + const modal = await NewIssueModal({ + data: modalData, + modify: this.modify, + read: this.read, + persistence: this.persistence, + http: this.http, + user: user, + room: room, + }) + + return context.getInteractionResponder().openModalViewResponse(modal) + } + + } + } catch (error){ + console.log(error) + } + + return context.getInteractionResponder().successResponse() + } +} From 14d75f57a0ae92f2b29f5decbd5a9e45ee4407d2 Mon Sep 17 00:00:00 2001 From: Henit Chobisa Date: Fri, 31 Mar 2023 09:45:41 +0000 Subject: [PATCH 4/4] chore: Modified App Configuration with Added Permission System --- github/app.json | 47 +++++++++++++++++++++++++++++++++++++++++++++ github/i18n/en.json | 5 +++-- github/package.json | 5 +++-- 3 files changed, 53 insertions(+), 4 deletions(-) diff --git a/github/app.json b/github/app.json index 58af157..7a81c8b 100644 --- a/github/app.json +++ b/github/app.json @@ -8,6 +8,53 @@ "homepage": "https://github.com/samad-yar-khan", "support": "https://github.com/samad-yar-khan" }, + "permissions": [ + { + "name": "ui.registerButtons" + }, + { + "name": "api" + }, + { + "name": "slashcommand" + }, + { + "name": "scheduler" + }, + { + "name": "server-setting.read" + }, + { + "name": "server-setting.write" + }, + { + "name": "room.read" + }, + { + "name": "room.write" + }, + { + "name": "message.read" + }, + { + "name": "message.write" + }, + { + "name": "ui.interact" + }, + { + "name": "persistence" + }, + { + "name": "networking" + }, + { + "name": "user.read" + }, + { + "name": "user.write" + } + ], "name": "Github", "nameSlug": "github", "classFile": "GithubApp.ts", diff --git a/github/i18n/en.json b/github/i18n/en.json index 5b24054..c074d7b 100644 --- a/github/i18n/en.json +++ b/github/i18n/en.json @@ -1,3 +1,4 @@ { - "cmd_description": "Search, Share, Review, Merge, Subscribe GitHub Resources and do much more from Rocket.Chat." -} \ No newline at end of file + "cmd_description": "Search, Share, Review, Merge, Subscribe GitHub Resources and do much more from Rocket.Chat.", + "open_issue_message": "🎈 Open Github Issue" +} diff --git a/github/package.json b/github/package.json index d70652c..d3da1ef 100644 --- a/github/package.json +++ b/github/package.json @@ -3,6 +3,7 @@ "@rocket.chat/apps-engine": "^1.36.0", "@types/node": "14.14.6", "tslint": "^5.10.0", - "typescript": "^4.0.5" + "typescript": "^4.0.5", + "@rocket.chat/ui-kit": "^0.31.22" } -} \ No newline at end of file +}