@zhin.js/adapter-slack 1.1.2 → 1.1.4
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 +28 -0
- package/lib/side-event-dispatch.d.ts +1 -1
- package/lib/side-event-dispatch.js +32 -14
- package/package.json +16 -16
- package/src/side-event-dispatch.ts +35 -16
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,33 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.1.4
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 43eda99: Unify Notice and Request payloads with their public types and runtime exports. Use camelCase fields, preserve native data under metadata, and bind canonical endpoint identity and request actions to the held generation. Remove legacy data aliases and from factories.
|
|
8
|
+
|
|
9
|
+
Keep login and lifecycle signals as independent SystemEvent payloads on system.receive, without chat conversation fields or user interaction. Update built-in adapter projections and authoring guidance.
|
|
10
|
+
|
|
11
|
+
- Updated dependencies [43eda99]
|
|
12
|
+
- Updated dependencies [0de4836]
|
|
13
|
+
- @zhin.js/core@1.1.39
|
|
14
|
+
- @zhin.js/adapter@1.1.15
|
|
15
|
+
|
|
16
|
+
## 1.1.3
|
|
17
|
+
|
|
18
|
+
### Patch Changes
|
|
19
|
+
|
|
20
|
+
- Updated dependencies [5b5d270]
|
|
21
|
+
- Updated dependencies [36c2eb9]
|
|
22
|
+
- @zhin.js/im-contract@1.1.2
|
|
23
|
+
- @zhin.js/core@1.1.38
|
|
24
|
+
- @zhin.js/adapter@1.1.15
|
|
25
|
+
- @zhin.js/host-http@1.1.2
|
|
26
|
+
- @zhin.js/agent-feature@1.1.2
|
|
27
|
+
- @zhin.js/feature-kit@1.1.2
|
|
28
|
+
- @zhin.js/skill@1.1.2
|
|
29
|
+
- @zhin.js/tool@1.1.2
|
|
30
|
+
|
|
3
31
|
## 1.1.2
|
|
4
32
|
|
|
5
33
|
### Patch Changes
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { EndpointEventEmitter } from 'zhin.js/adapter';
|
|
2
2
|
import { type getAdapterLogger } from '@zhin.js/logger';
|
|
3
|
-
import type
|
|
3
|
+
import { type SlackEvent } from './protocol.js';
|
|
4
4
|
export declare function receiveSlackSideEvent(emit: EndpointEventEmitter, endpointKey: string, configId: string, event: SlackEvent, logger: ReturnType<typeof getAdapterLogger>): void;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { buildNotice, mapNoticeParts, senderFromId, SLACK_NOTICE_PARTS_MAP } from '@zhin.js/core';
|
|
1
|
+
import { composeSideEventName, buildNotice, mapNoticeParts, senderFromId, SLACK_NOTICE_PARTS_MAP } from '@zhin.js/core';
|
|
2
2
|
import { formatCompact } from '@zhin.js/logger';
|
|
3
|
+
import { slackInboundConversation } from './protocol.js';
|
|
3
4
|
export function receiveSlackSideEvent(emit, endpointKey, configId, event, logger) {
|
|
4
5
|
if (!emit)
|
|
5
6
|
return;
|
|
@@ -8,9 +9,18 @@ export function receiveSlackSideEvent(emit, endpointKey, configId, event, logger
|
|
|
8
9
|
return;
|
|
9
10
|
const record = event;
|
|
10
11
|
const parts = mapNoticeParts('slack', eventType);
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
const
|
|
12
|
+
const item = asRecord(record.item);
|
|
13
|
+
const channel = stringField(record.channel) ?? stringField(asRecord(record.channel).id) ?? stringField(item.channel);
|
|
14
|
+
const user = stringField(record.user) ?? stringField(asRecord(record.user).id);
|
|
15
|
+
const conversation = channel ? slackInboundConversation(endpointKey, {
|
|
16
|
+
channelId: channel,
|
|
17
|
+
channelType: stringField(record.channel_type) ?? stringField(item.channel_type),
|
|
18
|
+
threadId: stringField(record.thread_ts),
|
|
19
|
+
}) : undefined;
|
|
20
|
+
const sceneType = parts.scene_type === 'group' && conversation?.kind === 'private'
|
|
21
|
+
? 'friend' : parts.scene_type;
|
|
22
|
+
const memberEvent = eventType === 'member_joined_channel' || eventType === 'member_left_channel' || eventType === 'team_join';
|
|
23
|
+
const reactionEvent = eventType === 'reaction_added' || eventType === 'reaction_removed';
|
|
14
24
|
const dedupeKey = [
|
|
15
25
|
eventType,
|
|
16
26
|
channel ?? '',
|
|
@@ -18,16 +28,18 @@ export function receiveSlackSideEvent(emit, endpointKey, configId, event, logger
|
|
|
18
28
|
String(record.ts ?? record.event_ts ?? ''),
|
|
19
29
|
].join(':');
|
|
20
30
|
void emit('notice.receive', buildNotice(record, {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
+
id: `slack:${dedupeKey}`,
|
|
32
|
+
clientAdapter: 'slack',
|
|
33
|
+
endpointId: configId,
|
|
34
|
+
type: 'notice',
|
|
35
|
+
conversation,
|
|
36
|
+
name: composeSideEventName('notice', sceneType, parts.sub_type),
|
|
37
|
+
actor: memberEvent ? undefined : senderFromId(user),
|
|
38
|
+
target: senderFromId(memberEvent ? user : stringField(record.item_user)),
|
|
39
|
+
messageId: reactionEvent ? stringField(item.ts) : stringField(record.deleted_ts),
|
|
40
|
+
reaction: reactionEvent ? stringField(record.reaction) : undefined,
|
|
41
|
+
operation: reactionEvent ? (eventType === 'reaction_removed' ? 'removed' : 'added') : undefined,
|
|
42
|
+
timestamp: toMillis(record.event_ts ?? record.ts),
|
|
31
43
|
})).catch((err) => {
|
|
32
44
|
logger.warn(formatCompact({
|
|
33
45
|
op: 'slack_side_event_failed',
|
|
@@ -43,3 +55,9 @@ function toMillis(time) {
|
|
|
43
55
|
return Date.now();
|
|
44
56
|
return value < 1e12 ? Math.round(value * 1000) : Math.round(value);
|
|
45
57
|
}
|
|
58
|
+
function asRecord(value) {
|
|
59
|
+
return value && typeof value === 'object' ? value : {};
|
|
60
|
+
}
|
|
61
|
+
function stringField(value) {
|
|
62
|
+
return typeof value === 'string' && value.length > 0 ? value : undefined;
|
|
63
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zhin.js/adapter-slack",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.4",
|
|
4
4
|
"description": "Zhin.js Slack adapter for Plugin Runtime (Socket Mode / HTTP Events)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./lib/index.js",
|
|
@@ -34,24 +34,24 @@
|
|
|
34
34
|
"dependencies": {
|
|
35
35
|
"@slack/socket-mode": "^2.0.7",
|
|
36
36
|
"@slack/web-api": "^7.19.0",
|
|
37
|
-
"@zhin.js/adapter": "1.1.
|
|
38
|
-
"@zhin.js/agent-feature": "1.1.
|
|
39
|
-
"@zhin.js/core": "1.1.
|
|
40
|
-
"@zhin.js/feature-kit": "1.1.
|
|
41
|
-
"@zhin.js/host-http": "1.1.
|
|
42
|
-
"@zhin.js/im-contract": "1.1.
|
|
37
|
+
"@zhin.js/adapter": "1.1.15",
|
|
38
|
+
"@zhin.js/agent-feature": "1.1.2",
|
|
39
|
+
"@zhin.js/core": "1.1.39",
|
|
40
|
+
"@zhin.js/feature-kit": "1.1.2",
|
|
41
|
+
"@zhin.js/host-http": "1.1.2",
|
|
42
|
+
"@zhin.js/im-contract": "1.1.2",
|
|
43
43
|
"@zhin.js/logger": "1.1.1",
|
|
44
|
-
"@zhin.js/skill": "1.1.
|
|
45
|
-
"@zhin.js/tool": "1.1.
|
|
44
|
+
"@zhin.js/skill": "1.1.2",
|
|
45
|
+
"@zhin.js/tool": "1.1.2"
|
|
46
46
|
},
|
|
47
47
|
"peerDependencies": {
|
|
48
48
|
"zod": "^4.0.0",
|
|
49
|
-
"@zhin.js/adapter": "^1.1.
|
|
50
|
-
"@zhin.js/command": "^1.1.
|
|
51
|
-
"@zhin.js/core": "^1.1.
|
|
52
|
-
"@zhin.js/host-http": "^1.1.
|
|
53
|
-
"@zhin.js/permission": "^1.1.
|
|
54
|
-
"zhin.js": "^1.1.
|
|
49
|
+
"@zhin.js/adapter": "^1.1.15",
|
|
50
|
+
"@zhin.js/command": "^1.1.3",
|
|
51
|
+
"@zhin.js/core": "^1.1.39",
|
|
52
|
+
"@zhin.js/host-http": "^1.1.2",
|
|
53
|
+
"@zhin.js/permission": "^1.1.3",
|
|
54
|
+
"zhin.js": "^1.1.4"
|
|
55
55
|
},
|
|
56
56
|
"peerDependenciesMeta": {
|
|
57
57
|
"@zhin.js/command": {
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
"typescript": "^6.0.3",
|
|
70
70
|
"vitest": "^4.1.10",
|
|
71
71
|
"zod": "^4.4.3",
|
|
72
|
-
"zhin.js": "1.1.
|
|
72
|
+
"zhin.js": "1.1.4"
|
|
73
73
|
},
|
|
74
74
|
"files": [
|
|
75
75
|
"adapters",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { buildNotice, mapNoticeParts, senderFromId, SLACK_NOTICE_PARTS_MAP } from '@zhin.js/core';
|
|
1
|
+
import { composeSideEventName, buildNotice, mapNoticeParts, senderFromId, SLACK_NOTICE_PARTS_MAP } from '@zhin.js/core';
|
|
2
2
|
import type { EndpointEventEmitter } from 'zhin.js/adapter';
|
|
3
3
|
import { formatCompact, type getAdapterLogger } from '@zhin.js/logger';
|
|
4
|
-
import type
|
|
4
|
+
import { slackInboundConversation, type SlackEvent } from './protocol.js';
|
|
5
5
|
|
|
6
6
|
export function receiveSlackSideEvent(
|
|
7
7
|
emit: EndpointEventEmitter,
|
|
@@ -15,9 +15,18 @@ export function receiveSlackSideEvent(
|
|
|
15
15
|
if (!Object.prototype.hasOwnProperty.call(SLACK_NOTICE_PARTS_MAP, eventType)) return;
|
|
16
16
|
const record = event as Record<string, unknown>;
|
|
17
17
|
const parts = mapNoticeParts('slack', eventType);
|
|
18
|
-
const
|
|
19
|
-
const
|
|
20
|
-
const
|
|
18
|
+
const item = asRecord(record.item);
|
|
19
|
+
const channel = stringField(record.channel) ?? stringField(asRecord(record.channel).id) ?? stringField(item.channel);
|
|
20
|
+
const user = stringField(record.user) ?? stringField(asRecord(record.user).id);
|
|
21
|
+
const conversation = channel ? slackInboundConversation(endpointKey, {
|
|
22
|
+
channelId: channel,
|
|
23
|
+
channelType: stringField(record.channel_type) ?? stringField(item.channel_type),
|
|
24
|
+
threadId: stringField(record.thread_ts),
|
|
25
|
+
}) : undefined;
|
|
26
|
+
const sceneType = parts.scene_type === 'group' && conversation?.kind === 'private'
|
|
27
|
+
? 'friend' : parts.scene_type;
|
|
28
|
+
const memberEvent = eventType === 'member_joined_channel' || eventType === 'member_left_channel' || eventType === 'team_join';
|
|
29
|
+
const reactionEvent = eventType === 'reaction_added' || eventType === 'reaction_removed';
|
|
21
30
|
const dedupeKey = [
|
|
22
31
|
eventType,
|
|
23
32
|
channel ?? '',
|
|
@@ -25,18 +34,20 @@ export function receiveSlackSideEvent(
|
|
|
25
34
|
String(record.ts ?? record.event_ts ?? ''),
|
|
26
35
|
].join(':');
|
|
27
36
|
void emit('notice.receive', buildNotice(record, {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
typeof record.item_user === 'string' ? record.item_user : undefined,
|
|
37
|
+
id: `slack:${dedupeKey}`,
|
|
38
|
+
clientAdapter: 'slack',
|
|
39
|
+
endpointId: configId,
|
|
40
|
+
type: 'notice',
|
|
41
|
+
conversation,
|
|
42
|
+
name: composeSideEventName('notice', sceneType, parts.sub_type),
|
|
43
|
+
actor: memberEvent ? undefined : senderFromId(user),
|
|
44
|
+
target: senderFromId(
|
|
45
|
+
memberEvent ? user : stringField(record.item_user),
|
|
38
46
|
),
|
|
39
|
-
|
|
47
|
+
messageId: reactionEvent ? stringField(item.ts) : stringField(record.deleted_ts),
|
|
48
|
+
reaction: reactionEvent ? stringField(record.reaction) : undefined,
|
|
49
|
+
operation: reactionEvent ? (eventType === 'reaction_removed' ? 'removed' : 'added') : undefined,
|
|
50
|
+
timestamp: toMillis(record.event_ts ?? record.ts),
|
|
40
51
|
})).catch((err) => {
|
|
41
52
|
logger.warn(formatCompact({
|
|
42
53
|
op: 'slack_side_event_failed',
|
|
@@ -52,3 +63,11 @@ function toMillis(time: unknown): number {
|
|
|
52
63
|
if (!Number.isFinite(value) || value <= 0) return Date.now();
|
|
53
64
|
return value < 1e12 ? Math.round(value * 1000) : Math.round(value);
|
|
54
65
|
}
|
|
66
|
+
|
|
67
|
+
function asRecord(value: unknown): Record<string, unknown> {
|
|
68
|
+
return value && typeof value === 'object' ? value as Record<string, unknown> : {};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function stringField(value: unknown): string | undefined {
|
|
72
|
+
return typeof value === 'string' && value.length > 0 ? value : undefined;
|
|
73
|
+
}
|