@urugus/slack-cli 0.2.0 → 0.2.1
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/CHANGELOG.md +22 -0
- package/dist/utils/slack-operations/channel-operations.d.ts.map +1 -1
- package/dist/utils/slack-operations/channel-operations.js +24 -28
- package/dist/utils/slack-operations/channel-operations.js.map +1 -1
- package/dist/utils/slack-operations/message-operations.d.ts.map +1 -1
- package/dist/utils/slack-operations/message-operations.js +16 -4
- package/dist/utils/slack-operations/message-operations.js.map +1 -1
- package/package.json +1 -1
- package/src/utils/slack-operations/channel-operations.ts +25 -30
- package/src/utils/slack-operations/message-operations.ts +15 -4
- package/tests/commands/unread.test.ts +41 -0
- package/tests/utils/slack-operations/channel-operations.test.ts +7 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,28 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [0.2.1] - 2025-06-23
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
- Fixed unread message detection for channels where unread_count is 0 but messages exist after last_read timestamp
|
|
9
|
+
- Always check messages after last_read timestamp for accurate unread count
|
|
10
|
+
- Improved reliability of unread message detection for channels like dev_kiban_jira
|
|
11
|
+
|
|
12
|
+
## [0.2.0] - 2025-06-23
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
- Major version bump for improved unread message detection
|
|
16
|
+
|
|
17
|
+
## [0.1.9] - 2025-06-22
|
|
18
|
+
|
|
19
|
+
### Fixed
|
|
20
|
+
- Improved unread message detection using last_read timestamp
|
|
21
|
+
|
|
22
|
+
## [0.1.8] - 2025-06-22
|
|
23
|
+
|
|
24
|
+
### Changed
|
|
25
|
+
- Refactored code organization with separation of concerns
|
|
26
|
+
|
|
5
27
|
## [0.1.7] - 2025-06-22
|
|
6
28
|
|
|
7
29
|
### Fixed
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"channel-operations.d.ts","sourceRoot":"","sources":["../../../src/utils/slack-operations/channel-operations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAGhD,OAAO,EAAE,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAEnE,UAAU,qBAAsB,SAAQ,OAAO;IAC7C,YAAY,EAAE,MAAM,CAAC;IACrB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,iBAAkB,SAAQ,eAAe;IAC9C,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAuB9D,kBAAkB,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"channel-operations.d.ts","sourceRoot":"","sources":["../../../src/utils/slack-operations/channel-operations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAGhD,OAAO,EAAE,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAEnE,UAAU,qBAAsB,SAAQ,OAAO;IAC7C,YAAY,EAAE,MAAM,CAAC;IACrB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,iBAAkB,SAAQ,eAAe;IAC9C,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAuB9D,kBAAkB,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IAyExC,cAAc,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,CAAC;CAe9E"}
|
|
@@ -45,36 +45,32 @@ class ChannelOperations extends base_client_1.BaseSlackClient {
|
|
|
45
45
|
channel: channel.id,
|
|
46
46
|
limit: 1,
|
|
47
47
|
});
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
// Get
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
48
|
+
// Always check for messages after last_read timestamp
|
|
49
|
+
if (channelInfo.last_read) {
|
|
50
|
+
// Fetch messages after last_read
|
|
51
|
+
const unreadHistory = await this.client.conversations.history({
|
|
52
|
+
channel: channel.id,
|
|
53
|
+
oldest: channelInfo.last_read,
|
|
54
|
+
limit: 100, // Get up to 100 unread messages
|
|
55
|
+
});
|
|
56
|
+
const unreadCount = unreadHistory.messages?.length || 0;
|
|
57
|
+
if (unreadCount > 0) {
|
|
58
|
+
channelsWithUnread.push({
|
|
59
|
+
...channel,
|
|
60
|
+
unread_count: unreadCount,
|
|
61
|
+
unread_count_display: unreadCount,
|
|
62
|
+
last_read: channelInfo.last_read,
|
|
58
63
|
});
|
|
59
|
-
unreadCount = allHistory.messages?.length || 0;
|
|
60
|
-
}
|
|
61
|
-
else {
|
|
62
|
-
// Check if there are messages after last_read
|
|
63
|
-
const latestMessage = history.messages[0];
|
|
64
|
-
const lastReadTs = parseFloat(channelInfo.last_read);
|
|
65
|
-
const latestMessageTs = parseFloat(latestMessage.ts || '0');
|
|
66
|
-
if (latestMessageTs > lastReadTs) {
|
|
67
|
-
hasUnread = true;
|
|
68
|
-
// Calculate unread count by fetching messages after last_read
|
|
69
|
-
const unreadHistory = await this.client.conversations.history({
|
|
70
|
-
channel: channel.id,
|
|
71
|
-
oldest: channelInfo.last_read,
|
|
72
|
-
limit: 100, // Get up to 100 unread messages
|
|
73
|
-
});
|
|
74
|
-
unreadCount = unreadHistory.messages?.length || 0;
|
|
75
|
-
}
|
|
76
64
|
}
|
|
77
|
-
|
|
65
|
+
}
|
|
66
|
+
else if (history.messages && history.messages.length > 0) {
|
|
67
|
+
// If no last_read, all messages are unread
|
|
68
|
+
const allHistory = await this.client.conversations.history({
|
|
69
|
+
channel: channel.id,
|
|
70
|
+
limit: 100,
|
|
71
|
+
});
|
|
72
|
+
const unreadCount = allHistory.messages?.length || 0;
|
|
73
|
+
if (unreadCount > 0) {
|
|
78
74
|
channelsWithUnread.push({
|
|
79
75
|
...channel,
|
|
80
76
|
unread_count: unreadCount,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"channel-operations.js","sourceRoot":"","sources":["../../../src/utils/slack-operations/channel-operations.ts"],"names":[],"mappings":";;;AAAA,+CAAgD;AAChD,0DAAsD;AACtD,4CAAwC;AASxC,MAAa,iBAAkB,SAAQ,6BAAe;IACpD,KAAK,CAAC,YAAY,CAAC,OAA4B;QAC7C,MAAM,QAAQ,GAAc,EAAE,CAAC;QAC/B,IAAI,MAA0B,CAAC;QAE/B,gCAAgC;QAChC,GAAG,CAAC;YACF,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC;gBACpD,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,gBAAgB,EAAE,OAAO,CAAC,gBAAgB;gBAC1C,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,MAAM;aACP,CAAC,CAAC;YAEH,IAAI,QAAQ,CAAC,QAAQ,EAAE,CAAC;gBACtB,QAAQ,CAAC,IAAI,CAAC,GAAI,QAAQ,CAAC,QAAsB,CAAC,CAAC;YACrD,CAAC;YAED,MAAM,GAAG,QAAQ,CAAC,iBAAiB,EAAE,WAAW,CAAC;QACnD,CAAC,QAAQ,MAAM,EAAE;QAEjB,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,KAAK,CAAC,kBAAkB;QACtB,gDAAgD;QAChD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC;YACpD,KAAK,EAAE,wCAAwC;YAC/C,gBAAgB,EAAE,IAAI;YACtB,KAAK,EAAE,IAAI;SACZ,CAAC,CAAC;QAEH,MAAM,QAAQ,GAAG,QAAQ,CAAC,QAAqB,CAAC;QAChD,MAAM,kBAAkB,GAAc,EAAE,CAAC;QAEzC,8DAA8D;QAC9D,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC/B,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC;oBAChD,OAAO,EAAE,OAAO,CAAC,EAAE;oBACnB,mBAAmB,EAAE,KAAK;iBAC3B,CAAC,CAAC;gBACH,MAAM,WAAW,GAAG,IAAI,CAAC,OAAgC,CAAC;gBAE1D,wCAAwC;gBACxC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC;oBACtD,OAAO,EAAE,OAAO,CAAC,EAAE;oBACnB,KAAK,EAAE,CAAC;iBACT,CAAC,CAAC;gBAEH,
|
|
1
|
+
{"version":3,"file":"channel-operations.js","sourceRoot":"","sources":["../../../src/utils/slack-operations/channel-operations.ts"],"names":[],"mappings":";;;AAAA,+CAAgD;AAChD,0DAAsD;AACtD,4CAAwC;AASxC,MAAa,iBAAkB,SAAQ,6BAAe;IACpD,KAAK,CAAC,YAAY,CAAC,OAA4B;QAC7C,MAAM,QAAQ,GAAc,EAAE,CAAC;QAC/B,IAAI,MAA0B,CAAC;QAE/B,gCAAgC;QAChC,GAAG,CAAC;YACF,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC;gBACpD,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,gBAAgB,EAAE,OAAO,CAAC,gBAAgB;gBAC1C,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,MAAM;aACP,CAAC,CAAC;YAEH,IAAI,QAAQ,CAAC,QAAQ,EAAE,CAAC;gBACtB,QAAQ,CAAC,IAAI,CAAC,GAAI,QAAQ,CAAC,QAAsB,CAAC,CAAC;YACrD,CAAC;YAED,MAAM,GAAG,QAAQ,CAAC,iBAAiB,EAAE,WAAW,CAAC;QACnD,CAAC,QAAQ,MAAM,EAAE;QAEjB,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,KAAK,CAAC,kBAAkB;QACtB,gDAAgD;QAChD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC;YACpD,KAAK,EAAE,wCAAwC;YAC/C,gBAAgB,EAAE,IAAI;YACtB,KAAK,EAAE,IAAI;SACZ,CAAC,CAAC;QAEH,MAAM,QAAQ,GAAG,QAAQ,CAAC,QAAqB,CAAC;QAChD,MAAM,kBAAkB,GAAc,EAAE,CAAC;QAEzC,8DAA8D;QAC9D,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC/B,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC;oBAChD,OAAO,EAAE,OAAO,CAAC,EAAE;oBACnB,mBAAmB,EAAE,KAAK;iBAC3B,CAAC,CAAC;gBACH,MAAM,WAAW,GAAG,IAAI,CAAC,OAAgC,CAAC;gBAE1D,wCAAwC;gBACxC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC;oBACtD,OAAO,EAAE,OAAO,CAAC,EAAE;oBACnB,KAAK,EAAE,CAAC;iBACT,CAAC,CAAC;gBAEH,sDAAsD;gBACtD,IAAI,WAAW,CAAC,SAAS,EAAE,CAAC;oBAC1B,iCAAiC;oBACjC,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC;wBAC5D,OAAO,EAAE,OAAO,CAAC,EAAE;wBACnB,MAAM,EAAE,WAAW,CAAC,SAAS;wBAC7B,KAAK,EAAE,GAAG,EAAE,gCAAgC;qBAC7C,CAAC,CAAC;oBAEH,MAAM,WAAW,GAAG,aAAa,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAC,CAAC;oBACxD,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;wBACpB,kBAAkB,CAAC,IAAI,CAAC;4BACtB,GAAG,OAAO;4BACV,YAAY,EAAE,WAAW;4BACzB,oBAAoB,EAAE,WAAW;4BACjC,SAAS,EAAE,WAAW,CAAC,SAAS;yBACjC,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC;qBAAM,IAAI,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAC3D,2CAA2C;oBAC3C,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC;wBACzD,OAAO,EAAE,OAAO,CAAC,EAAE;wBACnB,KAAK,EAAE,GAAG;qBACX,CAAC,CAAC;oBACH,MAAM,WAAW,GAAG,UAAU,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAC,CAAC;oBAErD,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;wBACpB,kBAAkB,CAAC,IAAI,CAAC;4BACtB,GAAG,OAAO;4BACV,YAAY,EAAE,WAAW;4BACzB,oBAAoB,EAAE,WAAW;4BACjC,SAAS,EAAE,WAAW,CAAC,SAAS;yBACjC,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC;gBAED,qDAAqD;gBACrD,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YACxB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,0BAA0B;gBAC1B,MAAM,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;YACpC,CAAC;QACH,CAAC;QAED,OAAO,kBAAkB,CAAC;IAC5B,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,eAAuB;QAC1C,MAAM,SAAS,GAAG,MAAM,kCAAe,CAAC,gBAAgB,CAAC,eAAe,EAAE,GAAG,EAAE,CAC7E,IAAI,CAAC,YAAY,CAAC;YAChB,KAAK,EAAE,wCAAwC;YAC/C,gBAAgB,EAAE,IAAI;YACtB,KAAK,EAAE,oBAAQ,CAAC,cAAc;SAC/B,CAAC,CACH,CAAC;QAEF,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC;YAChD,OAAO,EAAE,SAAS;SACnB,CAAC,CAAC;QAEH,OAAO,IAAI,CAAC,OAAgC,CAAC;IAC/C,CAAC;CACF;AAhHD,8CAgHC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message-operations.d.ts","sourceRoot":"","sources":["../../../src/utils/slack-operations/message-operations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAGhD,OAAO,EAAW,cAAc,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAGlG,qBAAa,iBAAkB,SAAQ,eAAe;IACpD,OAAO,CAAC,UAAU,CAAoB;gBAE1B,KAAK,EAAE,MAAM;IAKnB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,CAAC;IAO5E,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC;IAyB5E,gBAAgB,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"message-operations.d.ts","sourceRoot":"","sources":["../../../src/utils/slack-operations/message-operations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAGhD,OAAO,EAAW,cAAc,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAGlG,qBAAa,iBAAkB,SAAQ,eAAe;IACpD,OAAO,CAAC,UAAU,CAAoB;gBAE1B,KAAK,EAAE,MAAM;IAKnB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,CAAC;IAO5E,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC;IAyB5E,gBAAgB,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;YAsC/D,aAAa;CAmB5B"}
|
|
@@ -39,19 +39,31 @@ class MessageOperations extends base_client_1.BaseSlackClient {
|
|
|
39
39
|
// Get unread messages
|
|
40
40
|
let messages = [];
|
|
41
41
|
let users = new Map();
|
|
42
|
-
|
|
42
|
+
let actualUnreadCount = 0;
|
|
43
|
+
if (channel.last_read) {
|
|
44
|
+
// Always fetch messages after last_read to get accurate unread count
|
|
43
45
|
const historyResult = await this.getHistory(channel.id, {
|
|
44
|
-
limit:
|
|
46
|
+
limit: 100, // Fetch up to 100 messages after last_read
|
|
45
47
|
oldest: channel.last_read,
|
|
46
48
|
});
|
|
47
49
|
messages = historyResult.messages;
|
|
48
50
|
users = historyResult.users;
|
|
51
|
+
actualUnreadCount = messages.length;
|
|
52
|
+
}
|
|
53
|
+
else if (!channel.last_read) {
|
|
54
|
+
// If no last_read, all messages are unread
|
|
55
|
+
const historyResult = await this.getHistory(channel.id, {
|
|
56
|
+
limit: 100,
|
|
57
|
+
});
|
|
58
|
+
messages = historyResult.messages;
|
|
59
|
+
users = historyResult.users;
|
|
60
|
+
actualUnreadCount = messages.length;
|
|
49
61
|
}
|
|
50
62
|
return {
|
|
51
63
|
channel: {
|
|
52
64
|
...channel,
|
|
53
|
-
unread_count:
|
|
54
|
-
unread_count_display:
|
|
65
|
+
unread_count: actualUnreadCount,
|
|
66
|
+
unread_count_display: actualUnreadCount,
|
|
55
67
|
},
|
|
56
68
|
messages,
|
|
57
69
|
users,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message-operations.js","sourceRoot":"","sources":["../../../src/utils/slack-operations/message-operations.ts"],"names":[],"mappings":";;;AACA,+CAAgD;AAChD,0DAAsD;AACtD,4CAAwC;AAExC,6DAAyD;AAEzD,MAAa,iBAAkB,SAAQ,6BAAe;IAGpD,YAAY,KAAa;QACvB,KAAK,CAAC,KAAK,CAAC,CAAC;QACb,IAAI,CAAC,UAAU,GAAG,IAAI,sCAAiB,CAAC,KAAK,CAAC,CAAC;IACjD,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,OAAe,EAAE,IAAY;QAC7C,OAAO,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC;YACxC,OAAO;YACP,IAAI;SACL,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,OAAe,EAAE,OAAuB;QACvD,uCAAuC;QACvC,MAAM,SAAS,GAAG,MAAM,kCAAe,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE,CACrE,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC;YAC3B,KAAK,EAAE,wCAAwC;YAC/C,gBAAgB,EAAE,IAAI;YACtB,KAAK,EAAE,oBAAQ,CAAC,cAAc;SAC/B,CAAC,CACH,CAAC;QAEF,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC;YACvD,OAAO,EAAE,SAAS;YAClB,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,MAAM,EAAE,OAAO,CAAC,MAAM;SACvB,CAAC,CAAC;QAEH,MAAM,QAAQ,GAAG,QAAQ,CAAC,QAAqB,CAAC;QAEhD,sBAAsB;QACtB,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAK,CAAC,CAAC,CAAC,CAAC;QACjF,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QAEhD,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;IAC7B,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,eAAuB;QAC5C,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC;QAEtE,sBAAsB;QACtB,IAAI,QAAQ,GAAc,EAAE,CAAC;QAC7B,IAAI,KAAK,GAAG,IAAI,GAAG,EAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"message-operations.js","sourceRoot":"","sources":["../../../src/utils/slack-operations/message-operations.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -59,38 +59,33 @@ export class ChannelOperations extends BaseSlackClient {
|
|
|
59
59
|
limit: 1,
|
|
60
60
|
});
|
|
61
61
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
62
|
+
// Always check for messages after last_read timestamp
|
|
63
|
+
if (channelInfo.last_read) {
|
|
64
|
+
// Fetch messages after last_read
|
|
65
|
+
const unreadHistory = await this.client.conversations.history({
|
|
66
|
+
channel: channel.id,
|
|
67
|
+
oldest: channelInfo.last_read,
|
|
68
|
+
limit: 100, // Get up to 100 unread messages
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
const unreadCount = unreadHistory.messages?.length || 0;
|
|
72
|
+
if (unreadCount > 0) {
|
|
73
|
+
channelsWithUnread.push({
|
|
74
|
+
...channel,
|
|
75
|
+
unread_count: unreadCount,
|
|
76
|
+
unread_count_display: unreadCount,
|
|
77
|
+
last_read: channelInfo.last_read,
|
|
73
78
|
});
|
|
74
|
-
unreadCount = allHistory.messages?.length || 0;
|
|
75
|
-
} else {
|
|
76
|
-
// Check if there are messages after last_read
|
|
77
|
-
const latestMessage = history.messages[0];
|
|
78
|
-
const lastReadTs = parseFloat(channelInfo.last_read!);
|
|
79
|
-
const latestMessageTs = parseFloat(latestMessage.ts || '0');
|
|
80
|
-
|
|
81
|
-
if (latestMessageTs > lastReadTs) {
|
|
82
|
-
hasUnread = true;
|
|
83
|
-
// Calculate unread count by fetching messages after last_read
|
|
84
|
-
const unreadHistory = await this.client.conversations.history({
|
|
85
|
-
channel: channel.id,
|
|
86
|
-
oldest: channelInfo.last_read,
|
|
87
|
-
limit: 100, // Get up to 100 unread messages
|
|
88
|
-
});
|
|
89
|
-
unreadCount = unreadHistory.messages?.length || 0;
|
|
90
|
-
}
|
|
91
79
|
}
|
|
92
|
-
|
|
93
|
-
|
|
80
|
+
} else if (history.messages && history.messages.length > 0) {
|
|
81
|
+
// If no last_read, all messages are unread
|
|
82
|
+
const allHistory = await this.client.conversations.history({
|
|
83
|
+
channel: channel.id,
|
|
84
|
+
limit: 100,
|
|
85
|
+
});
|
|
86
|
+
const unreadCount = allHistory.messages?.length || 0;
|
|
87
|
+
|
|
88
|
+
if (unreadCount > 0) {
|
|
94
89
|
channelsWithUnread.push({
|
|
95
90
|
...channel,
|
|
96
91
|
unread_count: unreadCount,
|
|
@@ -51,21 +51,32 @@ export class MessageOperations extends BaseSlackClient {
|
|
|
51
51
|
// Get unread messages
|
|
52
52
|
let messages: Message[] = [];
|
|
53
53
|
let users = new Map<string, string>();
|
|
54
|
+
let actualUnreadCount = 0;
|
|
54
55
|
|
|
55
|
-
if (channel.last_read
|
|
56
|
+
if (channel.last_read) {
|
|
57
|
+
// Always fetch messages after last_read to get accurate unread count
|
|
56
58
|
const historyResult = await this.getHistory(channel.id, {
|
|
57
|
-
limit:
|
|
59
|
+
limit: 100, // Fetch up to 100 messages after last_read
|
|
58
60
|
oldest: channel.last_read,
|
|
59
61
|
});
|
|
60
62
|
messages = historyResult.messages;
|
|
61
63
|
users = historyResult.users;
|
|
64
|
+
actualUnreadCount = messages.length;
|
|
65
|
+
} else if (!channel.last_read) {
|
|
66
|
+
// If no last_read, all messages are unread
|
|
67
|
+
const historyResult = await this.getHistory(channel.id, {
|
|
68
|
+
limit: 100,
|
|
69
|
+
});
|
|
70
|
+
messages = historyResult.messages;
|
|
71
|
+
users = historyResult.users;
|
|
72
|
+
actualUnreadCount = messages.length;
|
|
62
73
|
}
|
|
63
74
|
|
|
64
75
|
return {
|
|
65
76
|
channel: {
|
|
66
77
|
...channel,
|
|
67
|
-
unread_count:
|
|
68
|
-
unread_count_display:
|
|
78
|
+
unread_count: actualUnreadCount,
|
|
79
|
+
unread_count_display: actualUnreadCount,
|
|
69
80
|
},
|
|
70
81
|
messages,
|
|
71
82
|
users,
|
|
@@ -276,4 +276,45 @@ describe('unread command', () => {
|
|
|
276
276
|
expect(mockSlackClient.listUnreadChannels).toHaveBeenCalledTimes(1);
|
|
277
277
|
});
|
|
278
278
|
});
|
|
279
|
+
|
|
280
|
+
describe('last_read timestamp handling', () => {
|
|
281
|
+
it('should fetch messages after last_read timestamp even when unread_count is 0', async () => {
|
|
282
|
+
vi.mocked(mockConfigManager.getConfig).mockResolvedValue({
|
|
283
|
+
token: 'test-token',
|
|
284
|
+
updatedAt: new Date().toISOString()
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
const channelWithLastRead = {
|
|
288
|
+
id: 'C08JFKGJPPE',
|
|
289
|
+
name: 'dev_kiban_jira',
|
|
290
|
+
is_channel: true,
|
|
291
|
+
is_member: true,
|
|
292
|
+
is_archived: false,
|
|
293
|
+
unread_count: 0,
|
|
294
|
+
unread_count_display: 0,
|
|
295
|
+
last_read: '1750646034.663209',
|
|
296
|
+
is_private: false,
|
|
297
|
+
created: 1742353688
|
|
298
|
+
};
|
|
299
|
+
|
|
300
|
+
const unreadMessage = {
|
|
301
|
+
ts: '1750646072.447069',
|
|
302
|
+
user: 'U5F87BSGP',
|
|
303
|
+
text: '@Suguru Sakashita / 阪下 駿 transitioned ES-4359 ArgumentError: \'発行者\' is not a valid field_name in Clip',
|
|
304
|
+
type: 'message',
|
|
305
|
+
};
|
|
306
|
+
|
|
307
|
+
vi.mocked(mockSlackClient.getChannelUnread).mockResolvedValue({
|
|
308
|
+
channel: { ...channelWithLastRead, unread_count: 1, unread_count_display: 1 },
|
|
309
|
+
messages: [unreadMessage],
|
|
310
|
+
users: new Map([['U5F87BSGP', 'jira-bot']])
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
await program.parseAsync(['node', 'slack-cli', 'unread', '--channel', 'dev_kiban_jira']);
|
|
314
|
+
|
|
315
|
+
expect(mockSlackClient.getChannelUnread).toHaveBeenCalledWith('dev_kiban_jira');
|
|
316
|
+
expect(mockConsole.logSpy).toHaveBeenCalledWith(chalk.bold('#dev_kiban_jira: 1 unread messages'));
|
|
317
|
+
expect(mockConsole.logSpy).toHaveBeenCalledWith(expect.stringContaining('transitioned ES-4359'));
|
|
318
|
+
});
|
|
319
|
+
});
|
|
279
320
|
});
|
|
@@ -172,10 +172,15 @@ describe('ChannelOperations', () => {
|
|
|
172
172
|
},
|
|
173
173
|
});
|
|
174
174
|
|
|
175
|
-
//
|
|
176
|
-
mockClient.conversations.history.
|
|
175
|
+
// First call to get latest message (limit: 1)
|
|
176
|
+
mockClient.conversations.history.mockResolvedValueOnce({
|
|
177
177
|
messages: [{ ts: '1234567890.000100' }],
|
|
178
178
|
});
|
|
179
|
+
|
|
180
|
+
// Second call to get messages after last_read (should be empty)
|
|
181
|
+
mockClient.conversations.history.mockResolvedValueOnce({
|
|
182
|
+
messages: [],
|
|
183
|
+
});
|
|
179
184
|
|
|
180
185
|
const result = await channelOps.listUnreadChannels();
|
|
181
186
|
|