diff --git a/components/slack/actions/add-emoji-reaction/add-emoji-reaction.mjs b/components/slack/actions/add-emoji-reaction/add-emoji-reaction.mjs index 027e4db91d2f1..9e40b595b50b0 100644 --- a/components/slack/actions/add-emoji-reaction/add-emoji-reaction.mjs +++ b/components/slack/actions/add-emoji-reaction/add-emoji-reaction.mjs @@ -4,7 +4,7 @@ export default { key: "slack-add-emoji-reaction", name: "Add Emoji Reaction", description: "Add an emoji reaction to a message. [See the documentation](https://api.slack.com/methods/reactions.add)", - version: "0.0.14", + version: "0.0.15", type: "action", props: { slack, @@ -32,7 +32,7 @@ export default { }, }, async run({ $ }) { - const response = await this.slack.sdk().reactions.add({ + const response = await this.slack.addReactions({ channel: this.conversation, timestamp: this.timestamp, name: this.icon_emoji, diff --git a/components/slack/actions/approve-workflow/approve-workflow.mjs b/components/slack/actions/approve-workflow/approve-workflow.mjs index 4c60c63a900d6..7de3fafa926eb 100644 --- a/components/slack/actions/approve-workflow/approve-workflow.mjs +++ b/components/slack/actions/approve-workflow/approve-workflow.mjs @@ -5,7 +5,7 @@ export default { key: "slack-approve-workflow", name: "Approve Workflow", description: "Suspend the workflow until approved by a Slack message. [See the documentation](https://pipedream.com/docs/code/nodejs/rerun#flowsuspend)", - version: "0.0.3", + version: "0.0.4", type: "action", props: { slack, @@ -44,7 +44,7 @@ export default { resume_url, cancel_url, } = $.flow.suspend(); - const response = await this.slack.sdk().chat.postMessage({ + const response = await this.slack.postChatMessage({ text: "Click here to approve or cancel workflow", blocks: [ { diff --git a/components/slack/actions/archive-channel/archive-channel.mjs b/components/slack/actions/archive-channel/archive-channel.mjs index 9586782dd2a78..81178d8bf9d8a 100644 --- a/components/slack/actions/archive-channel/archive-channel.mjs +++ b/components/slack/actions/archive-channel/archive-channel.mjs @@ -5,7 +5,7 @@ export default { key: "slack-archive-channel", name: "Archive Channel", description: "Archive a channel. [See the documentation](https://api.slack.com/methods/conversations.archive)", - version: "0.0.22", + version: "0.0.23", type: "action", props: { slack, @@ -24,7 +24,7 @@ export default { }, }, async run({ $ }) { - const response = await this.slack.sdk().conversations.archive({ + const response = await this.slack.archiveConversations({ channel: this.conversation, }); $.export("$summary", "Successfully archived channel."); diff --git a/components/slack/actions/common/send-message.mjs b/components/slack/actions/common/send-message.mjs index e40b2d4545d21..ff923367dbdbb 100644 --- a/components/slack/actions/common/send-message.mjs +++ b/components/slack/actions/common/send-message.mjs @@ -235,16 +235,18 @@ export default { if (this.post_at) { obj.post_at = Math.floor(new Date(this.post_at).getTime() / 1000); - return await this.slack.sdk().chat.scheduleMessage(obj); + return await this.slack.scheduleMessage(obj); } - const resp = await this.slack.sdk().chat.postMessage(obj); + const resp = await this.slack.postChatMessage(obj); const { channel } = await this.slack.conversationsInfo({ channel: resp.channel, }); let channelName = `#${channel?.name}`; if (channel.is_im) { - const usernames = await this.slack.userNames(); - channelName = `@${usernames[channel.user]}`; + const { profile } = await this.slack.getUserProfile({ + user: channel.user, + }); + channelName = `@${profile.real_name}`; } else if (channel.is_mpim) { channelName = `@${channel.purpose.value}`; } diff --git a/components/slack/actions/create-channel/create-channel.mjs b/components/slack/actions/create-channel/create-channel.mjs index 13aedcc6c0966..898c0790f4bcc 100644 --- a/components/slack/actions/create-channel/create-channel.mjs +++ b/components/slack/actions/create-channel/create-channel.mjs @@ -4,7 +4,7 @@ export default { key: "slack-create-channel", name: "Create a Channel", description: "Create a new channel. [See the documentation](https://api.slack.com/methods/conversations.create)", - version: "0.0.23", + version: "0.0.24", type: "action", props: { slack, @@ -25,7 +25,7 @@ export default { // parse name const name = this.channelName.replace(/\s+/g, "-").toLowerCase(); - const response = await this.slack.sdk().conversations.create({ + const response = await this.slack.createConversations({ name, is_private: this.isPrivate, }); diff --git a/components/slack/actions/create-reminder/create-reminder.mjs b/components/slack/actions/create-reminder/create-reminder.mjs index d0332a9bf9344..5165ba591e53c 100644 --- a/components/slack/actions/create-reminder/create-reminder.mjs +++ b/components/slack/actions/create-reminder/create-reminder.mjs @@ -4,7 +4,7 @@ export default { key: "slack-create-reminder", name: "Create Reminder", description: "Create a reminder. [See the documentation](https://api.slack.com/methods/reminders.add)", - version: "0.0.23", + version: "0.0.24", type: "action", props: { slack, @@ -35,7 +35,7 @@ export default { }, }, async run({ $ }) { - const response = await this.slack.sdk().reminders.add({ + const response = await this.slack.addReminders({ text: this.text, team_id: this.team_id, time: this.timestamp, diff --git a/components/slack/actions/delete-file/delete-file.mjs b/components/slack/actions/delete-file/delete-file.mjs index 2394582668de7..72d4dd046cee5 100644 --- a/components/slack/actions/delete-file/delete-file.mjs +++ b/components/slack/actions/delete-file/delete-file.mjs @@ -4,19 +4,28 @@ export default { key: "slack-delete-file", name: "Delete File", description: "Delete a file. [See the documentation](https://api.slack.com/methods/files.delete)", - version: "0.0.22", + version: "0.0.23", type: "action", props: { slack, + conversation: { + propDefinition: [ + slack, + "conversation", + ], + }, file: { propDefinition: [ slack, "file", + (c) => ({ + channel: c.conversation, + }), ], }, }, async run({ $ }) { - const response = await this.slack.sdk().files.delete({ + const response = await this.slack.deleteFiles({ file: this.file, }); $.export("$summary", `Successfully deleted file with ID ${this.file}`); diff --git a/components/slack/actions/delete-message/delete-message.mjs b/components/slack/actions/delete-message/delete-message.mjs index ba566bed71f96..6bee963612b0c 100644 --- a/components/slack/actions/delete-message/delete-message.mjs +++ b/components/slack/actions/delete-message/delete-message.mjs @@ -4,7 +4,7 @@ export default { key: "slack-delete-message", name: "Delete Message", description: "Delete a message. [See the documentation](https://api.slack.com/methods/chat.delete)", - version: "0.0.22", + version: "0.0.23", type: "action", props: { slack, @@ -29,7 +29,7 @@ export default { }, }, async run({ $ }) { - const response = await this.slack.sdk().chat.delete({ + const response = await this.slack.deleteMessage({ channel: this.conversation, ts: this.timestamp, as_user: this.as_user, diff --git a/components/slack/actions/find-message/find-message.mjs b/components/slack/actions/find-message/find-message.mjs index a00ea389a52d2..2eebe5b19f440 100644 --- a/components/slack/actions/find-message/find-message.mjs +++ b/components/slack/actions/find-message/find-message.mjs @@ -4,7 +4,7 @@ export default { key: "slack-find-message", name: "Find Message", description: "Find a Slack message. [See the documentation](https://api.slack.com/methods/search.messages)", - version: "0.0.22", + version: "0.0.23", type: "action", props: { slack, diff --git a/components/slack/actions/find-user-by-email/find-user-by-email.mjs b/components/slack/actions/find-user-by-email/find-user-by-email.mjs index 5d5bde64e7bd9..92b1ac76b3ff1 100644 --- a/components/slack/actions/find-user-by-email/find-user-by-email.mjs +++ b/components/slack/actions/find-user-by-email/find-user-by-email.mjs @@ -4,7 +4,7 @@ export default { key: "slack-find-user-by-email", name: "Find User by Email", description: "Find a user by matching against their email. [See the documentation](https://api.slack.com/methods/users.lookupByEmail)", - version: "0.0.22", + version: "0.0.23", type: "action", props: { slack, @@ -16,7 +16,7 @@ export default { }, }, async run({ $ }) { - const response = await this.slack.sdk().users.lookupByEmail({ + const response = await this.slack.lookupUserByEmail({ email: this.email, }); if (response.ok) { diff --git a/components/slack/actions/get-file/get-file.mjs b/components/slack/actions/get-file/get-file.mjs index f04cffdf6570f..f89784a4bb89c 100644 --- a/components/slack/actions/get-file/get-file.mjs +++ b/components/slack/actions/get-file/get-file.mjs @@ -4,19 +4,28 @@ export default { key: "slack-get-file", name: "Get File", description: "Return information about a file. [See the documentation](https://api.slack.com/methods/files.info)", - version: "0.0.22", + version: "0.0.23", type: "action", props: { slack, + conversation: { + propDefinition: [ + slack, + "conversation", + ], + }, file: { propDefinition: [ slack, "file", + (c) => ({ + channel: c.conversation, + }), ], }, }, async run({ $ }) { - const response = await this.slack.sdk().files.info({ + const response = await this.slack.getFileInfo({ file: this.file, }); $.export("$summary", `Successfully retrieved file with ID ${this.file}`); diff --git a/components/slack/actions/invite-user-to-channel/invite-user-to-channel.mjs b/components/slack/actions/invite-user-to-channel/invite-user-to-channel.mjs index 1898623175d08..9b9cf1d1801bb 100644 --- a/components/slack/actions/invite-user-to-channel/invite-user-to-channel.mjs +++ b/components/slack/actions/invite-user-to-channel/invite-user-to-channel.mjs @@ -4,7 +4,7 @@ export default { key: "slack-invite-user-to-channel", name: "Invite User to Channel", description: "Invite a user to an existing channel. [See the documentation](https://api.slack.com/methods/conversations.invite)", - version: "0.0.22", + version: "0.0.23", type: "action", props: { slack, @@ -22,11 +22,19 @@ export default { }, }, async run({ $ }) { - const response = await this.slack.sdk().conversations.invite({ - channel: this.conversation, - users: this.user, - }); - $.export("$summary", `Successfully invited user ${this.user} to channel with ID ${this.conversation}`); - return response; + try { + const response = await this.slack.inviteToConversation({ + channel: this.conversation, + users: this.user, + }); + $.export("$summary", `Successfully invited user ${this.user} to channel with ID ${this.conversation}`); + return response; + } catch (error) { + if (error.includes("already_in_channel")) { + $.export("$summary", `The user ${this.user} is already in the channel`); + return; + } + throw error; + } }, }; diff --git a/components/slack/actions/kick-user/kick-user.mjs b/components/slack/actions/kick-user/kick-user.mjs index c937a6b0d8d8a..5598d9cf0d543 100644 --- a/components/slack/actions/kick-user/kick-user.mjs +++ b/components/slack/actions/kick-user/kick-user.mjs @@ -5,7 +5,7 @@ export default { key: "slack-kick-user", name: "Kick User", description: "Remove a user from a conversation. [See the documentation](https://api.slack.com/methods/conversations.kick)", - version: "0.0.22", + version: "0.0.23", type: "action", props: { slack, @@ -33,11 +33,19 @@ export default { }, }, async run({ $ }) { - const response = await this.slack.sdk().conversations.kick({ - channel: this.conversation, - user: this.user, - }); - $.export("$summary", `Successfully kicked user ${this.user} from channel with ID ${this.conversation}`); - return response; + try { + const response = await this.slack.kickUserFromConversation({ + channel: this.conversation, + user: this.user, + }); + $.export("$summary", `Successfully kicked user ${this.user} from channel with ID ${this.conversation}`); + return response; + } catch (error) { + if (error.includes("not_in_channel")) { + $.export("$summary", `The user ${this.user} is not in the channel`); + return; + } + throw error; + } }, }; diff --git a/components/slack/actions/list-channels/list-channels.mjs b/components/slack/actions/list-channels/list-channels.mjs index 0b4ead78ad740..32cab1cf48ac4 100644 --- a/components/slack/actions/list-channels/list-channels.mjs +++ b/components/slack/actions/list-channels/list-channels.mjs @@ -4,16 +4,44 @@ export default { key: "slack-list-channels", name: "List Channels", description: "Return a list of all channels in a workspace. [See the documentation](https://api.slack.com/methods/conversations.list)", - version: "0.0.22", + version: "0.0.23", type: "action", props: { slack, + pageSize: { + propDefinition: [ + slack, + "pageSize", + ], + }, + numPages: { + propDefinition: [ + slack, + "numPages", + ], + }, }, async run({ $ }) { - const response = await this.slack.sdk().conversations.list(); - $.export("$summary", `Successfully found ${response.length} channel${response.length === 1 + const allChannels = []; + const params = { + limit: this.pageSize, + }; + let page = 0; + + do { + const { + channels, response_metadata: { next_cursor: nextCursor }, + } = await this.slack.conversationsList(params); + allChannels.push(...channels); + params.cursor = nextCursor; + page++; + } while (params.cursor && page < this.numPages); + + $.export("$summary", `Successfully found ${allChannels.length} channel${allChannels.length === 1 ? "" : "s"}`); - return response; + return { + channels: allChannels, + }; }, }; diff --git a/components/slack/actions/list-files/list-files.mjs b/components/slack/actions/list-files/list-files.mjs index 08b6919734dbe..1915becf44591 100644 --- a/components/slack/actions/list-files/list-files.mjs +++ b/components/slack/actions/list-files/list-files.mjs @@ -4,7 +4,7 @@ export default { key: "slack-list-files", name: "List Files", description: "Return a list of files within a team. [See the documentation](https://api.slack.com/methods/files.list)", - version: "0.0.50", + version: "0.0.51", type: "action", props: { slack, @@ -28,6 +28,18 @@ export default { ], optional: true, }, + pageSize: { + propDefinition: [ + slack, + "pageSize", + ], + }, + numPages: { + propDefinition: [ + slack, + "numPages", + ], + }, }, async run({ $ }) { const allFiles = []; @@ -36,15 +48,16 @@ export default { user: this.user, team_id: this.team_id, page: 1, + count: this.pageSize, }; let hasMore; do { - const { files } = await this.slack.sdk().files.list(params); + const { files } = await this.slack.listFiles(params); allFiles.push(...files); hasMore = files.length; params.page++; - } while (hasMore); + } while (hasMore && params.page <= this.numPages); $.export("$summary", `Successfully retrieved ${allFiles.length} file${allFiles.length === 1 ? "" diff --git a/components/slack/actions/list-group-members/list-group-members.mjs b/components/slack/actions/list-group-members/list-group-members.mjs index 5d6509d4c7738..16aba1393b3c5 100644 --- a/components/slack/actions/list-group-members/list-group-members.mjs +++ b/components/slack/actions/list-group-members/list-group-members.mjs @@ -4,7 +4,7 @@ export default { key: "slack-list-group-members", name: "List Group Members", description: "List all users in a User Group. [See the documentation](https://api.slack.com/methods/usergroups.users.list)", - version: "0.0.7", + version: "0.0.8", type: "action", props: { slack, @@ -22,21 +22,42 @@ export default { optional: true, description: "Encoded team id where the user group exists, required if org token is used.", }, + pageSize: { + propDefinition: [ + slack, + "pageSize", + ], + }, + numPages: { + propDefinition: [ + slack, + "numPages", + ], + }, }, async run({ $ }) { - const { - userGroup, - team, - } = this; - const response = await this.slack.sdk().usergroups.users.list({ - usergroup: userGroup, - team_id: team, - }); - if (response.users?.length) { - $.export("$summary", `Successfully retrieved ${response.users.length} user${response.users.length === 1 + const members = []; + const params = { + usergroup: this.userGroup, + team_id: this.team, + limit: this.pageSize, + }; + let page = 0; + + do { + const { + users, response_metadata: { next_cursor: nextCursor }, + } = await this.slack.listGroupMembers(params); + members.push(...users); + params.cursor = nextCursor; + page++; + } while (params.cursor && page < this.numPages); + + if (members?.length) { + $.export("$summary", `Successfully retrieved ${members.length} user${members.length === 1 ? "" : "s"}`); } - return response; + return members; }, }; diff --git a/components/slack/actions/list-members-in-channel/list-members-in-channel.mjs b/components/slack/actions/list-members-in-channel/list-members-in-channel.mjs index 368618203fb93..dded65e4afd74 100644 --- a/components/slack/actions/list-members-in-channel/list-members-in-channel.mjs +++ b/components/slack/actions/list-members-in-channel/list-members-in-channel.mjs @@ -4,7 +4,7 @@ export default { key: "slack-list-members-in-channel", name: "List Members in Channel", description: "Retrieve members of a channel. [See the documentation](https://api.slack.com/methods/conversations.members)", - version: "0.0.22", + version: "0.0.23", type: "action", props: { slack, @@ -20,19 +20,44 @@ export default { description: "Optionally, return usernames in addition to IDs", optional: true, }, + pageSize: { + propDefinition: [ + slack, + "pageSize", + ], + }, + numPages: { + propDefinition: [ + slack, + "numPages", + ], + }, }, async run({ $ }) { - const { members } = await this.slack.sdk().conversations.members({ + let channelMembers = []; + const params = { channel: this.conversation, - }); - let channelMembers = members; + limit: this.pageSize, + }; + let page = 0; + + do { + const { + members, response_metadata: { next_cursor: nextCursor }, + } = await this.slack.listChannelMembers(params); + channelMembers.push(...members); + params.cursor = nextCursor; + page++; + } while (params.cursor && page < this.numPages); + if (this.returnUsernames) { - const usernames = await this.slack.userNames(); + const usernames = await this.slack.userNameLookup(channelMembers); channelMembers = channelMembers?.map((id) => ({ id, username: usernames[id], })) || []; } + $.export("$summary", `Successfully retrieved ${channelMembers.length} member${channelMembers.length === 1 ? "" : "s"}`); diff --git a/components/slack/actions/list-replies/list-replies.mjs b/components/slack/actions/list-replies/list-replies.mjs index 34c5a1071b810..8abffdaea3403 100644 --- a/components/slack/actions/list-replies/list-replies.mjs +++ b/components/slack/actions/list-replies/list-replies.mjs @@ -4,7 +4,7 @@ export default { key: "slack-list-replies", name: "List Replies", description: "Retrieve a thread of messages posted to a conversation. [See the documentation](https://api.slack.com/methods/conversations.replies)", - version: "0.0.22", + version: "0.0.23", type: "action", props: { slack, @@ -20,15 +20,42 @@ export default { "messageTs", ], }, + pageSize: { + propDefinition: [ + slack, + "pageSize", + ], + }, + numPages: { + propDefinition: [ + slack, + "numPages", + ], + }, }, async run({ $ }) { - const response = await this.slack.sdk().conversations.replies({ + const replies = []; + const params = { channel: this.conversation, ts: this.timestamp, - }); - $.export("$summary", `Successfully retrieved ${response.messages.length} reply message${response.messages.length === 1 + limit: this.pageSize, + }; + let page = 0; + + do { + const { + messages, response_metadata: { next_cursor: nextCursor }, + } = await this.slack.getConversationReplies(params); + replies.push(...messages); + params.cursor = nextCursor; + page++; + } while (params.cursor && page < this.numPages); + + $.export("$summary", `Successfully retrieved ${replies.length} reply message${replies.length === 1 ? "" : "s"}`); - return response; + return { + messages: replies, + }; }, }; diff --git a/components/slack/actions/list-users/list-users.mjs b/components/slack/actions/list-users/list-users.mjs index 5cef36ae20dd6..79ddcf8281845 100644 --- a/components/slack/actions/list-users/list-users.mjs +++ b/components/slack/actions/list-users/list-users.mjs @@ -4,7 +4,7 @@ export default { key: "slack-list-users", name: "List Users", description: "Return a list of all users in a workspace. [See the documentation](https://api.slack.com/methods/users.list)", - version: "0.0.22", + version: "0.0.23", type: "action", props: { slack, @@ -15,14 +15,41 @@ export default { ], optional: true, }, + pageSize: { + propDefinition: [ + slack, + "pageSize", + ], + }, + numPages: { + propDefinition: [ + slack, + "numPages", + ], + }, }, async run({ $ }) { - const response = await this.slack.usersList({ + const users = []; + const params = { team_id: this.teamId, - }); - $.export("$summary", `Successfully retrieved ${response.members.length} user${response.members.length === 1 + limit: this.pageSize, + }; + let page = 0; + + do { + const { + members, response_metadata: { next_cursor: nextCursor }, + } = await this.slack.usersList(params); + users.push(...members); + params.cursor = nextCursor; + page++; + } while (params.cursor && page < this.numPages); + + $.export("$summary", `Successfully retrieved ${users.length} user${users.length === 1 ? "" : "s"}`); - return response; + return { + members: users, + }; }, }; diff --git a/components/slack/actions/reply-to-a-message/reply-to-a-message.mjs b/components/slack/actions/reply-to-a-message/reply-to-a-message.mjs index 9ea8bd50ffb4a..fe983a74f0fd8 100644 --- a/components/slack/actions/reply-to-a-message/reply-to-a-message.mjs +++ b/components/slack/actions/reply-to-a-message/reply-to-a-message.mjs @@ -6,7 +6,7 @@ export default { key: "slack-reply-to-a-message", name: "Reply to a Message Thread", description: "Send a message as a threaded reply. See [postMessage](https://api.slack.com/methods/chat.postMessage) or [scheduleMessage](https://api.slack.com/methods/chat.scheduleMessage) docs here", - version: "0.1.27", + version: "0.1.28", type: "action", props: { slack: common.props.slack, diff --git a/components/slack/actions/send-block-kit-message/send-block-kit-message.mjs b/components/slack/actions/send-block-kit-message/send-block-kit-message.mjs index 3bd4e25f90358..8e7695e168aa8 100644 --- a/components/slack/actions/send-block-kit-message/send-block-kit-message.mjs +++ b/components/slack/actions/send-block-kit-message/send-block-kit-message.mjs @@ -7,7 +7,7 @@ export default { key: "slack-send-block-kit-message", name: "Build and Send a Block Kit Message", description: "Configure custom blocks and send to a channel, group, or user. [See the documentation](https://api.slack.com/tools/block-kit-builder).", - version: "0.4.3", + version: "0.4.4", type: "action", props: { slack: common.props.slack, diff --git a/components/slack/actions/send-large-message/send-large-message.mjs b/components/slack/actions/send-large-message/send-large-message.mjs index f7916b04054db..412f13940a8cb 100644 --- a/components/slack/actions/send-large-message/send-large-message.mjs +++ b/components/slack/actions/send-large-message/send-large-message.mjs @@ -5,7 +5,7 @@ export default { key: "slack-send-large-message", name: "Send a Large Message (3000+ characters)", description: "Send a large message (more than 3000 characters) to a channel, group or user. See [postMessage](https://api.slack.com/methods/chat.postMessage) or [scheduleMessage](https://api.slack.com/methods/chat.scheduleMessage) docs here", - version: "0.0.22", + version: "0.0.23", type: "action", props: { slack: common.props.slack, @@ -70,17 +70,20 @@ export default { let response; if (this.post_at) { obj.post_at = this.post_at; - response = await this.slack.sdk().chat.scheduleMessage(obj); + response = await this.slack.scheduleMessage(obj); + } else { + response = await this.slack.postChatMessage(obj); } - response = await this.slack.sdk().chat.postMessage(obj); const { channel } = await this.slack.conversationsInfo({ channel: response.channel, }); let channelName = `#${channel?.name}`; if (channel.is_im) { - const usernames = await this.slack.userNames(); - channelName = `@${usernames[channel.user]}`; + const { profile } = await this.slack.getUserProfile({ + user: channel.user, + }); + channelName = `@${profile.real_name}`; } else if (channel.is_mpim) { channelName = `@${channel.purpose.value}`; } diff --git a/components/slack/actions/send-message-advanced/send-message-advanced.mjs b/components/slack/actions/send-message-advanced/send-message-advanced.mjs index 18eeb21e25dba..1a724cbb50d20 100644 --- a/components/slack/actions/send-message-advanced/send-message-advanced.mjs +++ b/components/slack/actions/send-message-advanced/send-message-advanced.mjs @@ -7,7 +7,7 @@ export default { key: "slack-send-message-advanced", name: "Send Message (Advanced)", description: "Customize advanced setttings and send a message to a channel, group or user. See [postMessage](https://api.slack.com/methods/chat.postMessage) or [scheduleMessage](https://api.slack.com/methods/chat.scheduleMessage) docs here", - version: "0.0.5", + version: "0.0.6", type: "action", props: { slack: common.props.slack, diff --git a/components/slack/actions/send-message-to-channel/send-message-to-channel.mjs b/components/slack/actions/send-message-to-channel/send-message-to-channel.mjs index a3779f1bdeea1..c5dd32cf4ca32 100644 --- a/components/slack/actions/send-message-to-channel/send-message-to-channel.mjs +++ b/components/slack/actions/send-message-to-channel/send-message-to-channel.mjs @@ -6,7 +6,7 @@ export default { key: "slack-send-message-to-channel", name: "Send Message to Channel", description: "Send a message to a public or private channel. [See the documentation](https://api.slack.com/methods/chat.postMessage)", - version: "0.0.3", + version: "0.0.4", type: "action", props: { slack: common.props.slack, diff --git a/components/slack/actions/send-message-to-user-or-group/send-message-to-user-or-group.mjs b/components/slack/actions/send-message-to-user-or-group/send-message-to-user-or-group.mjs index f475992216ec0..5a11024688ab5 100644 --- a/components/slack/actions/send-message-to-user-or-group/send-message-to-user-or-group.mjs +++ b/components/slack/actions/send-message-to-user-or-group/send-message-to-user-or-group.mjs @@ -7,7 +7,7 @@ export default { key: "slack-send-message-to-user-or-group", name: "Send Message to User or Group", description: "Send a message to a user or group. [See the documentation](https://api.slack.com/methods/chat.postMessage)", - version: "0.0.3", + version: "0.0.4", type: "action", props: { slack: common.props.slack, diff --git a/components/slack/actions/send-message/send-message.mjs b/components/slack/actions/send-message/send-message.mjs index eff6db0fd21ab..514495ea0ab1e 100644 --- a/components/slack/actions/send-message/send-message.mjs +++ b/components/slack/actions/send-message/send-message.mjs @@ -6,7 +6,7 @@ export default { key: "slack-send-message", name: "Send Message", description: "Send a message to a user, group, private channel or public channel. [See the documentation](https://api.slack.com/methods/chat.postMessage)", - version: "0.0.18", + version: "0.0.19", type: "action", props: { slack: common.props.slack, diff --git a/components/slack/actions/set-channel-description/set-channel-description.mjs b/components/slack/actions/set-channel-description/set-channel-description.mjs index e7a353c8db39e..ff8df9907e254 100644 --- a/components/slack/actions/set-channel-description/set-channel-description.mjs +++ b/components/slack/actions/set-channel-description/set-channel-description.mjs @@ -4,7 +4,7 @@ export default { key: "slack-set-channel-description", name: "Set Channel Description", description: "Change the description or purpose of a channel. [See the documentation](https://api.slack.com/methods/conversations.setPurpose)", - version: "0.0.7", + version: "0.0.8", type: "action", props: { slack, @@ -22,7 +22,7 @@ export default { }, }, async run({ $ }) { - const response = await this.slack.sdk().conversations.setPurpose({ + const response = await this.slack.setChannelDescription({ channel: this.conversation, purpose: this.purpose, }); diff --git a/components/slack/actions/set-channel-topic/set-channel-topic.mjs b/components/slack/actions/set-channel-topic/set-channel-topic.mjs index fc51deecdd1cb..844d926ef37eb 100644 --- a/components/slack/actions/set-channel-topic/set-channel-topic.mjs +++ b/components/slack/actions/set-channel-topic/set-channel-topic.mjs @@ -4,7 +4,7 @@ export default { key: "slack-set-channel-topic", name: "Set Channel Topic", description: "Set the topic on a selected channel. [See the documentation](https://api.slack.com/methods/conversations.setTopic)", - version: "0.0.22", + version: "0.0.23", type: "action", props: { slack, @@ -22,7 +22,7 @@ export default { }, }, async run({ $ }) { - const response = await this.slack.sdk().conversations.setTopic({ + const response = await this.slack.setChannelTopic({ channel: this.conversation, topic: this.topic, }); diff --git a/components/slack/actions/set-status/set-status.mjs b/components/slack/actions/set-status/set-status.mjs index d506905982e61..a7f9a05fb98f3 100644 --- a/components/slack/actions/set-status/set-status.mjs +++ b/components/slack/actions/set-status/set-status.mjs @@ -4,7 +4,7 @@ export default { key: "slack-set-status", name: "Set Status", description: "Set the current status for a user. [See the documentation](https://api.slack.com/methods/users.profile.set)", - version: "0.0.7", + version: "0.0.8", type: "action", props: { slack, @@ -30,7 +30,7 @@ export default { }, }, async run({ $ }) { - const response = await this.slack.sdk().users.profile.set({ + const response = await this.slack.updateProfile({ profile: { status_text: this.statusText, status_emoji: this.statusEmoji && `:${this.statusEmoji}:`, diff --git a/components/slack/actions/update-group-members/update-group-members.mjs b/components/slack/actions/update-group-members/update-group-members.mjs index c0531ee8d3df3..ebd92713c2379 100644 --- a/components/slack/actions/update-group-members/update-group-members.mjs +++ b/components/slack/actions/update-group-members/update-group-members.mjs @@ -4,7 +4,7 @@ export default { key: "slack-update-group-members", name: "Update Groups Members", description: "Update the list of users for a User Group. [See the documentation](https://api.slack.com/methods/usergroups.users.update)", - version: "0.0.7", + version: "0.0.8", type: "action", props: { slack, @@ -50,13 +50,13 @@ export default { usersToRemove, team, } = this; - let { users } = await this.slack.sdk().usergroups.users.list({ + let { users } = await this.slack.listGroupMembers({ usergroup: userGroup, team_id: team, }); users = users.filter((user) => !usersToRemove.includes(user)); users.push(...usersToAdd); - const response = await this.slack.sdk().usergroups.users.update({ + const response = await this.slack.updateGroupMembers({ usergroup: userGroup, users, team_id: team, diff --git a/components/slack/actions/update-message/update-message.mjs b/components/slack/actions/update-message/update-message.mjs index 1614932abdc21..1c0087958f304 100644 --- a/components/slack/actions/update-message/update-message.mjs +++ b/components/slack/actions/update-message/update-message.mjs @@ -4,7 +4,7 @@ export default { key: "slack-update-message", name: "Update Message", description: "Update a message. [See the documentation](https://api.slack.com/methods/chat.update)", - version: "0.1.22", + version: "0.1.23", type: "action", props: { slack, @@ -41,7 +41,7 @@ export default { }, }, async run({ $ }) { - const response = await this.slack.sdk().chat.update({ + const response = await this.slack.updateMessage({ ts: this.timestamp, text: this.text, channel: this.conversation, diff --git a/components/slack/actions/update-profile/update-profile.mjs b/components/slack/actions/update-profile/update-profile.mjs index b58e64a5d57cf..4ea6418afe444 100644 --- a/components/slack/actions/update-profile/update-profile.mjs +++ b/components/slack/actions/update-profile/update-profile.mjs @@ -5,7 +5,7 @@ export default { key: "slack-update-profile", name: "Update Profile", description: "Update basic profile field such as name or title. [See the documentation](https://api.slack.com/methods/users.profile.set)", - version: "0.0.22", + version: "0.0.23", type: "action", props: { slack, @@ -70,7 +70,7 @@ export default { ) { throw new ConfigurationError("Please provide at least one value to update"); } - const response = await this.slack.sdk().users.profile.set({ + const response = await this.slack.updateProfile({ profile: { display_name: this.displayName, first_name: this.firstName, diff --git a/components/slack/actions/upload-file/upload-file.mjs b/components/slack/actions/upload-file/upload-file.mjs index 37065aa5cad9d..5489b4f2899b2 100644 --- a/components/slack/actions/upload-file/upload-file.mjs +++ b/components/slack/actions/upload-file/upload-file.mjs @@ -1,12 +1,15 @@ -import { ConfigurationError } from "@pipedream/platform"; +import { + ConfigurationError, axios, +} from "@pipedream/platform"; import fs from "fs"; +import FormData from "form-data"; import slack from "../../slack.app.mjs"; export default { key: "slack-upload-file", name: "Upload File", - description: "Upload a file. [See the documentation](https://api.slack.com/methods/files.upload)", - version: "0.0.26", + description: "Upload a file. [See the documentation](https://api.slack.com/messaging/files#uploading_files)", + version: "0.0.27", type: "action", props: { slack, @@ -35,13 +38,54 @@ export default { if (!fs.existsSync(this.content)) { throw new ConfigurationError(`\`${this.content}\` not found, a valid \`/tmp\` path is needed`); } - const response = await this.slack.sdk().filesUploadV2({ - file: fs.createReadStream(this.content), + + const filename = this.content.split("/").pop(); + + // Get an upload URL from Slack + const getUploadUrlResponse = await this.slack.getUploadUrl({ + filename, + length: fs.statSync(this.content).size, + }); + + if (!getUploadUrlResponse.ok) { + throw new ConfigurationError(`Error getting upload URL: ${JSON.stringify(getUploadUrlResponse)}`); + } + + const { + upload_url: uploadUrl, file_id: fileId, + } = getUploadUrlResponse; + + // Upload the file to the provided URL + const formData = new FormData(); + formData.append("file", fs.createReadStream(this.content)); + formData.append("filename", filename); + + await axios($, { + url: uploadUrl, + data: formData, + method: "POST", + headers: { + ...formData.getHeaders(), + Authorization: `Bearer ${this.slack.getToken()}`, + }, + }); + + // Complete the file upload process in Slack + const completeUploadResponse = await this.slack.completeUpload({ channel_id: this.conversation, initial_comment: this.initialComment, - filename: this.content.split("/").pop(), + files: [ + { + id: fileId, + }, + ], }); + + if (!completeUploadResponse.ok) { + throw new Error(`Error completing upload: ${JSON.stringify(completeUploadResponse)}`); + } + $.export("$summary", "Successfully uploaded file"); - return response; + return completeUploadResponse; }, }; diff --git a/components/slack/actions/verify-slack-signature/verify-slack-signature.mjs b/components/slack/actions/verify-slack-signature/verify-slack-signature.mjs index 2e607905c6c75..1860e13bd59a0 100644 --- a/components/slack/actions/verify-slack-signature/verify-slack-signature.mjs +++ b/components/slack/actions/verify-slack-signature/verify-slack-signature.mjs @@ -5,7 +5,7 @@ export default { key: "slack-verify-slack-signature", name: "Verify Slack Signature", description: "Verifying requests from Slack, slack signs its requests using a secret that's unique to your app. [See the documentation](https://api.slack.com/authentication/verifying-requests-from-slack)", - version: "0.0.15", + version: "0.0.16", type: "action", props: { slack, diff --git a/components/slack/common/constants.mjs b/components/slack/common/constants.mjs index c96e534bc3936..7d64f48d573d7 100644 --- a/components/slack/common/constants.mjs +++ b/components/slack/common/constants.mjs @@ -1,5 +1,5 @@ const MAX_RESOURCES = 800; -const LIMIT = 200; +const LIMIT = 250; const CHANNEL_TYPE = { PUBLIC: "public_channel", diff --git a/components/slack/package.json b/components/slack/package.json index 060f3e2262d73..ff314623396bd 100644 --- a/components/slack/package.json +++ b/components/slack/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/slack", - "version": "0.9.1", + "version": "0.9.2", "description": "Pipedream Slack Components", "main": "slack.app.mjs", "keywords": [ @@ -15,6 +15,6 @@ }, "dependencies": { "@pipedream/platform": "^3.0.0", - "@slack/web-api": "^7.0.4" + "@slack/web-api": "^7.9.0" } } diff --git a/components/slack/slack.app.mjs b/components/slack/slack.app.mjs index f73a14124d8c5..81b560452a7ac 100644 --- a/components/slack/slack.app.mjs +++ b/components/slack/slack.app.mjs @@ -1,5 +1,7 @@ import { WebClient } from "@slack/web-api"; import constants from "./common/constants.mjs"; +import get from "lodash/get.js"; +import retry from "async-retry"; export default { type: "app", @@ -15,27 +17,24 @@ export default { const types = [ "im", ]; - let [ - userNames, - conversationsResp, - ] = await Promise.all([ - prevContext.userNames ?? this.userNames(), - this.availableConversations(types.join(), prevContext.cursor), - ]); + let conversationsResp + = await this.availableConversations(types.join(), prevContext.cursor, true); if (channelId) { - const { members } = await this.sdk().conversations.members({ + const { members } = await this.listChannelMembers({ channel: channelId, + throwRateLimitError: true, }); conversationsResp.conversations = conversationsResp.conversations .filter((c) => members.includes(c.user || c.id)); } + const userIds = conversationsResp.conversations.map(({ user }) => user); + const userNames = await this.userNameLookup(userIds); return { options: conversationsResp.conversations.map((c) => ({ label: `@${userNames[c.user]}`, value: c.user || c.id, })), context: { - userNames, cursor: conversationsResp.cursor, }, }; @@ -50,7 +49,7 @@ export default { const types = [ "mpim", ]; - const resp = await this.availableConversations(types.join(), cursor); + const resp = await this.availableConversations(types.join(), cursor, true); return { options: resp.conversations.map((c) => { return { @@ -69,7 +68,9 @@ export default { label: "User Group", description: "The encoded ID of the User Group.", async options() { - const { usergroups } = await this.usergroupsList(); + const { usergroups } = await this.usergroupsList({ + throwRateLimitError: true, + }); return usergroups.map((c) => ({ label: c.name, value: c.id, @@ -81,7 +82,9 @@ export default { label: "Reminder", description: "Select a reminder", async options() { - const { reminders } = await this.remindersList(); + const { reminders } = await this.remindersList({ + throwRateLimitError: true, + }); return reminders.map((c) => ({ label: c.text, value: c.id, @@ -95,15 +98,14 @@ export default { async options({ prevContext, types, }) { - let { - cursor, - userNames: userNamesOrPromise, - } = prevContext; + let { cursor } = prevContext; if (prevContext?.types) { types = prevContext.types; } if (types == null) { - const { response_metadata: { scopes } } = await this.authTest(); + const { response_metadata: { scopes } } = await this.authTest({ + throwRateLimitError: true, + }); types = [ "public_channel", ]; @@ -115,21 +117,17 @@ export default { } if (scopes.includes("im:read")) { types.push("im"); - userNamesOrPromise = this.userNames(); } - } else if (types.includes("im")) { - userNamesOrPromise = this.userNames(); } - const [ - userNames, - conversationsResp, - ] = await Promise.all([ - userNamesOrPromise, - this.availableConversations(types.join(), cursor), - ]); - const conversations = userNames - ? conversationsResp.conversations - : conversationsResp.conversations.filter((c) => !c.is_im); + const conversationsResp = await this.availableConversations(types.join(), cursor, true); + let conversations, userNames; + if (types.includes("im")) { + conversations = conversationsResp.conversations; + const userIds = conversations.map(({ user }) => user); + userNames = await this.userNameLookup(userIds); + } else { + conversations = conversationsResp.conversations.filter((c) => !c.is_im); + } return { options: conversations.map((c) => { if (c.is_im) { @@ -154,7 +152,6 @@ export default { context: { types, cursor: conversationsResp.cursor, - userNames, }, }; }, @@ -169,7 +166,6 @@ export default { channelsFilter = (channel) => channel, excludeArchived = true, }) { - const userNames = prevContext.userNames || await this.userNames(); const { channels, response_metadata: { next_cursor: cursor }, @@ -178,8 +174,15 @@ export default { cursor: prevContext.cursor, limit: constants.LIMIT, exclude_archived: excludeArchived, + throwRateLimitError: true, }); + let userNames; + if (types.includes("im")) { + const userIds = channels.filter(({ is_im }) => is_im).map(({ user }) => user); + userNames = await this.userNameLookup(userIds); + } + const options = channels .filter(channelsFilter) .map((c) => { @@ -207,7 +210,6 @@ export default { options, context: { cursor, - userNames, }, }; }, @@ -222,6 +224,8 @@ export default { response_metadata: { next_cursor: cursor }, } = await this.authTeamsList({ cursor: prevContext.cursor, + limit: constants.LIMIT, + throwRateLimitError: true, }); return { @@ -268,9 +272,11 @@ export default { async options({ channel, page, }) { - const { files } = await this.sdk().files.list({ + const { files } = await this.listFiles({ channel, page: page + 1, + count: constants.LIMIT, + throwRateLimitError: true, }); return files?.map(({ id: value, name: label, @@ -344,7 +350,9 @@ export default { description: "Optionally provide an emoji to use as the icon for this message. E.g., `:fire:` Overrides `icon_url`. Must be used in conjunction with `Send as User` set to `false`, otherwise ignored.", optional: true, async options() { - return await this.getCustomEmojis(); + return await this.getCustomEmojis({ + throwRateLimitError: true, + }); }, }, content: { @@ -425,6 +433,20 @@ export default { default: false, optional: true, }, + pageSize: { + type: "integer", + label: "Page Size", + description: "The number of results to include in a page. Default: 250", + default: constants.LIMIT, + optional: true, + }, + numPages: { + type: "integer", + label: "Number of Pages", + description: "The number of pages to retrieve. Default: 1", + default: 1, + optional: true, + }, }, methods: { getChannelLabel(resource) { @@ -450,22 +472,18 @@ export default { * token */ sdk() { - return new WebClient(this.getToken()); + return new WebClient(this.getToken(), { + rejectRateLimitedCalls: true, + }); }, async makeRequest({ - method = "", ...args + method = "", throwRateLimitError = false, ...args } = {}) { - let response; const props = method.split("."); const sdk = props.reduce((reduction, prop) => reduction[prop], this.sdk()); - try { - response = await sdk(args); - } catch (error) { - console.log(`Error calling ${method}`, error); - throw error; - } + const response = await this._withRetries(() => sdk(args), throwRateLimitError); if (!response.ok) { console.log(`Error in response with method ${method}`, response.error); @@ -473,6 +491,28 @@ export default { } return response; }, + async _withRetries(apiCall, throwRateLimitError = false) { + const retryOpts = { + retries: 3, + minTimeout: 30000, + }; + return retry(async (bail) => { + try { + return await apiCall(); + } catch (error) { + const statusCode = get(error, "code"); + if (statusCode === "slack_webapi_rate_limited_error") { + if (throwRateLimitError) { + bail(`Rate limit exceeded. ${error}`); + } else { + console.log(`Rate limit exceeded. Will retry in ${retryOpts.minTimeout / 1000} seconds`); + throw error; + } + } + bail(`${error}`); + } + }, retryOpts); + }, /** * Returns a list of channel-like conversations in a workspace. The * "channels" returned depend on what the calling token has access to and @@ -485,7 +525,7 @@ export default { * @returns an object containing a list of conversations and the cursor for the next * page of conversations */ - async availableConversations(types, cursor) { + async availableConversations(types, cursor, throwRateLimitError = false) { const { channels: conversations, response_metadata: { next_cursor: nextCursor }, @@ -494,18 +534,14 @@ export default { cursor, limit: constants.LIMIT, exclude_archived: true, + throwRateLimitError, }); return { cursor: nextCursor, conversations, }; }, - /** - * Returns a mapping from user ID to user name for all users in the workspace - * - * @returns the mapping from user ID to user name - */ - async userNames() { + async userNameLookup(ids = [], throwRateLimitError = true, args = {}) { let cursor; const userNames = {}; do { @@ -513,15 +549,20 @@ export default { members: users, response_metadata: { next_cursor: nextCursor }, } = await this.usersList({ + limit: constants.LIMIT, cursor, + throwRateLimitError, + ...args, }); for (const user of users) { - userNames[user.id] = user.name; + if (ids.includes(user.id)) { + userNames[user.id] = user.name; + } } cursor = nextCursor; - } while (cursor); + } while (cursor && Object.keys(userNames).length < ids.length); return userNames; }, /** @@ -560,6 +601,7 @@ export default { }); }, authTeamsList(args = {}) { + args.limit ||= constants.LIMIT; return this.makeRequest({ method: "auth.teams.list", ...args, @@ -572,7 +614,7 @@ export default { * @param {string} [args.cursor] Pagination value e.g. (`dXNlcjpVMDYxTkZUVDI=`) * @param {boolean} [args.exclude_archived] Set to `true` to exclude archived channels * from the list. Defaults to `false` - * @param {number} [args.limit] Pagination value. Defaults to `0` + * @param {number} [args.limit] Pagination value. Defaults to `250` * @param {string} [args.team_id] Encoded team id to list users in, * required if org token is used * @param {string} [args.types] Mix and match channel types by providing a @@ -584,6 +626,7 @@ export default { * @returns Promise */ usersConversations(args = {}) { + args.limit ||= constants.LIMIT; return this.makeRequest({ method: "users.conversations", user: this.$auth.oauth_uid, @@ -603,7 +646,7 @@ export default { * @returns Promise */ usersList(args = {}) { - args.limit ||= 250; + args.limit ||= constants.LIMIT; return this.makeRequest({ method: "users.list", ...args, @@ -616,7 +659,7 @@ export default { * @param {string} [args.cursor] Pagination value e.g. (`dXNlcjpVMDYxTkZUVDI=`) * @param {boolean} [args.exclude_archived] Set to `true` to exclude archived channels * from the list. Defaults to `false` - * @param {number} [args.limit] pagination value. Defaults to `0` + * @param {number} [args.limit] pagination value. Defaults to `250` * @param {string} [args.team_id] encoded team id to list users in, * required if org token is used * @param {string} [args.types] Mix and match channel types by providing a @@ -625,6 +668,7 @@ export default { * @returns Promise */ conversationsList(args = {}) { + args.limit ||= constants.LIMIT; return this.makeRequest({ method: "conversations.list", ...args, @@ -644,6 +688,7 @@ export default { * @returns Promise */ conversationsHistory(args = {}) { + args.limit ||= constants.LIMIT; return this.makeRequest({ method: "conversations.history", ...args, @@ -686,7 +731,7 @@ export default { * User Scopes: `search:read` * @param {SearchMessagesArguments} args Arguments object * @param {string} args.query Search query - * @param {number} [args.count] Number of items to return per page. Default `20` + * @param {number} [args.count] Number of items to return per page. Default `250` * @param {string} [args.cursor] Use this when getting results with cursormark * pagination. For first call send `*` for subsequent calls, send the value of * `next_cursor` returned in the previous call's results @@ -699,6 +744,7 @@ export default { * @returns Promise */ searchMessages(args = {}) { + args.count ||= constants.LIMIT; return this.makeRequest({ method: "search.messages", ...args, @@ -725,14 +771,17 @@ export default { * @returns Promise */ reactionsList(args = {}) { + args.limit ||= constants.LIMIT; return this.makeRequest({ method: "reactions.list", ...args, }); }, - async getCustomEmojis() { + async getCustomEmojis(args = {}) { const resp = await this.sdk().emoji.list({ include_categories: true, + limit: constants.LIMIT, + ...args, }); const emojis = Object.keys(resp.emoji); @@ -741,5 +790,164 @@ export default { } return emojis; }, + listChannelMembers(args = {}) { + args.limit ||= constants.LIMIT; + return this.makeRequest({ + method: "conversations.members", + ...args, + }); + }, + listFiles(args = {}) { + args.count ||= constants.LIMIT; + return this.makeRequest({ + method: "files.list", + ...args, + }); + }, + listGroupMembers(args = {}) { + args.limit ||= constants.LIMIT; + return this.makeRequest({ + method: "usergroups.users.list", + ...args, + }); + }, + getFileInfo(args = {}) { + return this.makeRequest({ + method: "files.info", + ...args, + }); + }, + getUserProfile(args = {}) { + return this.makeRequest({ + method: "users.profile.get", + ...args, + }); + }, + getBotInfo(args = {}) { + return this.makeRequest({ + method: "bots.info", + ...args, + }); + }, + getTeamInfo(args = {}) { + return this.makeRequest({ + method: "team.info", + ...args, + }); + }, + getConversationReplies(args = {}) { + return this.makeRequest({ + method: "conversations.replies", + ...args, + }); + }, + addReactions(args = {}) { + return this.makeRequest({ + method: "reactions.add", + ...args, + }); + }, + postChatMessage(args = {}) { + return this.makeRequest({ + method: "chat.postMessage", + ...args, + }); + }, + archiveConversations(args = {}) { + return this.makeRequest({ + method: "conversations.archive", + ...args, + }); + }, + scheduleMessage(args = {}) { + return this.makeRequest({ + method: "chat.scheduleMessage", + ...args, + }); + }, + createConversations(args = {}) { + return this.makeRequest({ + method: "conversations.create", + ...args, + }); + }, + inviteToConversation(args = {}) { + return this.makeRequest({ + method: "conversations.invite", + ...args, + }); + }, + kickUserFromConversation(args = {}) { + return this.makeRequest({ + method: "conversations.kick", + ...args, + }); + }, + addReminders(args = {}) { + return this.makeRequest({ + method: "reminders.add", + ...args, + }); + }, + deleteFiles(args = {}) { + return this.makeRequest({ + method: "files.delete", + ...args, + }); + }, + deleteMessage(args = {}) { + return this.makeRequest({ + method: "chat.delete", + ...args, + }); + }, + lookupUserByEmail(args = {}) { + return this.makeRequest({ + method: "users.lookupByEmail", + ...args, + }); + }, + setChannelDescription(args = {}) { + return this.makeRequest({ + method: "conversations.setPurpose", + ...args, + }); + }, + setChannelTopic(args = {}) { + return this.makeRequest({ + method: "conversations.setTopic", + ...args, + }); + }, + updateProfile(args = {}) { + return this.makeRequest({ + method: "users.profile.set", + ...args, + }); + }, + updateGroupMembers(args = {}) { + return this.makeRequest({ + method: "usergroups.users.update", + ...args, + }); + }, + updateMessage(args = {}) { + return this.makeRequest({ + method: "chat.update", + ...args, + }); + }, + getUploadUrl(args = {}) { + return this.makeRequest({ + method: "files.getUploadURLExternal", + ...args, + }); + }, + completeUpload(args = {}) { + return this.makeRequest({ + method: "files.completeUploadExternal", + ...args, + }); + }, }, }; diff --git a/components/slack/sources/common/base.mjs b/components/slack/sources/common/base.mjs index 1f518ccc40baa..8207f3de8c6b9 100644 --- a/components/slack/sources/common/base.mjs +++ b/components/slack/sources/common/base.mjs @@ -85,7 +85,7 @@ export default { }, async getUserName(id) { return this.maybeCached(`users:${id}`, async () => { - const info = await this.slack.sdk().users.info({ + const info = await this.slack.usersInfo({ user: id, }); if (!info.ok) throw new Error(info.error); @@ -94,7 +94,7 @@ export default { }, async getRealName(id) { return this.maybeCached(`users_real_names:${id}`, async () => { - const info = await this.slack.sdk().users.info({ + const info = await this.slack.usersInfo({ user: id, }); if (!info.ok) throw new Error(info.error); @@ -103,7 +103,7 @@ export default { }, async getBotName(id) { return this.maybeCached(`bots:${id}`, async () => { - const info = await this.slack.sdk().bots.info({ + const info = await this.slack.getBotInfo({ bot: id, }); if (!info.ok) throw new Error(info.error); @@ -112,7 +112,7 @@ export default { }, async getConversationName(id) { return this.maybeCached(`conversations:${id}`, async () => { - const info = await this.slack.sdk().conversations.info({ + const info = await this.slack.conversationsInfo({ channel: id, }); if (!info.ok) throw new Error(info.error); @@ -125,7 +125,7 @@ export default { async getTeamName(id) { return this.maybeCached(`team:${id}`, async () => { try { - const info = await this.slack.sdk().team.info({ + const info = await this.slack.getTeamInfo({ team: id, }); return info.team.name; @@ -144,7 +144,7 @@ export default { return await this.maybeCached( `lastMessage:${channel}:${ts}`, async () => { - const response = await this.slack.sdk().conversations.replies({ + const response = await this.slack.sdk().getConversationReplies({ channel, ts, limit: 1, diff --git a/components/slack/sources/new-channel-created/new-channel-created.mjs b/components/slack/sources/new-channel-created/new-channel-created.mjs index 8d155271e68db..c71a16a586453 100644 --- a/components/slack/sources/new-channel-created/new-channel-created.mjs +++ b/components/slack/sources/new-channel-created/new-channel-created.mjs @@ -5,7 +5,7 @@ export default { ...common, key: "slack-new-channel-created", name: "New Channel Created (Instant)", - version: "0.0.8", + version: "0.0.9", description: "Emit new event when a new channel is created.", type: "source", dedupe: "unique", diff --git a/components/slack/sources/new-direct-message/new-direct-message.mjs b/components/slack/sources/new-direct-message/new-direct-message.mjs index fff5e35f0c0fe..b0eff2ca4e04e 100644 --- a/components/slack/sources/new-direct-message/new-direct-message.mjs +++ b/components/slack/sources/new-direct-message/new-direct-message.mjs @@ -5,7 +5,7 @@ export default { ...common, key: "slack-new-direct-message", name: "New Direct Message (Instant)", - version: "1.0.21", + version: "1.0.22", description: "Emit new event when a message was posted in a direct message channel", type: "source", dedupe: "unique", diff --git a/components/slack/sources/new-interaction-event-received/new-interaction-event-received.mjs b/components/slack/sources/new-interaction-event-received/new-interaction-event-received.mjs index 4b9ecc995867e..fb86d76847e98 100644 --- a/components/slack/sources/new-interaction-event-received/new-interaction-event-received.mjs +++ b/components/slack/sources/new-interaction-event-received/new-interaction-event-received.mjs @@ -3,7 +3,7 @@ import sampleEmit from "./test-event.mjs"; export default { name: "New Interaction Events (Instant)", - version: "0.0.18", + version: "0.0.19", key: "slack-new-interaction-event-received", description: "Emit new events on new Slack [interactivity events](https://api.slack.com/interactivity) sourced from [Block Kit interactive elements](https://api.slack.com/interactivity/components), [Slash commands](https://api.slack.com/interactivity/slash-commands), or [Shortcuts](https://api.slack.com/interactivity/shortcuts).", type: "source", diff --git a/components/slack/sources/new-keyword-mention/new-keyword-mention.mjs b/components/slack/sources/new-keyword-mention/new-keyword-mention.mjs index da8b56b1a0ed8..fd22554579d11 100644 --- a/components/slack/sources/new-keyword-mention/new-keyword-mention.mjs +++ b/components/slack/sources/new-keyword-mention/new-keyword-mention.mjs @@ -6,7 +6,7 @@ export default { ...common, key: "slack-new-keyword-mention", name: "New Keyword Mention (Instant)", - version: "0.0.6", + version: "0.0.7", description: "Emit new event when a specific keyword is mentioned in a channel", type: "source", dedupe: "unique", diff --git a/components/slack/sources/new-message-in-channels/new-message-in-channels.mjs b/components/slack/sources/new-message-in-channels/new-message-in-channels.mjs index 1ab6d48129082..e1aa0fea0cb73 100644 --- a/components/slack/sources/new-message-in-channels/new-message-in-channels.mjs +++ b/components/slack/sources/new-message-in-channels/new-message-in-channels.mjs @@ -6,7 +6,7 @@ export default { ...common, key: "slack-new-message-in-channels", name: "New Message In Channels (Instant)", - version: "1.0.23", + version: "1.0.24", description: "Emit new event when a new message is posted to one or more channels", type: "source", dedupe: "unique", diff --git a/components/slack/sources/new-reaction-added/new-reaction-added.mjs b/components/slack/sources/new-reaction-added/new-reaction-added.mjs index 6dd322c14a644..1f08165035279 100644 --- a/components/slack/sources/new-reaction-added/new-reaction-added.mjs +++ b/components/slack/sources/new-reaction-added/new-reaction-added.mjs @@ -5,7 +5,7 @@ export default { ...common, key: "slack-new-reaction-added", name: "New Reaction Added (Instant)", - version: "1.1.24", + version: "1.1.25", description: "Emit new event when a member has added an emoji reaction to a message", type: "source", dedupe: "unique", diff --git a/components/slack/sources/new-saved-message/new-saved-message.mjs b/components/slack/sources/new-saved-message/new-saved-message.mjs index 70126267892b3..8b077b82403cc 100644 --- a/components/slack/sources/new-saved-message/new-saved-message.mjs +++ b/components/slack/sources/new-saved-message/new-saved-message.mjs @@ -5,7 +5,7 @@ export default { ...common, key: "slack-new-saved-message", name: "New Saved Message (Instant)", - version: "0.0.4", + version: "0.0.5", description: "Emit new event when a message is saved. Note: The endpoint is marked as deprecated, and Slack might shut this off at some point down the line.", type: "source", dedupe: "unique", diff --git a/components/slack/sources/new-user-added/new-user-added.mjs b/components/slack/sources/new-user-added/new-user-added.mjs index 78f9f8cad3f51..427b230a83d68 100644 --- a/components/slack/sources/new-user-added/new-user-added.mjs +++ b/components/slack/sources/new-user-added/new-user-added.mjs @@ -5,7 +5,7 @@ export default { ...common, key: "slack-new-user-added", name: "New User Added (Instant)", - version: "0.0.2", + version: "0.0.3", description: "Emit new event when a new member joins a workspace.", type: "source", dedupe: "unique", diff --git a/components/slack/sources/new-user-mention/new-user-mention.mjs b/components/slack/sources/new-user-mention/new-user-mention.mjs index 369b92ba15a7a..0ed35c8583c13 100644 --- a/components/slack/sources/new-user-mention/new-user-mention.mjs +++ b/components/slack/sources/new-user-mention/new-user-mention.mjs @@ -6,7 +6,7 @@ export default { ...common, key: "slack-new-user-mention", name: "New User Mention (Instant)", - version: "0.0.6", + version: "0.0.7", description: "Emit new event when a username or specific keyword is mentioned in a channel", type: "source", dedupe: "unique", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e4c11cb38fdd9..4f4325f6fc5ff 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -421,8 +421,7 @@ importers: components/agentos: {} - components/agentql: - specifiers: {} + components/agentql: {} components/agenty: dependencies: @@ -4050,8 +4049,7 @@ importers: specifier: ^3.0.0 version: 3.0.3 - components/enginemailer: - specifiers: {} + components/enginemailer: {} components/enigma: {} @@ -11767,8 +11765,8 @@ importers: specifier: ^3.0.0 version: 3.0.3 '@slack/web-api': - specifier: ^7.0.4 - version: 7.7.0 + specifier: ^7.9.0 + version: 7.9.1 components/slack_bot: dependencies: @@ -19007,8 +19005,8 @@ packages: resolution: {integrity: sha512-tjQ8Zqv/Fmj9SOL9yIEd7IpTiKfKHi9DKAkfRVeotoX0clMr3SqQtBqO+KZMX27gm7dmgJsQaDKlILyzdCO+IA==} engines: {node: '>= 8.9.0', npm: '>= 5.5.1'} - '@slack/web-api@7.7.0': - resolution: {integrity: sha512-DtRyjgQi0mObA2uC6H8nL2OhAISKDhvtOXgRjGRBnBhiaWb6df5vPmKHsOHjpweYALBMHtiqE5ajZFkDW/ag8Q==} + '@slack/web-api@7.9.1': + resolution: {integrity: sha512-qMcb1oWw3Y/KlUIVJhkI8+NcQXq1lNymwf+ewk93ggZsGd6iuz9ObQsOEbvlqlx1J+wd8DmIm3DORGKs0fcKdg==} engines: {node: '>= 18', npm: '>= 8.6.0'} '@smiirl/smiirl-library-js@1.0.5': @@ -20399,6 +20397,9 @@ packages: axios@1.8.2: resolution: {integrity: sha512-ls4GYBm5aig9vWx8AWDSGLpnpDQRtWAfrjU+EuytuODrFBkqesN2RkOQCBzrA1RQNHw1SmRMSDDDSwzNAYQ6Rg==} + axios@1.8.4: + resolution: {integrity: sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==} + axobject-query@4.1.0: resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} engines: {node: '>= 0.4'} @@ -34318,6 +34319,8 @@ snapshots: '@putout/operator-filesystem': 5.0.0(putout@36.13.1(eslint@8.57.1)(typescript@5.6.3)) '@putout/operator-json': 2.2.0 putout: 36.13.1(eslint@8.57.1)(typescript@5.6.3) + transitivePeerDependencies: + - supports-color '@putout/operator-regexp@1.0.0(putout@36.13.1(eslint@8.57.1)(typescript@5.6.3))': dependencies: @@ -35228,13 +35231,13 @@ snapshots: transitivePeerDependencies: - debug - '@slack/web-api@7.7.0': + '@slack/web-api@7.9.1': dependencies: '@slack/logger': 4.0.0 '@slack/types': 2.14.0 '@types/node': 20.17.6 '@types/retry': 0.12.0 - axios: 1.7.7(debug@3.2.7) + axios: 1.8.4 eventemitter3: 5.0.1 form-data: 4.0.2 is-electron: 2.2.2 @@ -37118,6 +37121,14 @@ snapshots: transitivePeerDependencies: - debug + axios@1.8.4: + dependencies: + follow-redirects: 1.15.9(debug@3.2.7) + form-data: 4.0.2 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + axobject-query@4.1.0: {} b4a@1.6.7: {}