diff --git a/components/azure_cosmos_db/azure_cosmos_db.app.mjs b/components/azure_cosmos_db/azure_cosmos_db.app.mjs index 18b2c3a6feb6e..9bca1c2941cef 100644 --- a/components/azure_cosmos_db/azure_cosmos_db.app.mjs +++ b/components/azure_cosmos_db/azure_cosmos_db.app.mjs @@ -8,4 +8,4 @@ export default { console.log(Object.keys(this.$auth)); }, }, -}; \ No newline at end of file +}; diff --git a/components/binalyze_air/binalyze_air.app.mjs b/components/binalyze_air/binalyze_air.app.mjs index f9672fcd6915e..c76685631a381 100644 --- a/components/binalyze_air/binalyze_air.app.mjs +++ b/components/binalyze_air/binalyze_air.app.mjs @@ -8,4 +8,4 @@ export default { console.log(Object.keys(this.$auth)); }, }, -}; \ No newline at end of file +}; diff --git a/components/brainbase_labs/brainbase_labs.app.mjs b/components/brainbase_labs/brainbase_labs.app.mjs index c389f6f82b436..23cb29ded2a40 100644 --- a/components/brainbase_labs/brainbase_labs.app.mjs +++ b/components/brainbase_labs/brainbase_labs.app.mjs @@ -8,4 +8,4 @@ export default { console.log(Object.keys(this.$auth)); }, }, -}; \ No newline at end of file +}; diff --git a/components/google_perspective/google_perspective.app.mjs b/components/google_perspective/google_perspective.app.mjs index 5b343c8dfc547..2ef9ed80b5ac6 100644 --- a/components/google_perspective/google_perspective.app.mjs +++ b/components/google_perspective/google_perspective.app.mjs @@ -8,4 +8,4 @@ export default { console.log(Object.keys(this.$auth)); }, }, -}; \ No newline at end of file +}; diff --git a/components/n1n/n1n.app.mjs b/components/n1n/n1n.app.mjs index a6ba93bf24c41..57b8e6a82bc33 100644 --- a/components/n1n/n1n.app.mjs +++ b/components/n1n/n1n.app.mjs @@ -8,4 +8,4 @@ export default { console.log(Object.keys(this.$auth)); }, }, -}; \ No newline at end of file +}; 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 010ee53ed3e6c..86e55b66dbd53 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.16", + version: "0.0.17", annotations: { destructiveHint: false, openWorldHint: true, diff --git a/components/slack/actions/approve-workflow/approve-workflow.mjs b/components/slack/actions/approve-workflow/approve-workflow.mjs index fb8a147c59b85..3c2a5403bf9ad 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.5", + version: "0.0.6", annotations: { destructiveHint: false, openWorldHint: true, diff --git a/components/slack/actions/archive-channel/archive-channel.mjs b/components/slack/actions/archive-channel/archive-channel.mjs index 9ce69641c5627..2bf96a5aae7c7 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.24", + version: "0.0.25", annotations: { destructiveHint: true, openWorldHint: true, diff --git a/components/slack/actions/common/send-message.mjs b/components/slack/actions/common/send-message.mjs index ff923367dbdbb..37c1574a8196d 100644 --- a/components/slack/actions/common/send-message.mjs +++ b/components/slack/actions/common/send-message.mjs @@ -9,6 +9,12 @@ export default { "as_user", ], }, + addToChannel: { + propDefinition: [ + slack, + "addToChannel", + ], + }, post_at: { propDefinition: [ slack, @@ -181,6 +187,14 @@ export default { }, }, async run({ $ }) { + const channelId = await this.getChannelId(); + + if (this.addToChannel) { + await this.slack.maybeAddAppToChannels([ + channelId, + ]); + } + let blocks = this.blocks; if (!blocks) { @@ -216,7 +230,7 @@ export default { const obj = { text: this.text, - channel: await this.getChannelId(), + channel: channelId, attachments: this.attachments, unfurl_links: this.unfurl_links, unfurl_media: this.unfurl_media, @@ -241,15 +255,7 @@ export default { const { channel } = await this.slack.conversationsInfo({ channel: resp.channel, }); - let channelName = `#${channel?.name}`; - if (channel.is_im) { - const { profile } = await this.slack.getUserProfile({ - user: channel.user, - }); - channelName = `@${profile.real_name}`; - } else if (channel.is_mpim) { - channelName = `@${channel.purpose.value}`; - } + const channelName = await this.slack.getChannelDisplayName(channel); $.export("$summary", `Successfully sent a message to ${channelName}`); return resp; }, diff --git a/components/slack/actions/create-channel/create-channel.mjs b/components/slack/actions/create-channel/create-channel.mjs index d14ea45272547..79698261c6bb1 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.25", + version: "0.0.26", annotations: { destructiveHint: false, openWorldHint: true, diff --git a/components/slack/actions/create-reminder/create-reminder.mjs b/components/slack/actions/create-reminder/create-reminder.mjs index 7d3ce551d2ffc..44c00aed8045b 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.25", + version: "0.0.26", annotations: { destructiveHint: false, openWorldHint: true, diff --git a/components/slack/actions/delete-file/delete-file.mjs b/components/slack/actions/delete-file/delete-file.mjs index 0648c96c71ba5..5ef199841fb80 100644 --- a/components/slack/actions/delete-file/delete-file.mjs +++ b/components/slack/actions/delete-file/delete-file.mjs @@ -4,7 +4,7 @@ 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.24", + version: "0.0.25", annotations: { destructiveHint: true, openWorldHint: true, diff --git a/components/slack/actions/delete-message/delete-message.mjs b/components/slack/actions/delete-message/delete-message.mjs index 7dd9b92861992..6a3642bb64e41 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.24", + version: "0.1.0", annotations: { destructiveHint: true, openWorldHint: true, diff --git a/components/slack/actions/find-message/find-message.mjs b/components/slack/actions/find-message/find-message.mjs index 85d5bb317c9b2..89facad0a911b 100644 --- a/components/slack/actions/find-message/find-message.mjs +++ b/components/slack/actions/find-message/find-message.mjs @@ -3,8 +3,8 @@ import slack from "../../slack.app.mjs"; 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.26", + description: "Find a Slack message. [See the documentation](https://api.slack.com/methods/assistant.search.context)", + version: "0.1.0", annotations: { destructiveHint: false, openWorldHint: true, @@ -19,18 +19,11 @@ export default { "query", ], }, - teamId: { - propDefinition: [ - slack, - "team", - ], - optional: true, - }, maxResults: { type: "integer", label: "Max Results", description: "The maximum number of messages to return", - default: 100, + default: 20, optional: true, }, sort: { @@ -54,29 +47,161 @@ export default { optional: true, }, }, + methods: { + normalizeAssistantMatch(match) { + if (!match || typeof match !== "object") { + return match; + } + const { + author_user_id: authorUserId, + team_id: teamId, + channel_id: channelId, + message_ts: messageTs, + content, + permalink, + is_author_bot: isAuthorBot, + message, + channel, + ...rest + } = match; + const baseMessage = typeof message === "object" + ? message + : {}; + const channelInfo = channel && typeof channel === "object" + ? { + ...channel, + id: channel.id || channelId, + } + : channelId + ? { + id: channelId, + } + : undefined; + const normalized = { + type: "message", + user: authorUserId, + team: teamId, + ts: messageTs, + text: content, + permalink, + channel: channelInfo, + ...baseMessage, + ...rest, + }; + if (isAuthorBot !== undefined && normalized.is_author_bot === undefined) { + normalized.is_author_bot = isAuthorBot; + } + if (normalized.text == null) { + normalized.text = baseMessage.text || content; + } + if (normalized.ts == null) { + normalized.ts = baseMessage.ts || messageTs; + } + if (!normalized.channel && baseMessage.channel) { + normalized.channel = baseMessage.channel; + } else if (normalized.channel && baseMessage.channel && typeof baseMessage.channel === "object") { + normalized.channel = { + ...normalized.channel, + ...baseMessage.channel, + }; + } + return normalized; + }, + async searchWithAssistant(baseParams, maxResults) { + const matches = []; + let cursor; + + do { + const response = await this.slack.assistantSearch({ + ...baseParams, + channel_types: "public_channel,private_channel", + cursor, + }); + const messages = (response.results?.messages || []) + .map((item) => this.normalizeAssistantMatch(item)); + matches.push(...messages); + cursor = response.response_metadata?.next_cursor; + } while (cursor && matches.length < maxResults); + + return matches.slice(0, maxResults); + }, + async searchWithSearchMessages(baseParams, maxResults) { + const matches = []; + let page = 1; + const count = Math.min(Math.max(maxResults, 1), 100); + + while (matches.length < maxResults) { + const response = await this.slack.searchMessages({ + ...baseParams, + count, + page, + }); + const pageMatches = response.messages?.matches || []; + matches.push(...pageMatches); + + if (matches.length >= maxResults) { + break; + } + + const pagination = response.messages?.pagination; + const paging = response.messages?.paging; + const hasMore = pagination + ? pagination.page < pagination.page_count + : paging + ? paging.page < paging.pages + : false; + + if (!hasMore) { + break; + } + + page += 1; + } + + return matches.slice(0, maxResults); + }, + shouldFallbackToSearchMessages(error) { + const errorCode = typeof error === "string" + ? error + : error?.data?.error || error?.message; + + if (!errorCode.includes("missing_scope")) { + return false; + } + + const providedSources = [ + error?.data?.provided, + error?.provided, + error?.original?.data?.provided, + ].filter(Boolean); + + const providedScopes = providedSources + .flatMap((value) => Array.isArray(value) + ? value + : String(value).split(",")) + .map((scope) => scope.trim()) + .filter(Boolean); + + return providedScopes.includes("search:read"); + }, + }, async run({ $ }) { - const matches = []; - const params = { + const maxResults = Math.max(this.maxResults ?? 20, 1); + const baseParams = { query: this.query, - team_id: this.teamId, sort: this.sort, sort_dir: this.sortDirection, - page: 1, }; - let hasMore; + let matches; - do { - const { messages } = await this.slack.searchMessages(params); - matches.push(...messages.matches); - if (matches.length >= this.maxResults) { - break; + try { + matches = await this.searchWithAssistant(baseParams, maxResults); + } catch (error) { + if (this.shouldFallbackToSearchMessages(error)) { + matches = await this.searchWithSearchMessages(baseParams, maxResults); + } else { + throw error; } - hasMore = messages.matches?.length; - params.page++; - } while (hasMore); - - if (matches.length > this.maxResults) { - matches.length = this.maxResults; } $.export("$summary", `Found ${matches.length} matching message${matches.length === 1 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 cc12d5d439bf0..e1f35afe907ac 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.24", + version: "0.0.25", annotations: { destructiveHint: false, openWorldHint: true, diff --git a/components/slack/actions/get-file/get-file.mjs b/components/slack/actions/get-file/get-file.mjs index 9fc1afaa35b6a..601eb9528e7a5 100644 --- a/components/slack/actions/get-file/get-file.mjs +++ b/components/slack/actions/get-file/get-file.mjs @@ -1,10 +1,11 @@ +import constants from "../../common/constants.mjs"; import slack from "../../slack.app.mjs"; 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.24", + version: "0.1.0", annotations: { destructiveHint: false, openWorldHint: true, @@ -17,6 +18,19 @@ export default { propDefinition: [ slack, "conversation", + () => ({ + types: [ + constants.CHANNEL_TYPE.PUBLIC, + constants.CHANNEL_TYPE.PRIVATE, + ], + }), + ], + description: "Select a public or private channel", + }, + addToChannel: { + propDefinition: [ + slack, + "addToChannel", ], }, file: { @@ -30,6 +44,12 @@ export default { }, }, async run({ $ }) { + if (this.addToChannel) { + await this.slack.maybeAddAppToChannels([ + this.conversation, + ]); + } + const response = await this.slack.getFileInfo({ file: 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 4d2e8240a4ae3..28f08457fb2a2 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.24", + version: "0.0.25", annotations: { destructiveHint: false, openWorldHint: true, diff --git a/components/slack/actions/kick-user/kick-user.mjs b/components/slack/actions/kick-user/kick-user.mjs index eacd9d761f9a7..2a3cabc3696db 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.24", + version: "0.0.25", annotations: { destructiveHint: true, openWorldHint: true, diff --git a/components/slack/actions/list-channels/list-channels.mjs b/components/slack/actions/list-channels/list-channels.mjs index ef00493f71f77..27606438156ff 100644 --- a/components/slack/actions/list-channels/list-channels.mjs +++ b/components/slack/actions/list-channels/list-channels.mjs @@ -4,7 +4,7 @@ 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.24", + version: "0.0.25", annotations: { destructiveHint: false, openWorldHint: true, diff --git a/components/slack/actions/list-files/list-files.mjs b/components/slack/actions/list-files/list-files.mjs index 72881dd96edfb..48be1110dd452 100644 --- a/components/slack/actions/list-files/list-files.mjs +++ b/components/slack/actions/list-files/list-files.mjs @@ -1,10 +1,11 @@ +import constants from "../../common/constants.mjs"; import slack from "../../slack.app.mjs"; 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.52", + version: "0.1.0", annotations: { destructiveHint: false, openWorldHint: true, @@ -17,6 +18,19 @@ export default { propDefinition: [ slack, "conversation", + () => ({ + types: [ + constants.CHANNEL_TYPE.PUBLIC, + constants.CHANNEL_TYPE.PRIVATE, + ], + }), + ], + description: "Select a public or private channel", + }, + addToChannel: { + propDefinition: [ + slack, + "addToChannel", ], }, team_id: { @@ -47,6 +61,12 @@ export default { }, }, async run({ $ }) { + if (this.addToChannel) { + await this.slack.maybeAddAppToChannels([ + this.conversation, + ]); + } + const allFiles = []; const params = { channel: this.conversation, 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 a1ba13acdf935..0ff26898a734c 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.9", + version: "0.0.10", annotations: { destructiveHint: false, openWorldHint: true, 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 63981dcf5b29b..ff038cf536b26 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.24", + version: "0.0.25", annotations: { destructiveHint: false, openWorldHint: true, diff --git a/components/slack/actions/list-replies/list-replies.mjs b/components/slack/actions/list-replies/list-replies.mjs index 28cc4f750a0c6..413ac8aefddbc 100644 --- a/components/slack/actions/list-replies/list-replies.mjs +++ b/components/slack/actions/list-replies/list-replies.mjs @@ -1,10 +1,11 @@ +import constants from "../../common/constants.mjs"; import slack from "../../slack.app.mjs"; 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.24", + version: "0.0.25", annotations: { destructiveHint: false, openWorldHint: true, @@ -17,7 +18,14 @@ export default { propDefinition: [ slack, "conversation", + () => ({ + types: [ + constants.CHANNEL_TYPE.PUBLIC, + constants.CHANNEL_TYPE.PRIVATE, + ], + }), ], + description: "Select a public or private channel", }, timestamp: { propDefinition: [ diff --git a/components/slack/actions/list-users/list-users.mjs b/components/slack/actions/list-users/list-users.mjs index f4d7733cf7eb0..758d47f8f215e 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.24", + version: "0.0.25", annotations: { destructiveHint: false, openWorldHint: true, 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 6054fcd4efa19..167c1b081a690 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.29", + version: "0.2.0", annotations: { destructiveHint: false, openWorldHint: true, 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 f78c9489ce809..7fa53d5fc6559 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.5", + version: "0.5.0", annotations: { destructiveHint: false, openWorldHint: true, 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 9d0ee386a6dd5..474230475d486 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.24", + version: "0.1.0", annotations: { destructiveHint: false, openWorldHint: true, @@ -35,6 +35,12 @@ export default { ...common.props, }, async run({ $ }) { + if (this.addToChannel) { + await this.slack.maybeAddAppToChannels([ + this.conversation, + ]); + } + if (this.include_sent_via_pipedream_flag) { const sentViaPipedreamText = this._makeSentViaPipedreamBlock(); this.text += `\n\n\n${sentViaPipedreamText.elements[0].text}`; @@ -79,19 +85,10 @@ export default { } else { response = await this.slack.postChatMessage(obj); } - const { channel } = await this.slack.conversationsInfo({ channel: response.channel, }); - let channelName = `#${channel?.name}`; - if (channel.is_im) { - const { profile } = await this.slack.getUserProfile({ - user: channel.user, - }); - channelName = `@${profile.real_name}`; - } else if (channel.is_mpim) { - channelName = `@${channel.purpose.value}`; - } + const channelName = await this.slack.getChannelDisplayName(channel); $.export("$summary", `Successfully sent a message to ${channelName}`); return response; }, 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 ad2d604633db7..6b8df73332ac4 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.7", + version: "0.1.0", annotations: { destructiveHint: false, openWorldHint: true, 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 55d1119349614..ac00b08c5e5b8 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.5", + version: "0.1.0", annotations: { destructiveHint: false, openWorldHint: true, 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 ecbf1965e6077..60834909dec8a 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.5", + version: "0.1.0", annotations: { destructiveHint: false, openWorldHint: true, @@ -52,6 +52,13 @@ export default { ], }, ...common.props, + // eslint-disable-next-line pipedream/props-label, pipedream/props-description + addToChannel: { + type: "boolean", + ...common.props.addToChannel, + disabled: true, + hidden: true, + }, }, methods: { ...common.methods, diff --git a/components/slack/actions/send-message/send-message.mjs b/components/slack/actions/send-message/send-message.mjs index 06dc22d8b7f7a..e8a67df460932 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.20", + version: "0.1.0", annotations: { destructiveHint: false, openWorldHint: true, 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 7a544b28c6362..7567d090efd75 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.9", + version: "0.0.10", annotations: { destructiveHint: false, openWorldHint: true, 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 9f12041184de0..fa7a5b50de83a 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.24", + version: "0.0.25", annotations: { destructiveHint: true, openWorldHint: true, diff --git a/components/slack/actions/set-status/set-status.mjs b/components/slack/actions/set-status/set-status.mjs index 10f0069f743fd..954317d4f9487 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.9", + version: "0.0.10", annotations: { destructiveHint: true, openWorldHint: true, 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 fdb927619b3ac..79b78ca6b1a0c 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.9", + version: "0.0.10", annotations: { destructiveHint: true, openWorldHint: true, @@ -51,8 +51,8 @@ export default { async run({ $ }) { const { userGroup, - usersToAdd, - usersToRemove, + usersToAdd = [], + usersToRemove = [], team, } = this; let { users } = await this.slack.listGroupMembers({ diff --git a/components/slack/actions/update-message/update-message.mjs b/components/slack/actions/update-message/update-message.mjs index 4f797ffabb3af..7ff12d7b56427 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.24", + version: "0.2.0", annotations: { destructiveHint: true, openWorldHint: true, diff --git a/components/slack/actions/update-profile/update-profile.mjs b/components/slack/actions/update-profile/update-profile.mjs index e3c871d7d0246..270bc6f78474b 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.24", + version: "0.0.25", annotations: { destructiveHint: true, openWorldHint: true, diff --git a/components/slack/actions/upload-file/upload-file.mjs b/components/slack/actions/upload-file/upload-file.mjs index 56240f1c4b169..ddc1926d77a8b 100644 --- a/components/slack/actions/upload-file/upload-file.mjs +++ b/components/slack/actions/upload-file/upload-file.mjs @@ -8,7 +8,7 @@ export default { key: "slack-upload-file", name: "Upload File", description: "Upload a file. [See the documentation](https://api.slack.com/messaging/files#uploading_files)", - version: "0.1.2", + version: "0.1.3", annotations: { destructiveHint: false, openWorldHint: true, diff --git a/components/slack/actions/verify-slack-signature/verify-slack-signature.mjs b/components/slack/actions/verify-slack-signature/verify-slack-signature.mjs deleted file mode 100644 index 15997e6d2c906..0000000000000 --- a/components/slack/actions/verify-slack-signature/verify-slack-signature.mjs +++ /dev/null @@ -1,65 +0,0 @@ -import crypto from "crypto"; -import slack from "../../slack.app.mjs"; - -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.17", - annotations: { - destructiveHint: false, - openWorldHint: true, - readOnlyHint: true, - }, - type: "action", - props: { - slack, - slackSigningSecret: { - type: "string", - label: "Signing Secret", - description: "Slack [Signing Secret](https://api.slack.com/authentication/verifying-requests-from-slack#:~:text=Slack%20Signing%20Secret%2C%20available%20in%20the%20app%20admin%20panel%20under%20Basic%20Info.), available in the app admin panel under Basic Info.", - secret: true, - }, - slackSignature: { - type: "string", - label: "X-Slack-Signature", - description: "Slack signature (from X-Slack-Signature header).", - }, - slackRequestTimestamp: { - type: "string", - label: "X-Slack-Request-Timestamp", - description: "Slack request timestamp (from X-Slack-Request-Timestamp header).", - }, - requestBody: { - type: "any", - label: "Request Body", - description: "The body of the request to be verified.", - }, - }, - async run({ $ }) { - const { - slackSignature, - slackRequestTimestamp, - requestBody, - slackSigningSecret, - } = this; - const requestBodyStr = typeof (requestBody) === "string" ? - requestBody : - JSON.stringify(requestBody); - const sigBaseString = `v0:${slackRequestTimestamp}:${requestBodyStr}`; - const sha256Hex = crypto.createHmac("sha256", slackSigningSecret) - .update(sigBaseString, "utf8") - .digest("hex"); - const mySignature = `v0=${sha256Hex}`; - if (crypto.timingSafeEqual(Buffer.from(mySignature, "utf8"), Buffer.from(slackSignature, "utf8"))) { - $.export("$summary", `Successfully verified the request with "${slackSignature}" signature`); - return { - success: true, - }; - } - $.export("$summary", "Slack signature mismatch with provided properties, it may be a configuration issue."); - return { - success: false, - }; - }, -}; diff --git a/components/slack/package.json b/components/slack/package.json index 1c5aae17dca63..2e1c6cf76a6dc 100644 --- a/components/slack/package.json +++ b/components/slack/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/slack", - "version": "0.10.2", + "version": "0.11.0", "description": "Pipedream Slack Components", "main": "slack.app.mjs", "keywords": [ diff --git a/components/slack/slack.app.mjs b/components/slack/slack.app.mjs index 401d853f0f6cb..670ba2731c5da 100644 --- a/components/slack/slack.app.mjs +++ b/components/slack/slack.app.mjs @@ -2,6 +2,7 @@ import { WebClient } from "@slack/web-api"; import constants from "./common/constants.mjs"; import get from "lodash/get.js"; import retry from "async-retry"; +import { ConfigurationError } from "@pipedream/platform"; export default { type: "app", @@ -27,11 +28,11 @@ export default { 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); + const userIds = conversationsResp.conversations.map(({ user }) => user).filter(Boolean); + const realNames = await this.realNameLookup(userIds); return { - options: conversationsResp.conversations.map((c) => ({ - label: `@${userNames[c.user]}`, + options: conversationsResp.conversations.filter((c) => c.user).map((c) => ({ + label: `${realNames[c.user]}`, value: c.user || c.id, })), context: { @@ -120,24 +121,41 @@ export default { } } const conversationsResp = await this.availableConversations(types.join(), cursor, true); - let conversations, userNames; + let conversations, userIds, userNames, realNames; if (types.includes("im")) { conversations = conversationsResp.conversations; - const userIds = conversations.map(({ user }) => user); - userNames = await this.userNameLookup(userIds); + userIds = conversations.map(({ user }) => user).filter(Boolean); } else { conversations = conversationsResp.conversations.filter((c) => !c.is_im); } + if (types.includes("mpim")) { + userNames = [ + ...new Set(conversations.filter((c) => c.is_mpim).map((c) => c.purpose.value) + .map((v) => v.match(/@[\w.-]+/g) || []) + .flat() + .map((u) => u.slice(1))), + ]; + } + if ((userIds?.length > 0) || (userNames?.length > 0)) { + // Look up real names for userIds and userNames at the same time to + // minimize number of API calls. + realNames = await this.realNameLookup(userIds, userNames); + } + return { options: conversations.map((c) => { if (c.is_im) { return { - label: `Direct messaging with: @${userNames[c.user]}`, + label: `Direct messaging with: ${realNames[c.user]}`, value: c.id, }; } else if (c.is_mpim) { + const usernames = c.purpose.value.match(/@[\w.-]+/g) || []; + const realnames = usernames.map((u) => realNames[u.slice(1)] || u); return { - label: c.purpose.value, + label: realnames.length + ? `Group messaging with: ${realnames.join(", ")}` + : c.purpose.value, value: c.id, }; } else { @@ -447,6 +465,12 @@ export default { default: 1, optional: true, }, + addToChannel: { + type: "boolean", + label: "Add app to channel automatically?", + description: "If `true`, the app will be added to the specified non-DM channel(s) automatically. If `false`, you must add the app to the channel manually. Defaults to `true`.", + default: true, + }, }, methods: { getChannelLabel(resource) { @@ -464,29 +488,89 @@ export default { mySlackId() { return this.$auth.oauth_uid; }, - getToken() { - return this.$auth.oauth_access_token; + getToken(opts = {}) { + // Use bot token if asBot is true and available, otherwise use user token. + const botToken = this.getBotToken(); + const userToken = this.$auth.oauth_access_token; + return (opts.asBot && botToken) + ? botToken + : userToken; + }, + getBotToken() { + return this.$auth.bot_token; + }, + async getChannelDisplayName(channel) { + if (channel.user) { + try { + const { profile } = await this.getUserProfile({ + user: channel.user, + }); + return `@${profile.real_name || profile?.real_name}`; + } catch { + return "user"; + } + } else if (channel.is_mpim) { + try { + const { members } = await this.listChannelMembers({ + channel: channel.id, + }); + const users = await Promise.all(members.map((m) => this.getUserProfile({ + user: m, + }))); + const realNames = users.map((u) => u.profile?.real_name || u.real_name); + return `Group Messaging with: ${realNames.join(", ")}`; + } catch { + return `Group Messaging with: ${channel.purpose.value}`; + } + } + return `#${channel?.name}`; }, /** * Returns a Slack Web Client object authenticated with the user's access * token */ - sdk() { - return new WebClient(this.getToken(), { + sdk(opts = {}) { + return new WebClient(this.getToken(opts), { rejectRateLimitedCalls: true, + slackApiUrl: this.$auth.base_url, }); }, async makeRequest({ - method = "", throwRateLimitError = false, ...args + method = "", throwRateLimitError = false, asBot, as_user, ...args } = {}) { + // Passing as_user as false with a v2 user token lacking the deprecated + // `chat:write:bot` scope results in an error. If as_user is false and a + // bot token is available, use the bot token and omit as_user. Otherwise, + // pass as_user through. + if (as_user === false && Boolean(this.getBotToken())) { + asBot = true; + } else { + args.as_user = as_user; + } + const props = method.split("."); const sdk = props.reduce((reduction, prop) => - reduction[prop], this.sdk()); + reduction[prop], this.sdk({ + asBot, + })); - const response = await this._withRetries(() => sdk(args), throwRateLimitError); + let response; + try { + response = await this._withRetries(() => sdk(args), throwRateLimitError); + } catch (error) { + if ([ + "not_in_channel", + "channel_not_found", + ].some((errorType) => error.includes(errorType)) && asBot) { + const followUp = method.startsWith("chat.") + ? "Ensure the bot is a member of the channel, or set the **Send as User** option to true to act on behalf of the authenticated user." + : "Ensure the bot is a member of the channel."; + throw new ConfigurationError(`${error}\n${followUp}`); + } + throw error; + } if (!response.ok) { - console.log(`Error in response with method ${method}`, response.error); throw response.error; } return response; @@ -565,6 +649,64 @@ export default { } while (cursor && Object.keys(userNames).length < ids.length); return userNames; }, + async realNameLookup(ids = [], usernames = [], throwRateLimitError = true, args = {}) { + let cursor; + const realNames = {}; + do { + const { + members: users, + response_metadata: { next_cursor: nextCursor }, + } = await this.usersList({ + limit: constants.LIMIT, + cursor, + throwRateLimitError, + ...args, + }); + + for (const user of users) { + if (ids.includes(user.id)) { + realNames[user.id] = user.profile.real_name; + } + if (usernames.includes(user.name)) { + realNames[user.name] = user.profile.real_name; + } + } + + cursor = nextCursor; + } while (cursor && Object.keys(realNames).length < (ids.length + usernames.length)); + return realNames; + }, + async maybeAddAppToChannels(channelIds = []) { + if (!this.getBotToken()) { + console.log("Skipping adding app to channels: bot unavailable."); + return; + } + try { + const { + bot_id, user_id, + } = await this.authTest({ + asBot: true, + }); + if (!bot_id) { + console.log("Skipping adding app to channels: bot not found."); + return; + } + for (const channel of channelIds) { + try { + // Note: Trying to add the app to DM or group DM channels results in + // the error: method_not_supported_for_channel_type + await this.inviteToConversation({ + channel, + users: user_id, + }); + } catch (error) { + console.log(`Unable to add app to channel ${channel}: ${error}`); + } + } + } catch (error) { + console.log(`Unable to add app to channels: ${error}`); + } + }, /** * Checks authentication & identity. * @param {*} args Arguments object @@ -750,6 +892,12 @@ export default { ...args, }); }, + assistantSearch(args = {}) { + args.count ||= constants.LIMIT; + return this.sdk().apiCall("assistant.search.context", { + ...args, + }); + }, /** * Lists reactions made by a user. * User Scopes: `reactions:read` @@ -801,6 +949,9 @@ export default { args.count ||= constants.LIMIT; return this.makeRequest({ method: "files.list", + // Use bot token, if available, since the required `files:read` scope + // is only requested for bot tokens in the Pipedream app. + asBot: true, ...args, }); }, @@ -814,6 +965,9 @@ export default { getFileInfo(args = {}) { return this.makeRequest({ method: "files.info", + // Use bot token, if available, since the required `files:read` scope + // is only requested for bot tokens in the Pipedream app. + asBot: true, ...args, }); }, 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 7eb2ff9085f4a..9d1df1076dc05 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.10", + version: "0.0.11", 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 deleted file mode 100644 index 389c183951a5d..0000000000000 --- a/components/slack/sources/new-direct-message/new-direct-message.mjs +++ /dev/null @@ -1,53 +0,0 @@ -import common from "../common/base.mjs"; -import sampleEmit from "./test-event.mjs"; - -export default { - ...common, - key: "slack-new-direct-message", - name: "New Direct Message (Instant)", - version: "1.0.23", - description: "Emit new event when a message was posted in a direct message channel", - type: "source", - dedupe: "unique", - props: { - ...common.props, - // eslint-disable-next-line pipedream/props-description,pipedream/props-label - slackApphook: { - type: "$.interface.apphook", - appProp: "slack", - async eventNames() { - return [ - "message.im", - ]; - }, - }, - ignoreBot: { - propDefinition: [ - common.props.slack, - "ignoreBot", - ], - }, - ignoreSelf: { - type: "boolean", - label: "Ignore Messages from Yourself", - description: "Ignores messages sent to yourself", - default: false, - optional: true, - }, - }, - methods: { - ...common.methods, - getSummary() { - return "New direct message received"; - }, - processEvent(event) { - if ((this.ignoreSelf && event.user == this.slack.mySlackId()) - || ((this.ignoreBot) && (event.subtype === "bot_message" || event.bot_id)) - || (event.subtype === "message_changed")) { - return; - } - return event; - }, - }, - sampleEmit, -}; diff --git a/components/slack/sources/new-direct-message/test-event.mjs b/components/slack/sources/new-direct-message/test-event.mjs deleted file mode 100644 index d19486ed235f0..0000000000000 --- a/components/slack/sources/new-direct-message/test-event.mjs +++ /dev/null @@ -1,28 +0,0 @@ -export default { - "user": "USLACKBOT", - "type": "message", - "ts": "1716401124.947359", - "text": "Feeling great!", - "team": "TS8319547", - "blocks": [ - { - "type": "rich_text", - "block_id": "bid/", - "elements": [ - { - "type": "rich_text_section", - "elements": [ - { - "type": "text", - "text": "Feeling great!" - } - ] - } - ] - } - ], - "channel": "DS676Q73J", - "event_ts": "1716401124.947359", - "channel_type": "im", - "pipedream_msg_id": "pd_1716401126905_tjxu6josgz" -} \ No newline at end of file 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 75b100e999b45..4ec49f2be9653 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.20", + version: "0.0.21", 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 567abdb4806a8..c6323e562670e 100644 --- a/components/slack/sources/new-keyword-mention/new-keyword-mention.mjs +++ b/components/slack/sources/new-keyword-mention/new-keyword-mention.mjs @@ -1,12 +1,13 @@ import common from "../common/base.mjs"; import constants from "../common/constants.mjs"; import sampleEmit from "./test-event.mjs"; +import sharedConstants from "../../common/constants.mjs"; export default { ...common, key: "slack-new-keyword-mention", name: "New Keyword Mention (Instant)", - version: "0.0.8", + version: "0.1.0", description: "Emit new event when a specific keyword is mentioned in a channel", type: "source", dedupe: "unique", @@ -16,6 +17,12 @@ export default { propDefinition: [ common.props.slack, "conversation", + () => ({ + types: [ + sharedConstants.CHANNEL_TYPE.PUBLIC, + sharedConstants.CHANNEL_TYPE.PRIVATE, + ], + }), ], type: "string[]", label: "Channels", @@ -45,45 +52,8 @@ export default { ], }, }, - hooks: { - ...common.hooks, - async deploy() { - // emit historical events - const messages = await this.getMatches({ - query: this.keyword, - sort: "timestamp", - }); - const filteredMessages = this.conversations?.length > 0 - ? messages.filter((message) => this.conversations.includes(message.channel.id)) - : messages; - await this.emitHistoricalEvents(filteredMessages.slice(-25).reverse()); - }, - }, methods: { ...common.methods, - async getMatches(params) { - return (await this.slack.searchMessages(params)).messages.matches || []; - }, - async emitHistoricalEvents(messages) { - for (const message of messages) { - const event = await this.processEvent({ - ...message, - subtype: message.subtype || constants.SUBTYPE.PD_HISTORY_MESSAGE, - }); - if (event) { - if (!event.client_msg_id) { - event.pipedream_msg_id = `pd_${Date.now()}_${Math.random().toString(36) - .substr(2, 10)}`; - } - - this.$emit(event, { - id: event.client_msg_id || event.pipedream_msg_id, - summary: this.getSummary(event), - ts: event.event_ts || Date.now(), - }); - } - } - }, getSummary() { return "New keyword mention received"; }, 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 0de59c7a78749..72c9ef83bb751 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 @@ -1,12 +1,13 @@ import common from "../common/base.mjs"; import constants from "../common/constants.mjs"; import sampleEmit from "./test-event.mjs"; +import sharedConstants from "../../common/constants.mjs"; export default { ...common, key: "slack-new-message-in-channels", name: "New Message In Channels (Instant)", - version: "1.0.25", + version: "1.1.0", description: "Emit new event when a new message is posted to one or more channels", type: "source", dedupe: "unique", @@ -16,6 +17,12 @@ export default { propDefinition: [ common.props.slack, "conversation", + () => ({ + types: [ + sharedConstants.CHANNEL_TYPE.PUBLIC, + sharedConstants.CHANNEL_TYPE.PRIVATE, + ], + }), ], type: "string[]", label: "Channels", 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 6444e3fd9b57b..aaf4edf973db0 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.26", + version: "1.2.0", description: "Emit new event when a member has added an emoji reaction to a message", type: "source", dedupe: "unique", @@ -97,10 +97,14 @@ export default { event.itemUserInfo = itemUserResponse.user; } - event.message = await this.getMessage({ - channel: event.item.channel, - event_ts: event.item.ts, - }); + try { + event.message = await this.getMessage({ + channel: event.item.channel, + event_ts: event.item.ts, + }); + } catch (err) { + console.log("Error fetching message:", err); + } return event; }, 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 fe0f907aabf84..2d7a94e5c5b95 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.6", + version: "0.0.7", 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 80bde255eb668..03db742683377 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.4", + version: "0.0.5", 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 5f4371d84f6dc..15efc422c870d 100644 --- a/components/slack/sources/new-user-mention/new-user-mention.mjs +++ b/components/slack/sources/new-user-mention/new-user-mention.mjs @@ -1,12 +1,13 @@ import common from "../common/base.mjs"; import constants from "../common/constants.mjs"; import sampleEmit from "./test-event.mjs"; +import sharedConstants from "../../common/constants.mjs"; export default { ...common, key: "slack-new-user-mention", name: "New User Mention (Instant)", - version: "0.0.8", + version: "0.1.0", description: "Emit new event when a username or specific keyword is mentioned in a channel", type: "source", dedupe: "unique", @@ -16,6 +17,12 @@ export default { propDefinition: [ common.props.slack, "conversation", + () => ({ + types: [ + sharedConstants.CHANNEL_TYPE.PUBLIC, + sharedConstants.CHANNEL_TYPE.PRIVATE, + ], + }), ], type: "string[]", label: "Channels",