From 3593727d29dcf8ed87b9bdd8218b96f639248267 Mon Sep 17 00:00:00 2001 From: Ali BARIN Date: Fri, 9 Sep 2022 23:53:17 +0200 Subject: [PATCH 1/2] feat: add find message action in Slack --- packages/backend/src/apps/slack/actions.ts | 3 + .../src/apps/slack/actions/find-message.ts | 26 +++++++ .../slack/client/endpoints/find-messages.ts | 50 ++++++++++++++ .../backend/src/apps/slack/client/index.ts | 3 + packages/backend/src/apps/slack/info.json | 67 +++++++++++++++++++ packages/backend/src/graphql/schema.graphql | 6 ++ .../web/src/components/TestSubstep/index.tsx | 2 +- packages/web/src/graphql/queries/get-apps.ts | 4 ++ 8 files changed, 160 insertions(+), 1 deletion(-) create mode 100644 packages/backend/src/apps/slack/actions/find-message.ts create mode 100644 packages/backend/src/apps/slack/client/endpoints/find-messages.ts diff --git a/packages/backend/src/apps/slack/actions.ts b/packages/backend/src/apps/slack/actions.ts index 7e44ebc4..e4063b76 100644 --- a/packages/backend/src/apps/slack/actions.ts +++ b/packages/backend/src/apps/slack/actions.ts @@ -1,12 +1,15 @@ import SendMessageToChannel from './actions/send-message-to-channel'; +import FindMessage from './actions/find-message'; import SlackClient from './client'; export default class Actions { client: SlackClient; sendMessageToChannel: SendMessageToChannel; + findMessage: FindMessage; constructor(client: SlackClient) { this.client = client; this.sendMessageToChannel = new SendMessageToChannel(client); + this.findMessage = new FindMessage(client); } } diff --git a/packages/backend/src/apps/slack/actions/find-message.ts b/packages/backend/src/apps/slack/actions/find-message.ts new file mode 100644 index 00000000..4185d7b5 --- /dev/null +++ b/packages/backend/src/apps/slack/actions/find-message.ts @@ -0,0 +1,26 @@ +import SlackClient from '../client'; + +export default class FindMessage { + client: SlackClient; + + constructor(client: SlackClient) { + this.client = client; + } + + async run() { + const parameters = this.client.step.parameters; + const query = parameters.query as string; + const sortBy = parameters.sortBy as string; + const sortDirection = parameters.sortDirection as string; + const count = 1; + + const messages = await this.client.findMessages.run( + query, + sortBy, + sortDirection, + count, + ); + + return messages; + } +} diff --git a/packages/backend/src/apps/slack/client/endpoints/find-messages.ts b/packages/backend/src/apps/slack/client/endpoints/find-messages.ts new file mode 100644 index 00000000..c343a833 --- /dev/null +++ b/packages/backend/src/apps/slack/client/endpoints/find-messages.ts @@ -0,0 +1,50 @@ +import SlackClient from '../index'; + +export default class FindMessages { + client: SlackClient; + + constructor(client: SlackClient) { + this.client = client; + } + + async run( + query: string, + sortBy: string, + sortDirection: string, + count = 1, + ) { + const headers = { + Authorization: `Bearer ${this.client.connection.formattedData.accessToken}`, + }; + + const params = { + query, + sort: sortBy, + sort_dir: sortDirection, + count, + }; + + const response = await this.client.httpClient.get( + '/search.messages', + { headers, params } + ); + + const data = response.data; + const messages = data.messages.matches; + const message = messages?.[0]; + + if (!data.ok) { + if (data.error === 'missing_scope') { + throw new Error( + `Error occured while finding messages; ${data.error}: ${data.needed}` + ) + } + + throw new Error( + `Error occured while finding messages; ${data.error}` + ); + } + + return message; + } +} diff --git a/packages/backend/src/apps/slack/client/index.ts b/packages/backend/src/apps/slack/client/index.ts index b3e9e17d..ba47be53 100644 --- a/packages/backend/src/apps/slack/client/index.ts +++ b/packages/backend/src/apps/slack/client/index.ts @@ -2,6 +2,7 @@ import { IFlow, IStep, IConnection } from '@automatisch/types'; import HttpClient from '../../../helpers/http-client'; import VerifyAccessToken from './endpoints/verify-access-token'; import PostMessageToChannel from './endpoints/post-message-to-channel'; +import FindMessages from './endpoints/find-messages'; export default class SlackClient { flow: IFlow; @@ -11,6 +12,7 @@ export default class SlackClient { verifyAccessToken: VerifyAccessToken; postMessageToChannel: PostMessageToChannel; + findMessages: FindMessages; static baseUrl = 'https://slack.com/api'; @@ -22,5 +24,6 @@ export default class SlackClient { this.httpClient = new HttpClient({ baseURL: SlackClient.baseUrl }); this.verifyAccessToken = new VerifyAccessToken(this); this.postMessageToChannel = new PostMessageToChannel(this); + this.findMessages = new FindMessages(this); } } diff --git a/packages/backend/src/apps/slack/info.json b/packages/backend/src/apps/slack/info.json index 4e5cd4f8..d2ccc565 100644 --- a/packages/backend/src/apps/slack/info.json +++ b/packages/backend/src/apps/slack/info.json @@ -204,6 +204,73 @@ "name": "Test action" } ] + }, + { + "name": "Find message", + "key": "findMessage", + "description": "Find a Slack message using the Slack Search feature.", + "substeps": [ + { + "key": "chooseConnection", + "name": "Choose connection" + }, + { + "key": "setupAction", + "name": "Set up action", + "arguments": [ + { + "label": "Search Query", + "key": "query", + "type": "string", + "required": true, + "description": "Search query to use for finding matching messages. See the Slack Search Documentation for more information on constructing a query.", + "variables": true + }, + { + "label": "Sort by", + "key": "sortBy", + "type": "dropdown", + "description": "Sort messages by their match strength or by their date. Default is score.", + "required": true, + "value": "score", + "variables": false, + "options": [ + { + "label": "Match strength", + "value": "score" + }, + { + "label": "Message date time", + "value": "timestamp" + } + ] + }, + { + "label": "Sort direction", + "key": "sortDirection", + "type": "dropdown", + "description": "Sort matching messages in ascending or descending order. Default is descending.", + "required": true, + "value": "desc", + "variables": false, + "options": [ + { + "label": "Descending (newest or best match first)", + "value": "desc" + }, + { + "label": "Ascending (oldest or worst match first)", + "value": "asc" + } + ] + } + ] + }, + { + "key": "testStep", + "name": "Test action" + } + ] } ] } diff --git a/packages/backend/src/graphql/schema.graphql b/packages/backend/src/graphql/schema.graphql index 4ec57ecc..d26c9bf9 100644 --- a/packages/backend/src/graphql/schema.graphql +++ b/packages/backend/src/graphql/schema.graphql @@ -73,6 +73,7 @@ type ActionSubstepArgument { description: String required: Boolean variables: Boolean + options: [ActionSubstepArgumentOption] source: ActionSubstepArgumentSource dependsOn: [String] } @@ -83,6 +84,11 @@ type ActionSubstepArgumentSource { arguments: [ActionSubstepArgumentSourceArgument] } +type ActionSubstepArgumentOption { + label: String + value: JSONObject +} + type ActionSubstepArgumentSourceArgument { name: String value: String diff --git a/packages/web/src/components/TestSubstep/index.tsx b/packages/web/src/components/TestSubstep/index.tsx index de921f6e..6eb22e7b 100644 --- a/packages/web/src/components/TestSubstep/index.tsx +++ b/packages/web/src/components/TestSubstep/index.tsx @@ -73,7 +73,7 @@ function TestSubstep(props: TestSubstepProps): React.ReactElement { {error?.graphQLErrors.map((error) => (<>{error.message}
))} } - {called && !response && ( + {called && !loading && !error && !response && ( {formatMessage('flowEditor.noTestDataTitle')} diff --git a/packages/web/src/graphql/queries/get-apps.ts b/packages/web/src/graphql/queries/get-apps.ts index a09cdf26..82ff70ec 100644 --- a/packages/web/src/graphql/queries/get-apps.ts +++ b/packages/web/src/graphql/queries/get-apps.ts @@ -95,6 +95,10 @@ export const GET_APPS = gql` description variables dependsOn + options { + label + value + } source { type name From d812bb431f130bd29b03e1bb1edce5df7715125d Mon Sep 17 00:00:00 2001 From: Faruk AYDIN Date: Sun, 11 Sep 2022 15:21:25 +0300 Subject: [PATCH 2/2] fix: Throw error before getting slack messages for find messages action --- .../slack/client/endpoints/find-messages.ts | 26 +++++++------------ 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/packages/backend/src/apps/slack/client/endpoints/find-messages.ts b/packages/backend/src/apps/slack/client/endpoints/find-messages.ts index c343a833..50d99819 100644 --- a/packages/backend/src/apps/slack/client/endpoints/find-messages.ts +++ b/packages/backend/src/apps/slack/client/endpoints/find-messages.ts @@ -7,12 +7,7 @@ export default class FindMessages { this.client = client; } - async run( - query: string, - sortBy: string, - sortDirection: string, - count = 1, - ) { + async run(query: string, sortBy: string, sortDirection: string, count = 1) { const headers = { Authorization: `Bearer ${this.client.connection.formattedData.accessToken}`, }; @@ -24,27 +19,26 @@ export default class FindMessages { count, }; - const response = await this.client.httpClient.get( - '/search.messages', - { headers, params } - ); + const response = await this.client.httpClient.get('/search.messages', { + headers, + params, + }); const data = response.data; - const messages = data.messages.matches; - const message = messages?.[0]; if (!data.ok) { if (data.error === 'missing_scope') { throw new Error( `Error occured while finding messages; ${data.error}: ${data.needed}` - ) + ); } - throw new Error( - `Error occured while finding messages; ${data.error}` - ); + throw new Error(`Error occured while finding messages; ${data.error}`); } + const messages = data.messages.matches; + const message = messages?.[0]; + return message; } }