@hubot-friends/hubot-slack 3.1.3 → 3.2.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.
- package/.github/workflows/ci-build.yml +2 -4
- package/package.json +1 -1
- package/src/Bot.mjs +17 -18
- package/test/Bot.mjs +38 -0
- package/test/Thread_ts_ShouldPassThruTest.mjs +100 -0
|
@@ -16,8 +16,7 @@ jobs:
|
|
|
16
16
|
strategy:
|
|
17
17
|
matrix:
|
|
18
18
|
node-version:
|
|
19
|
-
- '
|
|
20
|
-
- '22.x'
|
|
19
|
+
- '23.x'
|
|
21
20
|
steps:
|
|
22
21
|
- name: Checkout
|
|
23
22
|
uses: actions/checkout@v4
|
|
@@ -41,8 +40,7 @@ jobs:
|
|
|
41
40
|
strategy:
|
|
42
41
|
matrix:
|
|
43
42
|
node-version:
|
|
44
|
-
- '
|
|
45
|
-
- '22.x'
|
|
43
|
+
- '23.x'
|
|
46
44
|
steps:
|
|
47
45
|
- name: Checkout
|
|
48
46
|
uses: actions/checkout@v4
|
package/package.json
CHANGED
package/src/Bot.mjs
CHANGED
|
@@ -9,10 +9,10 @@ class SlackClient {
|
|
|
9
9
|
process.env.HUBOT_SLACK_CONVERSATION_CACHE_TTL_MS
|
|
10
10
|
? parseInt(process.env.HUBOT_SLACK_CONVERSATION_CACHE_TTL_MS, 10)
|
|
11
11
|
: (5 * 60 * 1000);
|
|
12
|
-
constructor(options, robot) {
|
|
12
|
+
constructor(options, robot, socket, web) {
|
|
13
13
|
this.robot = robot;
|
|
14
|
-
this.socket = new SocketModeClient({ appToken: options.appToken, ...options.socketModeOptions });
|
|
15
|
-
this.web = new WebClient(options.botToken, { maxRequestConcurrency: 1, logLevel: 'error'});
|
|
14
|
+
this.socket = socket ?? new SocketModeClient({ appToken: options.appToken, ...options.socketModeOptions });
|
|
15
|
+
this.web = web ?? new WebClient(options.botToken, { maxRequestConcurrency: 1, logLevel: 'error'});
|
|
16
16
|
this.apiPageSize = 100;
|
|
17
17
|
if (!isNaN(options.apiPageSize)) {
|
|
18
18
|
this.apiPageSize = parseInt(options.apiPageSize, 10);
|
|
@@ -72,26 +72,24 @@ class SlackClient {
|
|
|
72
72
|
}
|
|
73
73
|
async send(envelope, message) {
|
|
74
74
|
const room = envelope.room || envelope.id;
|
|
75
|
+
const thread_ts = envelope.message?.thread_ts
|
|
75
76
|
if (room == null) {
|
|
76
77
|
this.robot.logger.error("Cannot send message without a valid room. Envelopes should contain a room property set to a Slack conversation ID.");
|
|
77
78
|
return;
|
|
78
79
|
}
|
|
79
80
|
this.robot.logger.debug(`SlackClient#send() room: ${room}, message: ${message}`);
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
} catch (e) {
|
|
93
|
-
this.robot.logger.error(e, `SlackClient#send(string) error: ${e.message}`)
|
|
94
|
-
}
|
|
81
|
+
const messageOptions = {
|
|
82
|
+
channel: room,
|
|
83
|
+
text: typeof message === "string" ? message : message.text,
|
|
84
|
+
thread_ts, // Include thread_ts if it's defined
|
|
85
|
+
...message, // Spread other properties from the message if it's an object
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
try {
|
|
89
|
+
const result = await this.web.chat.postMessage(messageOptions);
|
|
90
|
+
this.robot.logger.debug(`Successfully sent message to ${room}`);
|
|
91
|
+
} catch (e) {
|
|
92
|
+
this.robot.logger.error(e, `SlackClient#send() error: ${e.message}`);
|
|
95
93
|
}
|
|
96
94
|
}
|
|
97
95
|
loadUsers(callback) {
|
|
@@ -254,6 +252,7 @@ class SlackBot extends Adapter {
|
|
|
254
252
|
* @param {...(string|Object)} messages - fully documented in SlackClient
|
|
255
253
|
*/
|
|
256
254
|
async send(envelope, ...messages) {
|
|
255
|
+
|
|
257
256
|
this.robot.logger.debug('Sending message to Slack');
|
|
258
257
|
let callback = function() {};
|
|
259
258
|
if (typeof(messages[messages.length - 1]) === "function") {
|
package/test/Bot.mjs
CHANGED
|
@@ -191,6 +191,44 @@ describe('Send Messages', () => {
|
|
|
191
191
|
assert.deepEqual(stubs._sendCount, 1)
|
|
192
192
|
assert.deepEqual(stubs._msg, 'message with a callback')
|
|
193
193
|
})
|
|
194
|
+
|
|
195
|
+
it('envelope thread_ts should be undefined', () => {
|
|
196
|
+
slackbot.client.send = (envelope, message) => {
|
|
197
|
+
stubs._sendCount++;
|
|
198
|
+
stubs._msg = message;
|
|
199
|
+
stubs._envelope = envelope;
|
|
200
|
+
}
|
|
201
|
+
const fakeEnvelope = {
|
|
202
|
+
room: stubs.channel.id,
|
|
203
|
+
user: stubs.user
|
|
204
|
+
}
|
|
205
|
+
slackbot.send(fakeEnvelope, 'message');
|
|
206
|
+
assert.deepEqual(stubs._sendCount, 1);
|
|
207
|
+
assert.deepEqual(stubs._msg, 'message');
|
|
208
|
+
assert.strictEqual(stubs._envelope.message, undefined);
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
it('Should send a message with thread_ts when message is included in envelope', () => {
|
|
212
|
+
slackbot.client.send = (envelope, message) => {
|
|
213
|
+
stubs._sendCount++;
|
|
214
|
+
stubs._msg = message;
|
|
215
|
+
stubs._envelope = envelope;
|
|
216
|
+
}
|
|
217
|
+
const fakeEnvelope = {
|
|
218
|
+
room: stubs.channel.id,
|
|
219
|
+
user: stubs.user,
|
|
220
|
+
message: {
|
|
221
|
+
room: stubs.channel.id,
|
|
222
|
+
user: stubs.user,
|
|
223
|
+
thread_ts: '1234567890.123456'
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
slackbot.send(fakeEnvelope, 'message');
|
|
227
|
+
assert.deepEqual(stubs._sendCount, 1);
|
|
228
|
+
assert.deepEqual(stubs._msg, 'message');
|
|
229
|
+
assert.strictEqual(stubs._envelope.message.thread_ts, '1234567890.123456');
|
|
230
|
+
});
|
|
231
|
+
|
|
194
232
|
})
|
|
195
233
|
|
|
196
234
|
describe('Reply to Messages', () => {
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { describe, it, beforeEach } from 'node:test'
|
|
2
|
+
import assert from 'node:assert/strict'
|
|
3
|
+
import { SlackBot, SlackClient } from '../src/Bot.mjs'
|
|
4
|
+
import hubotSlackMock from '../index.mjs'
|
|
5
|
+
import { loadBot, Robot } from 'hubot'
|
|
6
|
+
import { SlackTextMessage, ReactionMessage, FileSharedMessage } from '../src/Message.mjs'
|
|
7
|
+
import EventEmitter from 'node:events'
|
|
8
|
+
|
|
9
|
+
class SocketModeClientMock extends EventEmitter{
|
|
10
|
+
constructor() {
|
|
11
|
+
super()
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
send() {
|
|
15
|
+
return Promise.resolve()
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
class WebClientMock extends EventEmitter{
|
|
20
|
+
constructor(api) {
|
|
21
|
+
super()
|
|
22
|
+
Object.keys(api).forEach((key) => {
|
|
23
|
+
this[key] = api[key]
|
|
24
|
+
})
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
describe('thread_ts should pass thru', () => {
|
|
29
|
+
it('Message should include thread_ts if present', async () => {
|
|
30
|
+
const user = { id
|
|
31
|
+
: 'U12345678', name: 'testuser' }
|
|
32
|
+
const text = 'Hello, world!'
|
|
33
|
+
const rawText = 'Hello, world!'
|
|
34
|
+
const rawMessage = {
|
|
35
|
+
type: 'message',
|
|
36
|
+
user: user.id,
|
|
37
|
+
text: rawText,
|
|
38
|
+
ts: '1234567890.123456',
|
|
39
|
+
thread_ts: '1234567890.123456'
|
|
40
|
+
}
|
|
41
|
+
const channel_id = 'C12345678'
|
|
42
|
+
const robot_name = 'testbot'
|
|
43
|
+
const robot_alias = 'testbot_alias'
|
|
44
|
+
const envelope = {
|
|
45
|
+
user: user,
|
|
46
|
+
message: rawMessage,
|
|
47
|
+
room: channel_id
|
|
48
|
+
}
|
|
49
|
+
const message = {
|
|
50
|
+
text: text,
|
|
51
|
+
user: user.id,
|
|
52
|
+
room: channel_id,
|
|
53
|
+
thread_ts: '1234567890.123456'
|
|
54
|
+
}
|
|
55
|
+
const msg = new SlackTextMessage(user, text, rawText, rawMessage, channel_id, robot_name, robot_alias)
|
|
56
|
+
const sut = new SlackClient({}, new Robot('TestBot', 'testbot', 'testbot_alias'), new SocketModeClientMock(), new WebClientMock({
|
|
57
|
+
chat: {
|
|
58
|
+
postMessage: async (params) => {
|
|
59
|
+
assert.strictEqual(params.thread_ts, '1234567890.123456')
|
|
60
|
+
return { ok: true, ts: '1234567890.123456' }
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}))
|
|
64
|
+
await sut.send(envelope, message)
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
it('Message send a text only message', async () => {
|
|
68
|
+
const user = { id
|
|
69
|
+
: 'U12345678', name: 'testuser' }
|
|
70
|
+
const text = 'Hello, world!'
|
|
71
|
+
const rawText = 'Hello, world!'
|
|
72
|
+
const rawMessage = {
|
|
73
|
+
type: 'message',
|
|
74
|
+
user: user.id,
|
|
75
|
+
text: rawText,
|
|
76
|
+
ts: '1234567890.123456',
|
|
77
|
+
thread_ts: '1234567890.123456'
|
|
78
|
+
}
|
|
79
|
+
const channel_id = 'C12345678'
|
|
80
|
+
const robot_name = 'testbot'
|
|
81
|
+
const robot_alias = 'testbot_alias'
|
|
82
|
+
const envelope = {
|
|
83
|
+
user: user,
|
|
84
|
+
message: rawMessage,
|
|
85
|
+
room: channel_id
|
|
86
|
+
}
|
|
87
|
+
const message = text
|
|
88
|
+
const msg = new SlackTextMessage(user, text, rawText, rawMessage, channel_id, robot_name, robot_alias)
|
|
89
|
+
const sut = new SlackClient({}, new Robot('TestBot', 'testbot', 'testbot_alias'), new SocketModeClientMock(), new WebClientMock({
|
|
90
|
+
chat: {
|
|
91
|
+
postMessage: async (param) => {
|
|
92
|
+
assert.strictEqual(param.text, 'Hello, world!')
|
|
93
|
+
return { ok: true, param }
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}))
|
|
97
|
+
await sut.send(envelope, message)
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
})
|