Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[R] Slack actions #8

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions packages/pieces/slack/src/lib/actions/create-channel.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { createAction, Property } from '@activepieces/pieces-framework';
import {
httpClient,
HttpMethod,
HttpRequest,
AuthenticationType,
} from '@activepieces/pieces-common';
import { slackAuth } from '../../';

export const slackCreateChannel = createAction({
auth: slackAuth,
name: 'create_channel',
displayName: 'Create Channel',
description: 'Creates a new channel',
props: {
channel_name: Property.ShortText({
displayName: 'Channel Name',
description: 'Name of the channel',
required: true,
}),
is_private: Property.Checkbox({
displayName: 'Private',
description: 'Is the channel private',
required: true,
}),
},
async run(context) {
const token = context.auth.access_token;
const { channel_name, is_private } = context.propsValue;

const body: CreateChannelRequestBody = {
name: channel_name,
is_private,
};

const request: HttpRequest<CreateChannelRequestBody> = {
method: HttpMethod.POST,
url: 'https://slack.com/api/conversations.create',
body,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token,
},
};

const response = await httpClient.sendRequest(request);
return response.body;
},
});

type CreateChannelRequestBody = {
name: string;
is_private: boolean;
};
40 changes: 40 additions & 0 deletions packages/pieces/slack/src/lib/actions/find-user.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { createAction, Property } from '@activepieces/pieces-framework';
import {
httpClient,
HttpMethod,
HttpRequest,
AuthenticationType,
} from '@activepieces/pieces-common';
import { slackAuth } from '../../';

export const slackFindUserByEmail = createAction({
auth: slackAuth,
name: 'find_user_by_email',
displayName: 'Find user by email',
description: 'Finds a user to a channel',
props: {
email: Property.ShortText({
displayName: 'Email',
description: 'Email of the user to invite',
required: true,
}),
},
async run(context) {
const token = context.auth.access_token;
const { email } = context.propsValue;

const request: HttpRequest = {
method: HttpMethod.POST,
url: 'https://slack.com/api/users.lookupByEmail',
body: { email },
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token,
},
};

const response = await httpClient.sendRequest(request);

return response.body;
},
});
47 changes: 47 additions & 0 deletions packages/pieces/slack/src/lib/actions/invite-user-to-channel.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { createAction, Property } from '@activepieces/pieces-framework';
import {
httpClient,
HttpMethod,
HttpRequest,
AuthenticationType,
} from '@activepieces/pieces-common';
import { slackAuth } from '../../';
import { slackChannel } from '../common/props';

export const slackInviteUserToChannel = createAction({
auth: slackAuth,
name: 'invite_to_channel',
displayName: 'Invite user',
description: 'Invites a user to a channel',
props: {
user: Property.ShortText({
displayName: 'User ID',
description: 'ID of the user to invite',
required: true,
}),
channel: slackChannel,
},
async run(context) {
const token = context.auth.access_token;
const { user, channel } = context.propsValue;

const body: any = {
user,
channel,
};

const request: HttpRequest<any> = {
method: HttpMethod.POST,
url: 'https://slack.com/api/conversations.invite',
body,
authentication: {
type: AuthenticationType.BEARER_TOKEN,
token,
},
};

const response = await httpClient.sendRequest(request);

return response.body;
},
});
47 changes: 27 additions & 20 deletions packages/pieces/slack/src/lib/common/utils.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
import { AuthenticationType, httpClient, HttpMethod, HttpRequest } from "@activepieces/pieces-common";

export const slackSendMessage = async ({ text, conversationId, username, profilePicture, blocks, token }: SlackSendMessageParams) => {
export const slackSendMessage = async ({
text,
conversationId,
username,
profilePicture,
blocks,
token,
}: SlackSendMessageParams) => {
const body: any = {
text,
channel: conversationId,
}
};

if (username) body['username'] = username;
if (profilePicture) body['icon_url'] = profilePicture;
if (blocks) body['blocks'] = blocks;

if (username) body['username'] = username
if (profilePicture) body['icon_url'] = profilePicture
if (blocks) body['blocks'] = blocks

const request: HttpRequest<SlackSendMessageRequestBody> = {
method: HttpMethod.POST,
url: 'https://slack.com/api/chat.postMessage',
Expand All @@ -18,27 +25,27 @@ export const slackSendMessage = async ({ text, conversationId, username, profile
type: AuthenticationType.BEARER_TOKEN,
token,
},
}
};

const response = await httpClient.sendRequest(request)
const response = await httpClient.sendRequest(request);

return {
success: true,
request_body: request.body,
response_body: response.body,
}
}
};
};

type SlackSendMessageRequestBody = {
text: string
channel: string
}
text: string;
channel: string;
};

type SlackSendMessageParams = {
token: string
conversationId: string
username?: string
profilePicture?: string
blocks?: unknown[]
text: string
}
token: string;
conversationId: string;
username?: string;
profilePicture?: string;
blocks?: unknown[];
text: string;
};
56 changes: 56 additions & 0 deletions packages/pieces/slack/src/lib/triggers/new-channel.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { TriggerStrategy, createTrigger } from '@activepieces/pieces-framework';
import { slackAuth } from '../../';

const sampleData = {
type: 'channel_created',
channel: {
id: 'C02ELGNBH',
name: 'fun',
is_channel: true,
created: 1626787984,
is_archived: false,
is_general: false,
unlinked: 0,
creator: 'U02ELGNC6',
name_normalized: 'fun',
is_shared: false,
is_org_shared: false,
is_member: true,
is_private: false,
is_mpim: false,
last_read: '1626787984.000100',
latest: null,
unread_count: 0,
unread_count_display: 0,
members: ['U02ELGNC6'],
topic: { value: '', creator: '', last_set: 0 },
purpose: { value: '', creator: '', last_set: 0 },
previous_names: [],
priority: 0,
},
};

export const newChannel = createTrigger({
auth: slackAuth,
name: 'new_channel',
displayName: 'New Channel',
description: 'Triggers when a new channel is created',
props: {},
type: TriggerStrategy.APP_WEBHOOK,
sampleData: sampleData,
onEnable: async (context) => {
await context.app.createListeners({
events: ['channel_created'],
identifierValue: context.auth.data['team_id'],
});
},
onDisable: async () => {
// Ignored
},
test: async () => {
return [sampleData];
},
run: async (context) => {
return [context.payload.body.event];
},
});
87 changes: 87 additions & 0 deletions packages/pieces/slack/src/lib/triggers/new-user.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { TriggerStrategy, createTrigger } from '@activepieces/pieces-framework';
import { slackAuth } from '../../';

const sampleData = {
user: {
id: 'U1234567',
team_id: 'T1234567',
name: 'some-user',
deleted: false,
color: '4bbe2e',
real_name: 'Some User',
tz: 'America/Los_Angeles',
tz_label: 'Pacific Daylight Time',
tz_offset: -25200,
profile: {
title: '',
phone: '',
skype: '',
real_name: 'Some User',
real_name_normalized: 'Some User',
display_name: '',
display_name_normalized: '',
fields: {},
status_text: 'riding a train',
status_emoji: ':mountain_railway:',
status_emoji_display_info: [],
status_expiration: 0,
avatar_hash: 'g12345678910',
first_name: 'Some',
last_name: 'User',
image_24:
'https://secure.gravatar.com/avatar/cb0c2b2ca5e8de16be31a55a734d0f31.jpg?s=24&d=https%3A%2F%2Fdev.slack.com%2Fdev-cdn%2Fv1648136338%2Fimg%2Favatars%2Fuser_shapes%2Fava_0001-24.png',
image_32:
'https://secure.gravatar.com/avatar/cb0c2b2ca5e8de16be31a55a734d0f31.jpg?s=32&d=https%3A%2F%2Fdev.slack.com%2Fdev-cdn%2Fv1648136338%2Fimg%2Favatars%2Fuser_shapes%2Fava_0001-32.png',
image_48:
'https://secure.gravatar.com/avatar/cb0c2b2ca5e8de16be31a55a734d0f31.jpg?s=48&d=https%3A%2F%2Fdev.slack.com%2Fdev-cdn%2Fv1648136338%2Fimg%2Favatars%2Fuser_shapes%2Fava_0001-48.png',
image_72:
'https://secure.gravatar.com/avatar/cb0c2b2ca5e8de16be31a55a734d0f31.jpg?s=72&d=https%3A%2F%2Fdev.slack.com%2Fdev-cdn%2Fv1648136338%2Fimg%2Favatars%2Fuser_shapes%2Fava_0001-72.png',
image_192:
'https://secure.gravatar.com/avatar/cb0c2b2ca5e8de16be31a55a734d0f31.jpg?s=192&d=https%3A%2F%2Fdev.slack.com%2Fdev-cdn%2Fv1648136338%2Fimg%2Favatars%2Fuser_shapes%2Fava_0001-192.png',
image_512:
'https://secure.gravatar.com/avatar/cb0c2b2ca5e8de16be31a55a734d0f31.jpg?s=512&d=https%3A%2F%2Fdev.slack.com%2Fdev-cdn%2Fv1648136338%2Fimg%2Favatars%2Fuser_shapes%2Fava_0001-512.png',
status_text_canonical: '',
team: 'T1234567',
},
is_admin: false,
is_owner: false,
is_primary_owner: false,
is_restricted: false,
is_ultra_restricted: false,
is_bot: false,
is_app_user: false,
updated: 1648596421,
is_email_confirmed: true,
who_can_share_contact_card: 'EVERYONE',
locale: 'en-US',
},
cache_ts: 1648596421,
type: 'user_change',
event_ts: '1648596712.000001',
};

export const newUser = createTrigger({
auth: slackAuth,
name: 'new_user',
displayName: 'Updated User',
description:
'Triggers when a user in your org changes (added/updated/deleted)',
props: {},
type: TriggerStrategy.APP_WEBHOOK,
sampleData: sampleData,
onEnable: async (context) => {
await context.app.createListeners({
events: ['user_change'],
identifierValue: context.auth.data['team_id'],
});
},
onDisable: async () => {
// Ignored
},
test: async () => {
return [sampleData];
},
run: async (context) => {
return [context.payload.body.event];
},
});