Merge pull request #493 from automatisch/issue-492

feat: add find messages action in Slack
This commit is contained in:
Ömer Faruk Aydın
2022-09-11 15:25:11 +03:00
committed by GitHub
8 changed files with 154 additions and 1 deletions

View File

@@ -1,12 +1,15 @@
import SendMessageToChannel from './actions/send-message-to-channel'; import SendMessageToChannel from './actions/send-message-to-channel';
import FindMessage from './actions/find-message';
import SlackClient from './client'; import SlackClient from './client';
export default class Actions { export default class Actions {
client: SlackClient; client: SlackClient;
sendMessageToChannel: SendMessageToChannel; sendMessageToChannel: SendMessageToChannel;
findMessage: FindMessage;
constructor(client: SlackClient) { constructor(client: SlackClient) {
this.client = client; this.client = client;
this.sendMessageToChannel = new SendMessageToChannel(client); this.sendMessageToChannel = new SendMessageToChannel(client);
this.findMessage = new FindMessage(client);
} }
} }

View File

@@ -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;
}
}

View File

@@ -0,0 +1,44 @@
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;
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}`);
}
const messages = data.messages.matches;
const message = messages?.[0];
return message;
}
}

View File

@@ -2,6 +2,7 @@ import { IFlow, IStep, IConnection } from '@automatisch/types';
import HttpClient from '../../../helpers/http-client'; import HttpClient from '../../../helpers/http-client';
import VerifyAccessToken from './endpoints/verify-access-token'; import VerifyAccessToken from './endpoints/verify-access-token';
import PostMessageToChannel from './endpoints/post-message-to-channel'; import PostMessageToChannel from './endpoints/post-message-to-channel';
import FindMessages from './endpoints/find-messages';
export default class SlackClient { export default class SlackClient {
flow: IFlow; flow: IFlow;
@@ -11,6 +12,7 @@ export default class SlackClient {
verifyAccessToken: VerifyAccessToken; verifyAccessToken: VerifyAccessToken;
postMessageToChannel: PostMessageToChannel; postMessageToChannel: PostMessageToChannel;
findMessages: FindMessages;
static baseUrl = 'https://slack.com/api'; static baseUrl = 'https://slack.com/api';
@@ -22,5 +24,6 @@ export default class SlackClient {
this.httpClient = new HttpClient({ baseURL: SlackClient.baseUrl }); this.httpClient = new HttpClient({ baseURL: SlackClient.baseUrl });
this.verifyAccessToken = new VerifyAccessToken(this); this.verifyAccessToken = new VerifyAccessToken(this);
this.postMessageToChannel = new PostMessageToChannel(this); this.postMessageToChannel = new PostMessageToChannel(this);
this.findMessages = new FindMessages(this);
} }
} }

View File

@@ -204,6 +204,73 @@
"name": "Test action" "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"
}
]
} }
] ]
} }

View File

@@ -73,6 +73,7 @@ type ActionSubstepArgument {
description: String description: String
required: Boolean required: Boolean
variables: Boolean variables: Boolean
options: [ActionSubstepArgumentOption]
source: ActionSubstepArgumentSource source: ActionSubstepArgumentSource
dependsOn: [String] dependsOn: [String]
} }
@@ -83,6 +84,11 @@ type ActionSubstepArgumentSource {
arguments: [ActionSubstepArgumentSourceArgument] arguments: [ActionSubstepArgumentSourceArgument]
} }
type ActionSubstepArgumentOption {
label: String
value: JSONObject
}
type ActionSubstepArgumentSourceArgument { type ActionSubstepArgumentSourceArgument {
name: String name: String
value: String value: String

View File

@@ -73,7 +73,7 @@ function TestSubstep(props: TestSubstepProps): React.ReactElement {
{error?.graphQLErrors.map((error) => (<>{error.message}<br /></>))} {error?.graphQLErrors.map((error) => (<>{error.message}<br /></>))}
</Alert>} </Alert>}
{called && !response && ( {called && !loading && !error && !response && (
<Alert severity="warning" sx={{ mb: 1, width: '100%' }}> <Alert severity="warning" sx={{ mb: 1, width: '100%' }}>
<AlertTitle sx={{ fontWeight: 700 }}>{formatMessage('flowEditor.noTestDataTitle')}</AlertTitle> <AlertTitle sx={{ fontWeight: 700 }}>{formatMessage('flowEditor.noTestDataTitle')}</AlertTitle>

View File

@@ -95,6 +95,10 @@ export const GET_APPS = gql`
description description
variables variables
dependsOn dependsOn
options {
label
value
}
source { source {
type type
name name