From c6c13ab443d360e97bb0385f5098be1e9d460ef3 Mon Sep 17 00:00:00 2001 From: Joseph Schlitz Date: Fri, 31 Dec 2021 02:15:02 -0500 Subject: [PATCH 1/2] Preliminary Confluence Provider Implementation --- src/index.ts | 2 + src/provider/Confluence.ts | 328 ++++++++++++++++++ test/confluence/confluence-spec.ts | 41 +++ test/confluence/confluence_attachment.json | 37 ++ test/confluence/confluence_blog.json | 23 ++ test/confluence/confluence_comment.json | 38 ++ test/confluence/confluence_label.json | 30 ++ test/confluence/confluence_page.json | 24 ++ test/confluence/confluence_space.json | 22 ++ test/confluence/confluence_user.json | 11 + test/confluence/confluence_webhook_events.txt | 54 +++ 11 files changed, 610 insertions(+) create mode 100644 src/provider/Confluence.ts create mode 100644 test/confluence/confluence-spec.ts create mode 100644 test/confluence/confluence_attachment.json create mode 100644 test/confluence/confluence_blog.json create mode 100644 test/confluence/confluence_comment.json create mode 100644 test/confluence/confluence_label.json create mode 100644 test/confluence/confluence_page.json create mode 100644 test/confluence/confluence_space.json create mode 100644 test/confluence/confluence_user.json create mode 100644 test/confluence/confluence_webhook_events.txt diff --git a/src/index.ts b/src/index.ts index 313054e..901fa95 100644 --- a/src/index.ts +++ b/src/index.ts @@ -13,6 +13,7 @@ import { BitBucket } from './provider/Bitbucket' import { BitBucketServer } from './provider/BitBucketServer' import { CircleCi } from './provider/CircleCi' import { Codacy } from './provider/Codacy' +import { Confluence } from './provider/Confluence' import { DockerHub } from './provider/DockerHub' import { GitLab } from './provider/GitLab' import { Heroku } from './provider/Heroku' @@ -51,6 +52,7 @@ const providers: Type[] = [ BitBucketServer, CircleCi, Codacy, + Confluence, DockerHub, GitLab, Heroku, diff --git a/src/provider/Confluence.ts b/src/provider/Confluence.ts new file mode 100644 index 0000000..3a7e506 --- /dev/null +++ b/src/provider/Confluence.ts @@ -0,0 +1,328 @@ +import { Embed } from '../model/DiscordApi' +import { DirectParseProvider } from '../provider/BaseProvider' + +/** + * https://developer.atlassian.com/server/jira/platform/webhooks/ + */ +export class Confluence extends DirectParseProvider { + constructor() { + super() + this.setEmbedColor(0x1e45a8) + } + + public getName(): string { + return 'Confluence' + } + + public getPath(): string { + return 'confluence' + } + + public async parseData(): Promise { + if (this.body.eventType == null) { + this.nullifyPayload() + return + } + // extract variables from Confluence that don't depend on the event + const user = this.body.userDisplayName || { displayName: 'Anonymous' } + const event = this.body.eventType + + let embed: Embed + + if (event.startsWith('attachment_')) { + embed = this.attachmentEvent(event,user) + this.addEmbed(embed) + } + else if (event.startsWith('blog_')) { + embed = this.blogEvent(event,user) + this.addEmbed(embed) + } + else if (event.startsWith('comment_')) { + embed = this.commentEvent(event,user) + this.addEmbed(embed) + } + else if (event.startsWith('group_')) { + embed = this.groupEvent(event) + this.addEmbed(embed) + } + else if (event.startsWith('label_')) { + embed = this.labelEvent(event,user) + this.addEmbed(embed) + } + else if (event.startsWith('page_')) { + embed = this.pageEvent(event,user) + this.addEmbed(embed) + } + else if (event.startsWith('space_')) { + embed = this.spaceEvent(event,user) + this.addEmbed(embed) + } + else if (event.startsWith('user_')) { + embed = this.userEvent(event) + this.addEmbed(embed) + } + else{ + //This is to nullify the payload for currently unsupported events + this.nullifyPayload() + return + } + + } + + private attachmentEvent(event:string, user:string): Embed { + /** + * Event Triggered when... + attachment_created a file is attached to a page or blog post + attachment_removed a file is deleted (sent to the trash) from the attachments page(not triggered when a version is deleted from the file history) + attachment_restored a file is restored from the trash + attachment_trashed a file is purged from the trash + attachment_updated a new file version of is uploaded directly or by editing the file + + */ + + const title = this.setEventTitle(event) + const action = this.setActionTitle(event) + const content_title = this.body.attachedTo.title + const space = this.body.attachedTo.spaceName + const content_type = this.body.attachedTo.contentType + const url = this.body.attachedTo.self + let description + + if(event.startsWith('attachment_removed')) + { + description = user + ' ' + action + ' from ' + content_type + ' ' + content_title + ' in ' + space + } + else if(event.startsWith('attachment_created') || event.startsWith('attachment_updated')) + { + description = user + ' ' + action + ' on ' + content_type + ' ' + content_title + ' in ' + space + } + else + { + description = user + ' ' + action + } + + const embed: Embed = { + title: title, + url: url, + description : description + } + + return embed + } + + private blogEvent(event:string, user:string): Embed { + /** + * Event Triggered when... + blog_created a blog post is published + blog_removed a blog post is deleted (sent to the trash) + blog_restored a blog post is restored from the trash + blog_trashed a blog post is purged from the trash + blog_updated a blog post is edited + */ + const title = this.setEventTitle(event) + const action = this.setActionTitle(event) + const content_title = this.body.blog.title + const url = this.body.blog.self + + const embed: Embed = { + title: title, + url: url, + description : user + ' ' + action + ' ' + content_title + } + + return embed + } + + private commentEvent(event:string, user:string): Embed { + /** + * Event Triggered when... + comment_created a page comment, inline comment or file comment is made + comment_removed a page comment, inline comment, or file comment is deleted + comment_updated a page comment, inline comment, or file comment is edited + + */ + const title = this.setEventTitle(event) + const action = this.setActionTitle(event) + const content_title = this.body.comment.parent.title + const content_type = this.body.comment.parent.contentType + const space = this.body.comment.spaceName + const url = this.body.comment.parent.self + + const embed: Embed = { + title: title, + url: url, + description : user + ' ' + action + ' on ' + content_type + ' ' + content_title + ' in ' + space + } + + return embed + } + + private labelEvent(event:string, user:string): Embed { + /** + * Event Triggered when... + label_added an existing label is applied to a page, blog post, or space + label_created a label is added for the first time (did not already exist) + label_deleted a label is removed from the last page, blog post, or space, and so ceases to exist + label_removed a label is removed from a page, blog post, or space + + */ + const title = this.setEventTitle(event) + const action = this.setActionTitle(event) + const label_title = this.body.label.name + const space = this.body.labeled.spaceName + const url = this.body.label.self + let description + let content_title + let content_type + + if (event.startsWith('label_created') || event.startsWith('label_deleted')) + { + description = user + ' ' + action + ' ' + label_title + } + else if(event.startsWith('label_removed')) + { + content_title = this.body.labeled.title + content_type = this.body.labeled.contentType + description = user + ' ' + action + ' from ' + content_type + ' ' + content_title + ' in ' + space + } + else if(event.startsWith('label_added')) + { + content_title = this.body.labeled.title + content_type = this.body.labeled.contentType + description = user + ' ' + action + ' to ' + content_type + ' ' + content_title + ' in ' + space + } + + const embed: Embed = { + title: title, + url: url, + description : description + } + + return embed + } + + private pageEvent(event:string, user:string): Embed { + /** + * Event Triggered when... + page_children_reordered the default ordering of pages is changed to alphabetical in the Space Tools > Reorder pages tab(is not triggered when you drag a page, or move a page, to change the page order) + page_created a page is published for the first time, including pages created from a template or blueprint + page_moved a page is moved to a different position in the page tree, to a different parent page, or to another space + page_removed a page is deleted (sent to the trash) + page_restored a page is restored from the trash + page_trashed a page is purged from the trash + page_updated a page is edited (triggered at the point the unpublished changes are published) + + */ + const title = this.setEventTitle(event) + const action = this.setActionTitle(event) + const content_title = this.body.page.title + const url = this.body.page.self + + const embed: Embed = { + title: title, + url: url, + description : user + ' ' + action + ' ' + content_title + } + + return embed + } + + private spaceEvent(event:string, user:string): Embed { + /** + * Event Triggered when... + space_created a new space is created + space_logo_updated a new file is uploaded for use as the logo of a space + space_permissions_updated space permissions are changed in the Space Tools > Permissions tab(is not triggered when you edit space permissions using Inspect Permissions) + space_removed a space is deleted + space_updated the space details (title, description, status) is updated in the Space Tools > Overview tab + + */ + + const title = this.setEventTitle(event) + const action = this.setActionTitle(event) + const content_title = this.body.space.title + const url = this.body.space.self + + const embed: Embed = { + title: title, + url: url, + description : user + ' ' + action + ' ' + content_title + } + + return embed + } + + private userEvent(event:string): Embed { + /** + * Event Triggered when... + user_created a new user account is created + user_deactivated a user account is disabled + user_followed someone follows a user + user_reactivated a disabled user account is enabled + user_removed a user account is deleted + */ + + const title = this.setEventTitle(event) + const action = this.setActionTitle(event) + const content_title = this.body.userProfile.fullName + + const embed: Embed = { + title: title, + description : title + ' ' + content_title + } + + return embed + } + + private groupEvent(event:string): Embed { + /** + * Event Triggered when... + group_created a new group is created + group_removed a group is deleted + */ + + const title = this.setEventTitle(event) + const action = this.setActionTitle(event) + const content_title = this.body.groupName + + const embed: Embed = { + title: title, + description : title + ' ' + content_title + } + + return embed + } + + //Utility Method for Capitalizing Words + private capitalizeFirstLetter(text:string): string { + return text.charAt(0).toUpperCase() + text.slice(1) + } + //Utility Method for Setting Event Title + private setEventTitle(event:string): string { + const event_words = event.split('_') + if(event_words.length == 3) + { + return this.capitalizeFirstLetter(event.split('_')[2]) + + ' ' + this.capitalizeFirstLetter(event.split('_')[1]) + + ' ' + this.capitalizeFirstLetter(event.split('_')[0]) + } + else{ + return this.capitalizeFirstLetter(event.split('_')[1]) + + ' ' + this.capitalizeFirstLetter(event.split('_')[0]) + } + } + //Utility Method for Setting Event Title + private setActionTitle(event:string): string { + const event_words = event.split('_') + if(event_words.length == 3) + { + return event.split('_')[2] + + ' ' + (event.split('_')[1]) + + ' ' + (event.split('_')[0]) + } + else{ + return event.split('_')[1] + + ' ' + event.split('_')[0] + } + } +} diff --git a/test/confluence/confluence-spec.ts b/test/confluence/confluence-spec.ts new file mode 100644 index 0000000..0f9ea81 --- /dev/null +++ b/test/confluence/confluence-spec.ts @@ -0,0 +1,41 @@ +import { expect } from 'chai' +import { Confluence } from '../../src/provider/Confluence' +import { Tester } from '../Tester' + +describe('/POST confluence', () => { + it('page_', async () => { + const res = await Tester.test(new Confluence(), 'confluence_page.json', null) + expect(res).to.not.be.null + expect(res!.embeds).to.be.an('array').that.has.length(1) + }) + it('attachment_', async () => { + const res = await Tester.test(new Confluence(), 'confluence_attachment.json', null) + expect(res).to.not.be.null + expect(res!.embeds).to.be.an('array').that.has.length(1) + }) + it('comment_', async () => { + const res = await Tester.test(new Confluence(), 'confluence_comment.json', null) + expect(res).to.not.be.null + expect(res!.embeds).to.be.an('array').that.has.length(1) + }) + it('label_', async () => { + const res = await Tester.test(new Confluence(), 'confluence_label.json', null) + expect(res).to.not.be.null + expect(res!.embeds).to.be.an('array').that.has.length(1) + }) + it('space_', async () => { + const res = await Tester.test(new Confluence(), 'confluence_space.json', null) + expect(res).to.not.be.null + expect(res!.embeds).to.be.an('array').that.has.length(1) + }) + it('blog_', async () => { + const res = await Tester.test(new Confluence(), 'confluence_blog.json', null) + expect(res).to.not.be.null + expect(res!.embeds).to.be.an('array').that.has.length(1) + }) + it('user_', async () => { + const res = await Tester.test(new Confluence(), 'confluence_user.json', null) + expect(res).to.not.be.null + expect(res!.embeds).to.be.an('array').that.has.length(1) + }) +}) \ No newline at end of file diff --git a/test/confluence/confluence_attachment.json b/test/confluence/confluence_attachment.json new file mode 100644 index 0000000..37b0075 --- /dev/null +++ b/test/confluence/confluence_attachment.json @@ -0,0 +1,37 @@ +{ + "attachments": [ + { + "creatorAccountId": "59fdbfc4a392de337954d52b", + "fileName": "PXL_20211203_004750797.MP.jpg", + "modificationDate": 1640921437512, + "fileSize": 5013749, + "lastModifierAccountId": "59fdbfc4a392de337954d52b", + "self": "https://example.atlassian.net/wiki/download/attachments/108265473/PXL_20211203_004750797.MP.jpg?version=1&modificationDate=1640921437512&cacheVersion=1&api=v2", + "comment": "", + "id": 108298474, + "creationDate": 1640921437512, + "version": 1 + } + ], + "accountType": "customer", + "userAccountId": "59fdbfc4a392de337954d52b", + "attachedTo": { + "creatorAccountId": "59fdbfc4a392de337954d52b", + "spaceKey": "EX", + "modificationDate": 1640902381483, + "lastModifierAccountId": "59fdbfc4a392de337954d52b", + "self": "https://example.atlassian.net/wiki/spaces/EX/pages/108265473/WEBHOOKS", + "id": 108265473, + "title": "WEBHOOKS", + "creationDate": 1640897371041, + "contentType": "page", + "version": 3, + "creatorDisplayName": "Zaphod Beeblebrox", + "spaceName": "Example", + "lastModifierDisplayName": "Zaphod Beeblebrox" + }, + "timestamp": 1640921438722, + "eventType": "attachment_created", + "transformedAt": "2021-12-31T03:30:39.312", + "userDisplayName": "Zaphod Beeblebrox" +} diff --git a/test/confluence/confluence_blog.json b/test/confluence/confluence_blog.json new file mode 100644 index 0000000..6085894 --- /dev/null +++ b/test/confluence/confluence_blog.json @@ -0,0 +1,23 @@ +{ + "userAccountId": "59fdbfc4a392de337954d52b", + "accountType": "customer", + "blog": { + "creatorAccountId": "59fdbfc4a392de337954d52b", + "spaceKey": "EX", + "modificationDate": 1640924555481, + "lastModifierAccountId": "59fdbfc4a392de337954d52b", + "self": "https://example.atlassian.net/wiki/spaces/EX/blog/2021/12/31/108396632/Heyyyyyyy+Guyyyyyys+It%27s+blog+post+here", + "id": 108396632, + "title": "Heyyyyyyy Guyyyyyys It's blog post here", + "creationDate": 1640924553463, + "contentType": "blogpost", + "version": 1, + "creatorDisplayName": "Zaphod Beeblebrox", + "spaceName": "Example", + "lastModifierDisplayName": "Zaphod Beeblebrox" + }, + "timestamp": 1640924555490, + "eventType": "blog_created", + "transformedAt": "2021-12-31T04:22:35.959", + "userDisplayName": "Zaphod Beeblebrox" +} diff --git a/test/confluence/confluence_comment.json b/test/confluence/confluence_comment.json new file mode 100644 index 0000000..254e9f1 --- /dev/null +++ b/test/confluence/confluence_comment.json @@ -0,0 +1,38 @@ +{ + "accountType": "customer", + "userAccountId": "59fdbfc4a392de337954d52b", + "comment": { + "creatorAccountId": "59fdbfc4a392de337954d52b", + "spaceKey": "ZC", + "parent": { + "creatorAccountId": "59fdbfc4a392de337954d52b", + "spaceKey": "ZC", + "modificationDate": 1640920585680, + "lastModifierAccountId": "59fdbfc4a392de337954d52b", + "self": "https://example.atlassian.net/wiki/spaces/EX/pages/108265543/example", + "id": 108265543, + "title": "example", + "creationDate": 1640920574721, + "contentType": "page", + "version": 1, + "creatorDisplayName": "Zaphod Beeblebrox", + "spaceName": "Example", + "lastModifierDisplayName": "Zaphod Beeblebrox" + }, + "modificationDate": 1640920711190, + "lastModifierAccountId": "59fdbfc4a392de337954d52b", + "self": "https://example.atlassian.net/wiki/spaces/ZC/pages/108265543/example?focusedCommentId=108298295#comment-108298295", + "id": 108298295, + "creationDate": 1640920711190, + "contentType": "comment", + "version": 1, + "creatorDisplayName": "Zaphod Beeblebrox", + "spaceName": "Example", + "lastModifierDisplayName": "Zaphod Beeblebrox", + "commentBody": "

joseph test

" + }, + "timestamp": 1640920711191, + "eventType": "comment_created", + "transformedAt": "2021-12-31T03:18:31.624", + "userDisplayName": "Zaphod Beeblebrox" +} diff --git a/test/confluence/confluence_label.json b/test/confluence/confluence_label.json new file mode 100644 index 0000000..a5a3598 --- /dev/null +++ b/test/confluence/confluence_label.json @@ -0,0 +1,30 @@ +{ + "userAccountId": "59fdbfc4a392de337954d52b", + "accountType": "customer", + "labeled": { + "creatorAccountId": "59fdbfc4a392de337954d52b", + "spaceKey": "EX", + "modificationDate": 1640902381483, + "lastModifierAccountId": "59fdbfc4a392de337954d52b", + "self": "https://example.atlassian.net/wiki/spaces/EX/pages/108265473/WEBHOOKS", + "id": 108265473, + "title": "WEBHOOKS", + "creationDate": 1640897371041, + "contentType": "page", + "version": 3, + "labels": [["Object"]], + "creatorDisplayName": "Zaphod Beeblebrox", + "spaceName": "Zelda Clone", + "lastModifierDisplayName": "Zaphod Beeblebrox" + }, + "label": { + "ownerAccountId": "", + "name": "debug", + "self": "https://example.atlassian.net/wiki/label/debug", + "title": "debug" + }, + "timestamp": 1640921288841, + "eventType": "label_added", + "transformedAt": "2021-12-31T03:28:09.031", + "userDisplayName": "Zaphod Beeblebrox" +} diff --git a/test/confluence/confluence_page.json b/test/confluence/confluence_page.json new file mode 100644 index 0000000..fb84b7d --- /dev/null +++ b/test/confluence/confluence_page.json @@ -0,0 +1,24 @@ +{ + "userAccountId": "59fdbfc4a392de337954d52b", + "accountType": "customer", + "updateTrigger": "edit_page", + "page": { + "creatorAccountId": "59fdbfc4a392de337954d52b", + "spaceKey": "EX", + "modificationDate": 1640921032197, + "lastModifierAccountId": "59fdbfc4a392de337954d52b", + "self": "https://example.atlassian.net/wiki/spaces/EX/pages/108265543/example_page", + "id": 108265543, + "title": "example_page", + "creationDate": 1640920574721, + "contentType": "page", + "version": 3, + "creatorDisplayName": "Zaphod Beeblebrox", + "spaceName": "Example", + "lastModifierDisplayName": "Zaphod Beeblebrox" + }, + "timestamp": 1640921032214, + "eventType": "page_updated", + "transformedAt": "2021-12-31T03:23:52.702", + "userDisplayName": "Zaphod Beeblebrox" +} diff --git a/test/confluence/confluence_space.json b/test/confluence/confluence_space.json new file mode 100644 index 0000000..596e3c8 --- /dev/null +++ b/test/confluence/confluence_space.json @@ -0,0 +1,22 @@ +{ + "accountType": "customer", + "userAccountId": "59fdbfc4a392de337954d52b", + "space": { + "creatorAccountId": "59fdbfc4a392de337954d52b", + "modificationDate": 1640921127797, + "isPersonalSpace": false, + "lastModifierAccountId": "59fdbfc4a392de337954d52b", + "description": "", + "self": "https://example.atlassian.net/wiki/spaces/TES", + "title": "test-space", + "creationDate": 1640921127797, + "homePage": { "id": 108298438 }, + "key": "TES", + "creatorDisplayName": "Zaphod Beeblebrox", + "lastModifierDisplayName": "Zaphod Beeblebrox" + }, + "timestamp": 1640921127858, + "eventType": "space_created", + "transformedAt": "2021-12-31T03:25:28.635", + "userDisplayName": "Zaphod Beeblebrox" +} diff --git a/test/confluence/confluence_user.json b/test/confluence/confluence_user.json new file mode 100644 index 0000000..76ed2c3 --- /dev/null +++ b/test/confluence/confluence_user.json @@ -0,0 +1,11 @@ +{ + "userProfile": { + "userAccountId": "61ce993f125b120071a733f1", + "fullName": "Debug Test (Unlicensed)", + "email": "", + "userDisplayName": "Debug Test (Unlicensed)" + }, + "timestamp": 1640930304591, + "eventType": "user_removed", + "transformedAt": "2021-12-31T05:58:25.138" +} diff --git a/test/confluence/confluence_webhook_events.txt b/test/confluence/confluence_webhook_events.txt new file mode 100644 index 0000000..9c4412c --- /dev/null +++ b/test/confluence/confluence_webhook_events.txt @@ -0,0 +1,54 @@ +Event Triggered when... +attachment_created a file is attached to a page or blog post +attachment_removed a file is deleted (sent to the trash) from the attachments page(not triggered when a version is deleted from the file history) +attachment_restored a file is restored from the trash +attachment_trashed a file is purged from the trash +attachment_updated a new file version of is uploaded directly or by editing the file + +blog_created a blog post is published +blog_removed a blog post is deleted (sent to the trash) +blog_restored a blog post is restored from the trash +blog_trashed a blog post is purged from the trash +blog_updated a blog post is edited + +blueprint_page_created a page is created from a blueprint (such as meeting notes, decision, or how-to) + +comment_created a page comment, inline comment or file comment is made +comment_removed a page comment, inline comment, or file comment is deleted +comment_updated a page comment, inline comment, or file comment is edited + +content_created a page, blog post, attachment (file), comment (page, inline, or file), or other file (such as a space logo) is created or uploaded. +content_restored a page, blog post, or attachment (file) is restored from the trash +content_trashed a page, blog post, or attachment (file) is purged from the trash +content_updated a page, blog post, attachment (file), or comment (page, inline, and file) is edited. +content_permissions_updated a view or edit restriction is applied or removed from a page or blog post + +group_created a new group is created +group_removed a group is deleted + +label_added an existing label is applied to a page, blog post, or space +label_created a label is added for the first time (did not already exist) +label_deleted a label is removed from the last page, blog post, or space, and so ceases to exist +label_removed a label is removed from a page, blog post, or space +page_children_reordered the default ordering of pages is changed to alphabetical in the Space Tools > Reorder pages tab(is not triggered when you drag a page, or move a page, to change the page order) +page_created a page is published for the first time, including pages created from a template or blueprint +page_moved a page is moved to a different position in the page tree, to a different parent page, or to another space +page_removed a page is deleted (sent to the trash) +page_restored a page is restored from the trash +page_trashed a page is purged from the trash +page_updated a page is edited (triggered at the point the unpublished changes are published) + +space_created a new space is created +space_logo_updated a new file is uploaded for use as the logo of a space +space_permissions_updated +space permissions are changed in the Space Tools > Permissions tab(is not triggered when you edit space permissions using Inspect Permissions) +space_removed a space is deleted +space_updated the space details (title, description, status) is updated in the Space Tools > Overview tab + +theme_enabled a specific theme or default theme is applied to to a space or the whole site + +user_created a new user account is created +user_deactivated a user account is disabled +user_followed someone follows a user +user_reactivated a disabled user account is enabled +user_removed a user account is deleted \ No newline at end of file From 47b6ef211287cbe1a4f2043224433ad4f1ef7bd1 Mon Sep 17 00:00:00 2001 From: Joseph Schlitz Date: Tue, 4 Jan 2022 10:10:14 -0500 Subject: [PATCH 2/2] Ran npx eslint on changes in PR --- src/provider/Confluence.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/provider/Confluence.ts b/src/provider/Confluence.ts index 3a7e506..f3a08a0 100644 --- a/src/provider/Confluence.ts +++ b/src/provider/Confluence.ts @@ -263,7 +263,6 @@ export class Confluence extends DirectParseProvider { */ const title = this.setEventTitle(event) - const action = this.setActionTitle(event) const content_title = this.body.userProfile.fullName const embed: Embed = { @@ -282,7 +281,6 @@ export class Confluence extends DirectParseProvider { */ const title = this.setEventTitle(event) - const action = this.setActionTitle(event) const content_title = this.body.groupName const embed: Embed = {