@pipedream/slack_v2 0.8.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/actions/add-emoji-reaction/add-emoji-reaction.mjs +2 -2
  2. package/actions/add-reaction/add-reaction.mjs +1 -1
  3. package/actions/archive-channel/archive-channel.mjs +3 -10
  4. package/actions/browse-files/browse-files.mjs +1 -1
  5. package/actions/common/build-blocks.mjs +44 -106
  6. package/actions/common/send-message.mjs +5 -59
  7. package/actions/create-channel/create-channel.mjs +2 -1
  8. package/actions/create-reminder/create-reminder.mjs +2 -1
  9. package/actions/delete-file/delete-file.mjs +2 -4
  10. package/actions/delete-message/delete-message.mjs +7 -6
  11. package/actions/edit-message/edit-message.mjs +20 -2
  12. package/actions/find-message/find-message.mjs +15 -3
  13. package/actions/find-user-by-email/find-user-by-email.mjs +2 -1
  14. package/actions/find-user-by-id/find-user-by-id.mjs +4 -3
  15. package/actions/get-channel-details/get-channel-details.mjs +3 -2
  16. package/actions/get-channel-history/get-channel-history.mjs +3 -3
  17. package/actions/get-current-user/get-current-user.mjs +3 -2
  18. package/actions/get-file/get-file.mjs +2 -12
  19. package/actions/get-thread-replies/get-thread-replies.mjs +1 -1
  20. package/actions/get-user-details/get-user-details.mjs +1 -1
  21. package/actions/invite-user-to-channel/invite-user-to-channel.mjs +2 -1
  22. package/actions/kick-user/kick-user.mjs +2 -12
  23. package/actions/list-channels/list-channels.mjs +28 -10
  24. package/actions/list-emojis/list-emojis.mjs +2 -1
  25. package/actions/list-files/list-files.mjs +6 -11
  26. package/actions/list-group-conversations/list-group-conversations.mjs +86 -0
  27. package/actions/list-group-members/list-group-members.mjs +3 -2
  28. package/actions/list-icon-emoji-options/list-icon-emoji-options.mjs +6 -3
  29. package/actions/list-members-in-channel/list-members-in-channel.mjs +2 -1
  30. package/actions/list-messages/list-messages.mjs +2 -1
  31. package/actions/list-reminder-options/list-reminder-options.mjs +10 -3
  32. package/actions/list-replies/list-replies.mjs +2 -9
  33. package/actions/list-teams/list-teams.mjs +88 -0
  34. package/actions/list-user-group-options/list-user-group-options.mjs +10 -3
  35. package/actions/list-users/list-users.mjs +2 -1
  36. package/actions/post-message/post-message.mjs +30 -4
  37. package/actions/reply-to-a-message/reply-to-a-message.mjs +13 -12
  38. package/actions/search/search.mjs +7 -2
  39. package/actions/send-block-kit-message/send-block-kit-message.mjs +2 -1
  40. package/actions/send-large-message/send-large-message.mjs +2 -1
  41. package/actions/send-message/send-message.mjs +5 -15
  42. package/actions/send-message-advanced/send-message-advanced.mjs +46 -4
  43. package/actions/send-message-to-channel/send-message-to-channel.mjs +10 -10
  44. package/actions/send-message-to-user-or-group/send-message-to-user-or-group.mjs +4 -9
  45. package/actions/set-channel-description/set-channel-description.mjs +2 -1
  46. package/actions/set-channel-topic/set-channel-topic.mjs +2 -1
  47. package/actions/set-status/set-status.mjs +4 -3
  48. package/actions/update-group-members/update-group-members.mjs +5 -4
  49. package/actions/update-message/update-message.mjs +3 -2
  50. package/actions/update-profile/update-profile.mjs +3 -2
  51. package/actions/upload-file/upload-file.mjs +7 -2
  52. package/actions/verify-slack-signature/verify-slack-signature.mjs +4 -3
  53. package/common/constants.mjs +16 -0
  54. package/common/utils.mjs +81 -1
  55. package/package.json +2 -2
  56. package/slack_v2.app.mjs +21 -370
  57. package/sources/new-channel-created/new-channel-created.mjs +1 -1
  58. package/sources/new-interaction-event-received/new-interaction-event-received.mjs +1 -1
  59. package/sources/new-keyword-mention/new-keyword-mention.mjs +1 -1
  60. package/sources/new-message-in-channels/new-message-in-channels.mjs +1 -1
  61. package/sources/new-private-channel-created/new-private-channel-created.mjs +1 -1
  62. package/sources/new-reaction-added/new-reaction-added.mjs +1 -1
  63. package/sources/new-saved-message/new-saved-message.mjs +1 -1
  64. package/sources/new-user-added/new-user-added.mjs +1 -1
  65. package/sources/new-user-mention/new-user-mention.mjs +1 -1
@@ -1,10 +1,11 @@
1
+ // x-pd-ai: optimized
1
2
  import slack from "../../slack_v2.app.mjs";
2
3
 
3
4
  export default {
4
5
  key: "slack_v2-add-emoji-reaction",
5
6
  name: "Add Emoji Reaction",
6
7
  description: "Add an emoji reaction to a message. [See the documentation](https://api.slack.com/methods/reactions.add)",
7
- version: "0.0.23",
8
+ version: "0.0.25",
8
9
  annotations: {
9
10
  destructiveHint: false,
10
11
  openWorldHint: true,
@@ -18,7 +19,6 @@ export default {
18
19
  slack,
19
20
  "conversation",
20
21
  ],
21
- description: "Channel where the message to add reaction to was posted.",
22
22
  },
23
23
  timestamp: {
24
24
  propDefinition: [
@@ -10,7 +10,7 @@ export default {
10
10
  + " Use **Get Channel History** or **Search** to find the message timestamp."
11
11
  + " Emoji name should be without colons (e.g. `thumbsup`, `fire`, `heart`)."
12
12
  + " [See the documentation](https://api.slack.com/methods/reactions.add)",
13
- version: "0.0.3",
13
+ version: "0.0.5",
14
14
  type: "action",
15
15
  annotations: {
16
16
  destructiveHint: false,
@@ -1,11 +1,11 @@
1
+ // x-pd-ai: optimized
1
2
  import slack from "../../slack_v2.app.mjs";
2
- import constants from "../../common/constants.mjs";
3
3
 
4
4
  export default {
5
5
  key: "slack_v2-archive-channel",
6
6
  name: "Archive Channel",
7
- description: "Archive a channel. [See the documentation](https://api.slack.com/methods/conversations.archive)",
8
- version: "0.0.31",
7
+ description: "Archive a public or private channel. Direct messages and group DMs can't be archived — pass a channel ID (e.g. `C1234567890`), not a user or group ID. [See the documentation](https://api.slack.com/methods/conversations.archive)",
8
+ version: "0.0.33",
9
9
  annotations: {
10
10
  destructiveHint: true,
11
11
  openWorldHint: true,
@@ -18,13 +18,6 @@ export default {
18
18
  propDefinition: [
19
19
  slack,
20
20
  "conversation",
21
- () => ({
22
- types: [
23
- constants.CHANNEL_TYPE.PUBLIC,
24
- constants.CHANNEL_TYPE.PRIVATE,
25
- constants.CHANNEL_TYPE.MPIM,
26
- ],
27
- }),
28
21
  ],
29
22
  },
30
23
  },
@@ -10,7 +10,7 @@ export default {
10
10
  + " Filter by file type (e.g. `images`, `pdfs`, `snippets`)."
11
11
  + " Returns file metadata including name, type, size, and download URL."
12
12
  + " [See the documentation](https://api.slack.com/methods/files.list)",
13
- version: "0.0.3",
13
+ version: "0.0.5",
14
14
  type: "action",
15
15
  annotations: {
16
16
  destructiveHint: false,
@@ -1,4 +1,26 @@
1
1
  import common from "./send-message.mjs";
2
+ import constants from "../../common/constants.mjs";
3
+
4
+ const SECTION_DESCRIPTION = "Add a **section** block to your message and configure with plain text or mrkdwn. See [Slack's docs](https://api.slack.com/reference/block-kit/blocks?ref=bk#section) for more info.";
5
+ const CONTEXT_DESCRIPTION = "Add a **context** block to your message and configure with plain text or mrkdwn. Define multiple items if you'd like multiple elements in the context block. See [Slack's docs](https://api.slack.com/reference/block-kit/blocks?ref=bk#context) for more info.";
6
+ const LINK_BUTTON_DESCRIPTION = "Add a **link button** to your message. Enter the button text as the key and the link URL as the value. Example: `{\"View docs\": \"https://example.com\", \"Open dashboard\": \"https://app.example.com\"}`. Configure multiple buttons in the object to render them inline, or add additional Link Button blocks to render them vertically. See [Slack's docs](https://api.slack.com/reference/block-kit/blocks?ref=bk#actions) for more info.";
7
+
8
+ const MAX_BLOCKS = 5;
9
+
10
+ const buildIndexedProps = (prefix, label, type, description) =>
11
+ Object.fromEntries(
12
+ Array.from({
13
+ length: MAX_BLOCKS,
14
+ }, (_, i) => [
15
+ `${prefix}${i + 1}`,
16
+ {
17
+ type,
18
+ label: `${label} ${i + 1}`,
19
+ description,
20
+ optional: true,
21
+ },
22
+ ]),
23
+ );
2
24
 
3
25
  export default {
4
26
  props: {
@@ -9,35 +31,28 @@ export default {
9
31
  options: [
10
32
  {
11
33
  label: "Reference an array of blocks",
12
- value: "array",
34
+ value: constants.PASS_ARRAY_OR_CONFIGURE_OPTIONS.ARRAY,
13
35
  },
14
36
  {
15
- label: "Configure blocks individually (maximum 5 blocks)",
16
- value: "configure",
37
+ label: "Configure blocks individually (maximum 15 blocks: 5 section, 5 context, 5 link button)",
38
+ value: constants.PASS_ARRAY_OR_CONFIGURE_OPTIONS.CONFIGURE,
17
39
  },
18
40
  ],
19
41
  optional: true,
20
- reloadProps: true,
21
42
  },
43
+ blocks: {
44
+ propDefinition: [
45
+ common.props.slack,
46
+ "blocks",
47
+ ],
48
+ },
49
+ ...buildIndexedProps("section", "Section Block", "string", SECTION_DESCRIPTION),
50
+ ...buildIndexedProps("context", "Context Block", "string[]", CONTEXT_DESCRIPTION),
51
+ ...buildIndexedProps("linkButton", "Link Button", "object", LINK_BUTTON_DESCRIPTION),
22
52
  },
23
53
  methods: {
24
- // This adds a visual separator in the props form between each block
25
- separator() {
26
- return `
27
-
28
- ---
29
-
30
- `;
31
- },
32
- createBlockProp(type, label, description) {
33
- return {
34
- type,
35
- label,
36
- description: `${description} ${this.separator()}`,
37
- };
38
- },
39
54
  createBlock(type, text) {
40
- if (type === "section") {
55
+ if (type === constants.BLOCK_TYPES.SECTION) {
41
56
  return {
42
57
  type: "section",
43
58
  text: {
@@ -45,7 +60,7 @@ export default {
45
60
  text,
46
61
  },
47
62
  };
48
- } else if (type === "context") {
63
+ } else if (type === constants.BLOCK_TYPES.CONTEXT) {
49
64
  const elements = Array.isArray(text)
50
65
  ? text.map((t) => ({
51
66
  type: "mrkdwn",
@@ -61,7 +76,7 @@ export default {
61
76
  type: "context",
62
77
  elements,
63
78
  };
64
- } else if (type === "link_button") {
79
+ } else if (type === constants.BLOCK_TYPES.LINK_BUTTON) {
65
80
  const buttons = Object.keys(text).map((buttonText) => ({
66
81
  type: "button",
67
82
  text: {
@@ -69,9 +84,9 @@ export default {
69
84
  text: buttonText,
70
85
  emoji: true,
71
86
  },
72
- url: text[buttonText], // Access the URL using buttonText as the key
87
+ url: text[buttonText],
73
88
  action_id: `actionId-${Math.random().toString(36)
74
- .substr(2, 9)}`, // Generates a random action_id
89
+ .substr(2, 9)}`,
75
90
  }));
76
91
 
77
92
  return {
@@ -81,102 +96,25 @@ export default {
81
96
  }
82
97
  },
83
98
  },
84
- async additionalProps(existingProps) {
85
- await common.additionalProps.call(this, existingProps);
86
- const props = {};
87
- const sectionDescription = "Add a **section** block to your message and configure with plain text or mrkdwn. See [Slack's docs](https://api.slack.com/reference/block-kit/blocks?ref=bk#section) for more info.";
88
- const contextDescription = "Add a **context** block to your message and configure with plain text or mrkdwn. Define multiple items if you'd like multiple elements in the context block. See [Slack's docs](https://api.slack.com/reference/block-kit/blocks?ref=bk#context) for more info.";
89
- const linkButtonDescription = "Add a **link button** to your message. Enter the button text as the key and the link URL as the value. Configure multiple buttons in the array to render them inline, or add additional Button Link blocks to render them vertically. See [Slack's docs](https://api.slack.com/reference/block-kit/blocks?ref=bk#actions) for more info.";
90
- const propsSection = this.createBlockProp("string", "Section Block Text", sectionDescription);
91
- const propsContext = this.createBlockProp("string[]", "Context Block Text", contextDescription);
92
- const propsLinkButton = this.createBlockProp("object", "Link Button", linkButtonDescription);
93
-
94
- if (!this.passArrayOrConfigure) {
95
- return props;
96
- }
97
- if (this.passArrayOrConfigure === "array") {
98
- props.blocks = {
99
- type: common.props.slack.propDefinitions.blocks.type,
100
- label: common.props.slack.propDefinitions.blocks.label,
101
- description: common.props.slack.propDefinitions.blocks.description,
102
- };
103
- } else {
104
- props.blockType = {
105
- type: "string",
106
- label: "Block Type",
107
- description: "Select the type of block to add. Refer to [Slack's docs](https://api.slack.com/reference/block-kit/blocks) for more info.",
108
- options: [
109
- {
110
- label: "Section",
111
- value: "section",
112
- },
113
- {
114
- label: "Context",
115
- value: "context",
116
- },
117
- {
118
- label: "Link Button",
119
- value: "link_button",
120
- },
121
- ],
122
- reloadProps: true,
123
- };}
124
- let currentBlockType = this.blockType;
125
- for (let i = 1; i <= 5; i++) {
126
- if (currentBlockType === "section") {
127
- props[`section${i}`] = propsSection;
128
- } else if (currentBlockType === "context") {
129
- props[`context${i}`] = propsContext;
130
- } else if (currentBlockType === "link_button") {
131
- props[`linkButton${i}`] = propsLinkButton;
132
- }
133
-
134
- if (i < 5 && currentBlockType) { // Check if currentBlockType is set before adding nextBlockType
135
- props[`nextBlockType${i}`] = {
136
- type: "string",
137
- label: "Next Block Type",
138
- options: [
139
- {
140
- label: "Section",
141
- value: "section",
142
- },
143
- {
144
- label: "Context",
145
- value: "context",
146
- },
147
- {
148
- label: "Link Button",
149
- value: "link_button",
150
- },
151
- ],
152
- optional: true,
153
- reloadProps: true,
154
- };
155
- currentBlockType = this[`nextBlockType${i}`];
156
- }
157
- }
158
- return props;
159
- },
160
99
  async run() {
161
100
  let blocks = [];
162
- if (this.passArrayOrConfigure === "array") {
101
+ if (this.passArrayOrConfigure === constants.PASS_ARRAY_OR_CONFIGURE_OPTIONS.ARRAY) {
163
102
  blocks = this.blocks;
164
103
  } else {
165
- for (let i = 1; i <= 5; i++) {
104
+ for (let i = 1; i <= MAX_BLOCKS; i++) {
166
105
  if (this[`section${i}`]) {
167
- blocks.push(this.createBlock("section", this[`section${i}`]));
106
+ blocks.push(this.createBlock(constants.BLOCK_TYPES.SECTION, this[`section${i}`]));
168
107
  }
169
108
 
170
109
  if (this[`context${i}`]) {
171
- blocks.push(this.createBlock("context", this[`context${i}`]));
110
+ blocks.push(this.createBlock(constants.BLOCK_TYPES.CONTEXT, this[`context${i}`]));
172
111
  }
173
112
 
174
113
  if (this[`linkButton${i}`]) {
175
- blocks.push(this.createBlock("link_button", this[`linkButton${i}`]));
114
+ blocks.push(this.createBlock(constants.BLOCK_TYPES.LINK_BUTTON, this[`linkButton${i}`]));
176
115
  }
177
116
  }
178
117
  }
179
118
  return blocks;
180
119
  },
181
120
  };
182
-
@@ -1,3 +1,4 @@
1
+ import { ConfigurationError } from "@pipedream/platform";
1
2
  import slack from "../../slack_v2.app.mjs";
2
3
 
3
4
  export default {
@@ -30,40 +31,23 @@ export default {
30
31
  label: "Include link to Pipedream",
31
32
  description: "Defaults to `true`, includes a link to Pipedream at the end of your Slack message.",
32
33
  },
33
- customizeBotSettings: {
34
- type: "boolean",
35
- label: "Customize Bot Settings",
36
- description: "Customize the username and/or icon of the Bot",
37
- optional: true,
38
- reloadProps: true,
39
- },
40
34
  username: {
41
35
  propDefinition: [
42
36
  slack,
43
37
  "username",
44
38
  ],
45
- hidden: true,
46
39
  },
47
40
  icon_emoji: {
48
41
  propDefinition: [
49
42
  slack,
50
43
  "icon_emoji",
51
44
  ],
52
- hidden: true,
53
45
  },
54
46
  icon_url: {
55
47
  propDefinition: [
56
48
  slack,
57
49
  "icon_url",
58
50
  ],
59
- hidden: true,
60
- },
61
- replyToThread: {
62
- type: "boolean",
63
- label: "Reply to Thread",
64
- description: "Reply to an existing thread",
65
- optional: true,
66
- reloadProps: true,
67
51
  },
68
52
  thread_ts: {
69
53
  propDefinition: [
@@ -72,78 +56,38 @@ export default {
72
56
  ],
73
57
  description: "Provide another message's `ts` value to make this message a reply (e.g., if triggering on new Slack messages, enter `{{event.ts}}`). Avoid using a reply's `ts` value; use its parent instead. e.g. `1403051575.000407`.",
74
58
  optional: true,
75
- hidden: true,
76
59
  },
77
60
  thread_broadcast: {
78
61
  propDefinition: [
79
62
  slack,
80
63
  "thread_broadcast",
81
64
  ],
82
- hidden: true,
83
- },
84
- addMessageMetadata: {
85
- type: "boolean",
86
- label: "Add Message Metadata",
87
- description: "Set the metadata event type and payload",
88
- optional: true,
89
- reloadProps: true,
90
65
  },
91
66
  metadata_event_type: {
92
67
  propDefinition: [
93
68
  slack,
94
69
  "metadata_event_type",
95
70
  ],
96
- hidden: true,
97
71
  },
98
72
  metadata_event_payload: {
99
73
  propDefinition: [
100
74
  slack,
101
75
  "metadata_event_payload",
102
76
  ],
103
- hidden: true,
104
- },
105
- configureUnfurlSettings: {
106
- type: "boolean",
107
- label: "Configure Unfurl Settings",
108
- description: "Configure settings for unfurling links and media",
109
- optional: true,
110
- reloadProps: true,
111
77
  },
112
78
  unfurl_links: {
113
79
  propDefinition: [
114
80
  slack,
115
81
  "unfurl_links",
116
82
  ],
117
- hidden: true,
118
83
  },
119
84
  unfurl_media: {
120
85
  propDefinition: [
121
86
  slack,
122
87
  "unfurl_media",
123
88
  ],
124
- hidden: true,
125
89
  },
126
90
  },
127
- async additionalProps(props) {
128
- if (this.conversation && this.replyToThread) {
129
- props.thread_ts.hidden = false;
130
- props.thread_broadcast.hidden = false;
131
- }
132
- if (this.customizeBotSettings) {
133
- props.username.hidden = false;
134
- props.icon_emoji.hidden = false;
135
- props.icon_url.hidden = false;
136
- }
137
- if (this.addMessageMetadata) {
138
- props.metadata_event_type.hidden = false;
139
- props.metadata_event_payload.hidden = false;
140
- }
141
- if (this.configureUnfurlSettings) {
142
- props.unfurl_links.hidden = false;
143
- props.unfurl_media.hidden = false;
144
- }
145
- return {};
146
- },
147
91
  methods: {
148
92
  _makeSentViaPipedreamBlock() {
149
93
  const workflowId = process.env.PIPEDREAM_WORKFLOW_ID;
@@ -220,7 +164,7 @@ export default {
220
164
  try {
221
165
  metadataEventPayload = JSON.parse(this.metadata_event_payload);
222
166
  } catch (error) {
223
- throw new Error(`Invalid JSON in metadata_event_payload: ${error.message}`);
167
+ throw new ConfigurationError(`Invalid JSON in metadata_event_payload: ${error.message}`);
224
168
  }
225
169
  }
226
170
 
@@ -251,7 +195,9 @@ export default {
251
195
 
252
196
  if (this.post_at) {
253
197
  obj.post_at = Math.floor(new Date(this.post_at).getTime() / 1000);
254
- return await this.slack.scheduleMessage(obj);
198
+ const result = await this.slack.scheduleMessage(obj);
199
+ $.export("$summary", `Message scheduled for ${this.post_at}`);
200
+ return result;
255
201
  }
256
202
  const resp = await this.slack.postChatMessage(obj);
257
203
  const { channel } = await this.slack.conversationsInfo({
@@ -1,10 +1,11 @@
1
+ // x-pd-ai: optimized
1
2
  import slack from "../../slack_v2.app.mjs";
2
3
 
3
4
  export default {
4
5
  key: "slack_v2-create-channel",
5
6
  name: "Create a Channel",
6
7
  description: "Create a new channel. [See the documentation](https://api.slack.com/methods/conversations.create)",
7
- version: "0.0.31",
8
+ version: "0.0.33",
8
9
  annotations: {
9
10
  destructiveHint: false,
10
11
  openWorldHint: true,
@@ -1,10 +1,11 @@
1
+ // x-pd-ai: optimized
1
2
  import slack from "../../slack_v2.app.mjs";
2
3
 
3
4
  export default {
4
5
  key: "slack_v2-create-reminder",
5
6
  name: "Create Reminder",
6
7
  description: "Create a reminder. [See the documentation](https://api.slack.com/methods/reminders.add)",
7
- version: "0.0.32",
8
+ version: "0.0.34",
8
9
  annotations: {
9
10
  destructiveHint: false,
10
11
  openWorldHint: true,
@@ -1,10 +1,11 @@
1
+ // x-pd-ai: optimized
1
2
  import slack from "../../slack_v2.app.mjs";
2
3
 
3
4
  export default {
4
5
  key: "slack_v2-delete-file",
5
6
  name: "Delete File",
6
7
  description: "Delete a file. [See the documentation](https://api.slack.com/methods/files.delete)",
7
- version: "0.0.31",
8
+ version: "0.0.33",
8
9
  annotations: {
9
10
  destructiveHint: true,
10
11
  openWorldHint: true,
@@ -23,9 +24,6 @@ export default {
23
24
  propDefinition: [
24
25
  slack,
25
26
  "file",
26
- (c) => ({
27
- channel: c.conversation,
28
- }),
29
27
  ],
30
28
  },
31
29
  },
@@ -5,14 +5,15 @@ export default {
5
5
  key: "slack_v2-delete-message",
6
6
  name: "Delete Message",
7
7
  description:
8
- "Permanently delete a message. **This cannot be undone — confirm the exact message with the"
9
- + " user before calling it.** Identify the message first with **Get Channel History** or"
10
- + " **Search** and quote its text back, rather than deleting by position ('the last one')."
8
+ "Permanently delete a message. **This cannot be undone.**"
9
+ + " To delete a specific message (including the most recent one), first call **Get Channel History**"
10
+ + " to retrieve messages `messages[0]` is the most recent then pass its `ts` here."
11
+ + " Quote the message text back to the user to confirm before deleting."
11
12
  + " Accepts a channel ID or NAME for the conversation, resolved automatically. Slack only"
12
13
  + " lets an identity delete its own messages, so this deletes as whichever identity posted:"
13
14
  + " it retries automatically with the other identity if the first attempt returns"
14
15
  + " `cant_delete_message`. [See the documentation](https://api.slack.com/methods/chat.delete)",
15
- version: "0.2.1",
16
+ version: "0.2.3",
16
17
  annotations: {
17
18
  destructiveHint: true,
18
19
  openWorldHint: true,
@@ -54,10 +55,10 @@ export default {
54
55
  // post-message had just created. "Post it, then take it back" failed every single
55
56
  // time with cant_delete_message. Rather than flip the default (a behaviour change for
56
57
  // existing workflows), try the configured identity and fall back to the other one.
57
- const attempt = (as_user) => this.slack.deleteMessage({
58
+ const attempt = (asUser) => this.slack.deleteMessage({
58
59
  channel,
59
60
  ts: this.timestamp,
60
- as_user,
61
+ as_user: asUser,
61
62
  });
62
63
 
63
64
  // makeRequest() routes to the bot token on `as_user === false` and to the user token for
@@ -11,7 +11,7 @@ export default {
11
11
  + " Requires the message timestamp (`ts`) from **Get Channel History** or **Post Message**."
12
12
  + " You can only edit messages posted by the same token/user."
13
13
  + " [See the documentation](https://api.slack.com/methods/chat.update)",
14
- version: "0.0.3",
14
+ version: "0.0.5",
15
15
  type: "action",
16
16
  annotations: {
17
17
  destructiveHint: false,
@@ -57,7 +57,25 @@ export default {
57
57
  throw new ConfigurationError("Invalid JSON string: " + error.message);
58
58
  }
59
59
  }
60
- const response = await this.slack.updateMessage(args);
60
+ // Slack refuses chat.update unless the calling identity authored the message, and
61
+ // post-message tries the bot identity first, falling back to the user identity when
62
+ // the bot can't deliver — so the message being edited may have been posted as
63
+ // either one. Try both here too, mirroring the fallback already used in
64
+ // delete-message, rather than guessing which identity posted it.
65
+ const attempt = (asUser) => this.slack.updateMessage({
66
+ ...args,
67
+ as_user: asUser,
68
+ });
69
+ const hasBotToken = Boolean(this.slack.getBotToken());
70
+
71
+ let response;
72
+ try {
73
+ response = await attempt(false);
74
+ } catch (error) {
75
+ if (!hasBotToken || !`${error}`.includes("cant_update_message")) throw error;
76
+ response = await attempt(true);
77
+ }
78
+
61
79
  $.export("$summary", `Message updated in ${channelId}`);
62
80
  return response;
63
81
  },
@@ -1,10 +1,22 @@
1
+ // x-pd-ai: optimized
2
+ import utils from "../../common/utils.mjs";
1
3
  import slack from "../../slack_v2.app.mjs";
2
4
 
3
5
  export default {
4
6
  key: "slack_v2-find-message",
5
7
  name: "Find Message",
6
- description: "Find a Slack message. [See the documentation](https://api.slack.com/methods/assistant.search.context)",
7
- version: "0.1.5",
8
+ description: "Find a Slack message by keyword or natural-language query across public and private channels."
9
+ + " Returns matching messages with channel context, timestamps, and permalinks."
10
+ + " Pass the returned `message_ts` to **Reply to a Message** to answer in thread,"
11
+ + " or to **Get Thread Replies** to read the rest of that conversation."
12
+ + " Use **Search** instead when you need file results or want to restrict `channelTypes`;"
13
+ + " use this action when you want to order results with `sort` / `sortDirection`."
14
+ + " User mentions come back in the canonical `<@U123>` form; echo it verbatim to post a real mention."
15
+ + " Display names are returned separately as `mentions`, an array of `{ id, name }` objects,"
16
+ + " omitted when no mention carried a name."
17
+ + " Do NOT splice a name back inline: Slack renders `<@U123|Name>` as literal text, not a mention."
18
+ + " [See the documentation](https://api.slack.com/methods/assistant.search.context)",
19
+ version: "0.2.0",
8
20
  annotations: {
9
21
  destructiveHint: false,
10
22
  openWorldHint: true,
@@ -62,7 +74,7 @@ export default {
62
74
  cursor = response.response_metadata?.next_cursor;
63
75
  } while (cursor && matches.length < maxResults);
64
76
 
65
- return matches.slice(0, maxResults);
77
+ return utils.normalizeSearchMessages(matches.slice(0, maxResults));
66
78
  },
67
79
  },
68
80
  async run({ $ }) {
@@ -1,10 +1,11 @@
1
+ // x-pd-ai: optimized
1
2
  import slack from "../../slack_v2.app.mjs";
2
3
 
3
4
  export default {
4
5
  key: "slack_v2-find-user-by-email",
5
6
  name: "Find User by Email",
6
7
  description: "Find a user by matching against their email. [See the documentation](https://api.slack.com/methods/users.lookupByEmail)",
7
- version: "0.0.30",
8
+ version: "0.0.32",
8
9
  annotations: {
9
10
  destructiveHint: false,
10
11
  openWorldHint: true,
@@ -1,10 +1,11 @@
1
+ // x-pd-ai: optimized
1
2
  import slack from "../../slack_v2.app.mjs";
2
3
 
3
4
  export default {
4
5
  key: "slack_v2-find-user-by-id",
5
6
  name: "Find User by ID",
6
- description: "Find a user by their ID. Returns user profile information including name, email (requires `users:read.email` scope), timezone, and status. [See the documentation](https://api.slack.com/methods/users.info)",
7
- version: "0.0.7",
7
+ description: "Find a user by their ID — including a specific user you already have the Slack ID for, whether or not it's your own. Returns user profile information including name, email (requires `users:read.email` scope), timezone, and status. If you only have an email address, use **Find User by Email** instead. [See the documentation](https://api.slack.com/methods/users.info)",
8
+ version: "0.0.9",
8
9
  type: "action",
9
10
  annotations: {
10
11
  destructiveHint: false,
@@ -18,7 +19,7 @@ export default {
18
19
  slack,
19
20
  "user",
20
21
  ],
21
- description: "Select a user or enter a user ID (e.g., `U1234567890`)",
22
+ description: "The user's ID (e.g. `U1234567890`). Use **Find User by Email** to resolve an ID from an email address, or **List Users** to browse all users.",
22
23
  },
23
24
  includeLocale: {
24
25
  type: "boolean",
@@ -1,10 +1,11 @@
1
+ // x-pd-ai: optimized
1
2
  import slack from "../../slack_v2.app.mjs";
2
3
 
3
4
  export default {
4
5
  key: "slack_v2-get-channel-details",
5
6
  name: "Get Channel Details",
6
7
  description: "Retrieve details for a Slack channel, specified by ID or by name — names are resolved automatically. [See the documentation](https://api.slack.com/methods/conversations.info)",
7
- version: "0.1.1",
8
+ version: "0.1.3",
8
9
  type: "action",
9
10
  annotations: {
10
11
  destructiveHint: false,
@@ -18,7 +19,7 @@ export default {
18
19
  slack,
19
20
  "conversation",
20
21
  ],
21
- description: "Select a channel or provide a channel ID.",
22
+ description: "A channel ID (e.g. `C1234567890`) or channel name (e.g. `general` or `#general`) resolved automatically. Use **List Channels** to look up channel IDs.",
22
23
  },
23
24
  includeLocale: {
24
25
  type: "boolean",
@@ -16,7 +16,7 @@ export default {
16
16
  + " messages carry blocks, attachments and edit metadata, so a busy channel can run to tens"
17
17
  + " of thousands of characters and be truncated before you see any of it."
18
18
  + " [See the documentation](https://api.slack.com/methods/conversations.history)",
19
- version: "0.2.0",
19
+ version: "0.2.2",
20
20
  type: "action",
21
21
  annotations: {
22
22
  destructiveHint: false,
@@ -40,13 +40,13 @@ export default {
40
40
  oldest: {
41
41
  type: "string",
42
42
  label: "Oldest",
43
- description: "Only messages after this Unix timestamp. Inclusive.",
43
+ description: "Only return messages posted after this timestamp (inclusive), as a Slack timestamp, e.g. `1610000000.000000` (Unix epoch seconds, optionally with fractional microseconds).",
44
44
  optional: true,
45
45
  },
46
46
  latest: {
47
47
  type: "string",
48
48
  label: "Latest",
49
- description: "Only messages before this Unix timestamp. Default: now.",
49
+ description: "Only return messages posted before this timestamp. Defaults to now. Same format as `Oldest`, e.g. `1610000000.000000`.",
50
50
  optional: true,
51
51
  },
52
52
  fields: {