From f1dab3e29530ee596d68db474024ddbae5fa055a Mon Sep 17 00:00:00 2001 From: Jon Date: Fri, 17 Apr 2026 20:13:53 +0100 Subject: [PATCH] feat(Slack Node): Add app_home_opened as a dedicated trigger event (#28626) Co-authored-by: Claude Sonnet 4.6 Co-authored-by: Roman Davydchuk --- .../nodes/Slack/SlackTrigger.node.ts | 8 +++- .../nodes/Slack/test/SlackTrigger.test.ts | 37 +++++++++++++++++++ .../utils/sendAndWait/test/util.test.ts | 4 +- 3 files changed, 46 insertions(+), 3 deletions(-) diff --git a/packages/nodes-base/nodes/Slack/SlackTrigger.node.ts b/packages/nodes-base/nodes/Slack/SlackTrigger.node.ts index eb54a2fc87e..3bc68c5a3f9 100644 --- a/packages/nodes-base/nodes/Slack/SlackTrigger.node.ts +++ b/packages/nodes-base/nodes/Slack/SlackTrigger.node.ts @@ -68,6 +68,11 @@ export class SlackTrigger implements INodeType { value: 'any_event', description: 'Triggers on any event', }, + { + name: 'App Home Opened', + value: 'app_home_opened', + description: "When a user opens your app's Home tab", + }, { name: 'Bot / App Mention', value: 'app_mention', @@ -352,7 +357,8 @@ export class SlackTrigger implements INodeType { return {}; } - if (eventType !== 'team_join') { + const eventsWithoutChannel = ['team_join', 'app_home_opened']; + if (!eventsWithoutChannel.includes(eventType)) { eventChannel = req.body.event.channel ?? req.body.event.item?.channel ?? req.body.event.channel_id; diff --git a/packages/nodes-base/nodes/Slack/test/SlackTrigger.test.ts b/packages/nodes-base/nodes/Slack/test/SlackTrigger.test.ts index 38fe6fe4e1e..8e1d23e4ae3 100644 --- a/packages/nodes-base/nodes/Slack/test/SlackTrigger.test.ts +++ b/packages/nodes-base/nodes/Slack/test/SlackTrigger.test.ts @@ -506,6 +506,43 @@ describe('SlackTrigger Node', () => { expect(out.user_resolved).toBe(mockRequest.body.event.user.name); }); + it('should trigger on app_home_opened event without channel validation', async () => { + mockWebhookFunctions.getNodeParameter.mockImplementation( + (paramName: string, defaultValue?: any) => { + switch (paramName) { + case 'trigger': + return ['app_home_opened']; + case 'watchWorkspace': + return false; + case 'options': + return {}; + default: + return defaultValue; + } + }, + ); + + const mockRequest = { + body: { + type: 'event_callback', + event: { + type: 'app_home_opened', + user: 'U061F7AUR', + channel: 'D0LAN2Q65', + tab: 'home', + event_ts: '1515449522000016', + }, + }, + }; + + mockWebhookFunctions.getRequestObject.mockReturnValue(mockRequest as any); + + const result = await slackTrigger.webhook!.call(mockWebhookFunctions); + + expect(result.workflowData).toBeDefined(); + expect(result.workflowData![0][0].json).toEqual(mockRequest.body.event); + }); + it('should handle url_verification challenge', async () => { const mockRequest = { body: { diff --git a/packages/nodes-base/utils/sendAndWait/test/util.test.ts b/packages/nodes-base/utils/sendAndWait/test/util.test.ts index 8ba55ebd158..5c060d78ae8 100644 --- a/packages/nodes-base/utils/sendAndWait/test/util.test.ts +++ b/packages/nodes-base/utils/sendAndWait/test/util.test.ts @@ -279,7 +279,7 @@ describe('Send and Wait utils tests', () => { expect(mockSetHeader).toHaveBeenCalledWith( 'Content-Security-Policy', - 'sandbox allow-downloads allow-forms allow-modals allow-orientation-lock allow-pointer-lock allow-popups allow-presentation allow-scripts allow-top-navigation-by-user-activation allow-top-navigation-to-custom-protocols', + 'sandbox allow-downloads allow-forms allow-modals allow-orientation-lock allow-pointer-lock allow-popups allow-popups-to-escape-sandbox allow-presentation allow-scripts allow-top-navigation-by-user-activation allow-top-navigation-to-custom-protocols', ); expect(mockRender).toHaveBeenCalledWith('form-trigger', { @@ -365,7 +365,7 @@ describe('Send and Wait utils tests', () => { expect(mockSetHeader).toHaveBeenCalledWith( 'Content-Security-Policy', - 'sandbox allow-downloads allow-forms allow-modals allow-orientation-lock allow-pointer-lock allow-popups allow-presentation allow-scripts allow-top-navigation-by-user-activation allow-top-navigation-to-custom-protocols', + 'sandbox allow-downloads allow-forms allow-modals allow-orientation-lock allow-pointer-lock allow-popups allow-popups-to-escape-sandbox allow-presentation allow-scripts allow-top-navigation-by-user-activation allow-top-navigation-to-custom-protocols', ); expect(mockRender).toHaveBeenCalledWith('form-trigger', {