alemonjs 2.1.82 → 2.1.83-alpha.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.
Files changed (42) hide show
  1. package/lib/app/event-error.d.ts +2 -0
  2. package/lib/app/event-error.js +20 -0
  3. package/lib/app/event-processor-callHandler.d.ts +5 -1
  4. package/lib/app/event-processor-callHandler.js +18 -2
  5. package/lib/app/event-processor-cycleFiles.d.ts +4 -1
  6. package/lib/app/event-processor-cycleFiles.js +21 -6
  7. package/lib/app/event-processor-cycleRoute.d.ts +4 -1
  8. package/lib/app/event-processor-cycleRoute.js +16 -2
  9. package/lib/app/event-processor-event.js +2 -2
  10. package/lib/app/event-processor-middleware.js +2 -2
  11. package/lib/app/event-processor-subscribe.js +31 -3
  12. package/lib/app/event-processor.js +6 -1
  13. package/lib/app/hook-event-context.d.ts +7 -3
  14. package/lib/app/hook-event-context.js +24 -5
  15. package/lib/app/hook-use/subscribe.js +3 -1
  16. package/lib/app/index.js +2 -2
  17. package/lib/app/lifecycle-callbacks.d.ts +14 -0
  18. package/lib/app/lifecycle-callbacks.js +99 -0
  19. package/lib/app/load_modules/loadChild.js +13 -10
  20. package/lib/app/router/dsl.js +2 -2
  21. package/lib/app/store.d.ts +2 -0
  22. package/lib/app/store.js +31 -5
  23. package/lib/cbp/connects/client.js +34 -32
  24. package/lib/cbp/connects/platform.js +45 -68
  25. package/lib/cbp/normalize.d.ts +16 -0
  26. package/lib/cbp/normalize.js +328 -0
  27. package/lib/cbp/processor/actions.js +15 -13
  28. package/lib/cbp/processor/api.js +15 -13
  29. package/lib/cbp/processor/config.d.ts +8 -4
  30. package/lib/cbp/processor/config.js +9 -5
  31. package/lib/cbp/server/main.js +28 -30
  32. package/lib/cbp/typings.d.ts +139 -0
  33. package/lib/client.js +11 -7
  34. package/lib/core/config.d.ts +3 -3
  35. package/lib/index.js +2 -2
  36. package/lib/server/routers/router.js +111 -17
  37. package/lib/types/actions.d.ts +20 -1
  38. package/lib/types/apis.d.ts +2 -1
  39. package/lib/types/cycle/index.d.ts +50 -0
  40. package/lib/types/event/index.d.ts +1 -0
  41. package/lib/types/subscribe/index.d.ts +1 -0
  42. package/package.json +1 -1
@@ -0,0 +1,328 @@
1
+ const now = () => Date.now();
2
+ const asRecord = (value) => {
3
+ return value && typeof value === 'object' && !Array.isArray(value) ? value : {};
4
+ };
5
+ const asResults = (value) => {
6
+ return Array.isArray(value) ? value : [];
7
+ };
8
+ const inferEventRouteId = (event) => {
9
+ const channelId = event.ChannelId;
10
+ const guildId = event.GuildId;
11
+ const deviceId = event.DeviceId;
12
+ if (typeof channelId === 'string' && channelId) {
13
+ return channelId;
14
+ }
15
+ if (typeof guildId === 'string' && guildId) {
16
+ return guildId;
17
+ }
18
+ if (typeof deviceId === 'string' && deviceId) {
19
+ return deviceId;
20
+ }
21
+ return undefined;
22
+ };
23
+ const createRequestEnvelope = (type, id, deviceId, payload) => {
24
+ return {
25
+ protocol: 'cbp',
26
+ version: 1,
27
+ type,
28
+ id,
29
+ timestamp: now(),
30
+ source: {
31
+ role: 'app-client',
32
+ deviceId
33
+ },
34
+ payload
35
+ };
36
+ };
37
+ const createResponseEnvelope = (type, replyTo, deviceId, payload, error) => {
38
+ return {
39
+ protocol: 'cbp',
40
+ version: 1,
41
+ type,
42
+ id: `${replyTo}:res`,
43
+ replyTo,
44
+ timestamp: now(),
45
+ source: {
46
+ role: 'platform',
47
+ deviceId
48
+ },
49
+ target: {
50
+ role: 'app-client',
51
+ deviceId
52
+ },
53
+ payload: {
54
+ results: payload
55
+ },
56
+ error
57
+ };
58
+ };
59
+ const normalizeEnvelopeMessage = (input) => {
60
+ const payload = input.payload;
61
+ const meta = asRecord(input.meta);
62
+ const deviceId = input.source?.deviceId ?? input.target?.deviceId;
63
+ const sourceRole = input.source?.role;
64
+ const targetRole = input.target?.role;
65
+ switch (input.type) {
66
+ case 'event': {
67
+ const eventPayload = asRecord(payload);
68
+ const event = asRecord(eventPayload.event);
69
+ return {
70
+ kind: 'event',
71
+ id: input.id,
72
+ timestamp: input.timestamp,
73
+ deviceId,
74
+ sourceRole,
75
+ targetRole,
76
+ eventName: String(eventPayload.name ?? ''),
77
+ event,
78
+ raw: eventPayload.raw,
79
+ meta
80
+ };
81
+ }
82
+ case 'action.req': {
83
+ const actionPayload = asRecord(payload);
84
+ return {
85
+ kind: 'action.req',
86
+ id: input.id,
87
+ timestamp: input.timestamp,
88
+ deviceId,
89
+ sourceRole,
90
+ targetRole,
91
+ action: String(actionPayload.action ?? ''),
92
+ input: asRecord(actionPayload.input),
93
+ meta
94
+ };
95
+ }
96
+ case 'action.res':
97
+ return {
98
+ kind: 'action.res',
99
+ id: input.id,
100
+ replyTo: String(input.replyTo ?? ''),
101
+ timestamp: input.timestamp,
102
+ deviceId,
103
+ sourceRole,
104
+ targetRole,
105
+ results: asResults(asRecord(payload).results),
106
+ error: input.error,
107
+ meta
108
+ };
109
+ case 'api.req': {
110
+ const apiPayload = asRecord(payload);
111
+ return {
112
+ kind: 'api.req',
113
+ id: input.id,
114
+ timestamp: input.timestamp,
115
+ deviceId,
116
+ sourceRole,
117
+ targetRole,
118
+ api: String(apiPayload.api ?? ''),
119
+ input: asRecord(apiPayload.input),
120
+ meta
121
+ };
122
+ }
123
+ case 'api.res':
124
+ return {
125
+ kind: 'api.res',
126
+ id: input.id,
127
+ replyTo: String(input.replyTo ?? ''),
128
+ timestamp: input.timestamp,
129
+ deviceId,
130
+ sourceRole,
131
+ targetRole,
132
+ results: asResults(asRecord(payload).results),
133
+ error: input.error,
134
+ meta
135
+ };
136
+ case 'control': {
137
+ const controlPayload = asRecord(payload);
138
+ return {
139
+ kind: 'control',
140
+ id: input.id,
141
+ timestamp: input.timestamp,
142
+ deviceId,
143
+ sourceRole,
144
+ targetRole,
145
+ op: String(controlPayload.op ?? 'error'),
146
+ payload: controlPayload,
147
+ error: input.error,
148
+ meta
149
+ };
150
+ }
151
+ default:
152
+ return null;
153
+ }
154
+ };
155
+ const normalizeLegacyMessage = (input) => {
156
+ if (input?.apiId) {
157
+ if (Array.isArray(input.payload)) {
158
+ return {
159
+ kind: 'api.res',
160
+ id: String(input.apiId),
161
+ replyTo: String(input.apiId),
162
+ timestamp: now(),
163
+ deviceId: typeof input.DeviceId === 'string' ? input.DeviceId : undefined,
164
+ results: input.payload,
165
+ meta: {}
166
+ };
167
+ }
168
+ return {
169
+ kind: 'api.req',
170
+ id: String(input.apiId),
171
+ timestamp: now(),
172
+ deviceId: typeof input.DeviceId === 'string' ? input.DeviceId : undefined,
173
+ api: typeof input.action === 'string' ? input.action : '',
174
+ input: asRecord(input.payload),
175
+ meta: {}
176
+ };
177
+ }
178
+ if (input?.actionId) {
179
+ if (Array.isArray(input.payload)) {
180
+ return {
181
+ kind: 'action.res',
182
+ id: String(input.actionId),
183
+ replyTo: String(input.actionId),
184
+ timestamp: now(),
185
+ deviceId: typeof input.DeviceId === 'string' ? input.DeviceId : undefined,
186
+ results: input.payload,
187
+ meta: {}
188
+ };
189
+ }
190
+ return {
191
+ kind: 'action.req',
192
+ id: String(input.actionId),
193
+ timestamp: now(),
194
+ deviceId: typeof input.DeviceId === 'string' ? input.DeviceId : undefined,
195
+ action: typeof input.action === 'string' ? input.action : '',
196
+ input: asRecord(input.payload),
197
+ meta: {}
198
+ };
199
+ }
200
+ if (input?.activeId && input?.active === 'sync') {
201
+ const payload = asRecord(input.payload);
202
+ return {
203
+ kind: 'control',
204
+ id: String(input.activeId),
205
+ timestamp: now(),
206
+ deviceId: typeof input.DeviceId === 'string' ? input.DeviceId : undefined,
207
+ op: 'sync',
208
+ payload,
209
+ meta: {}
210
+ };
211
+ }
212
+ if (input?.name) {
213
+ const event = input;
214
+ return {
215
+ kind: 'event',
216
+ id: typeof input.MessageId === 'string' ? input.MessageId : typeof input.DeviceId === 'string' ? input.DeviceId : `${input.name}:${now()}`,
217
+ timestamp: typeof input.CreateAt === 'number' ? input.CreateAt : now(),
218
+ deviceId: typeof input.DeviceId === 'string' ? input.DeviceId : undefined,
219
+ eventName: input.name,
220
+ event,
221
+ raw: input.value,
222
+ meta: {}
223
+ };
224
+ }
225
+ return null;
226
+ };
227
+ const isCBPEnvelope = (input) => {
228
+ if (!input || typeof input !== 'object') {
229
+ return false;
230
+ }
231
+ const value = input;
232
+ return value.protocol === 'cbp' && value.version === 1 && typeof value.type === 'string' && typeof value.id === 'string';
233
+ };
234
+ const normalizeInboundMessage = (input) => {
235
+ if (!input || typeof input !== 'object') {
236
+ return null;
237
+ }
238
+ if (isCBPEnvelope(input)) {
239
+ return normalizeEnvelopeMessage(input);
240
+ }
241
+ return normalizeLegacyMessage(input);
242
+ };
243
+ const toLegacyActionData = (message) => {
244
+ return {
245
+ action: message.action,
246
+ payload: message.input,
247
+ actionId: message.id,
248
+ DeviceId: message.deviceId
249
+ };
250
+ };
251
+ const toLegacyApiData = (message) => {
252
+ const input = message.input;
253
+ const key = typeof input.key === 'string' ? input.key : '';
254
+ const params = Array.isArray(input.params) ? input.params : [];
255
+ return {
256
+ action: message.api,
257
+ payload: {
258
+ event: input.event,
259
+ key,
260
+ params
261
+ },
262
+ apiId: message.id,
263
+ DeviceId: message.deviceId
264
+ };
265
+ };
266
+ const isNormalizedActionRequest = (message) => {
267
+ return message?.kind === 'action.req';
268
+ };
269
+ const isNormalizedApiRequest = (message) => {
270
+ return message?.kind === 'api.req';
271
+ };
272
+ const getNormalizedDeviceId = (message) => {
273
+ return message.deviceId;
274
+ };
275
+ const getNormalizedEventRouteId = (message) => {
276
+ if (message.kind !== 'event') {
277
+ return undefined;
278
+ }
279
+ return inferEventRouteId(message.event);
280
+ };
281
+ const createActionRequestEnvelope = (data) => {
282
+ return createRequestEnvelope('action.req', String(data.actionId ?? ''), data.DeviceId, {
283
+ action: data.action,
284
+ input: asRecord(data.payload)
285
+ });
286
+ };
287
+ const createApiRequestEnvelope = (data) => {
288
+ return createRequestEnvelope('api.req', String(data.apiId ?? ''), data.DeviceId, {
289
+ api: data.action,
290
+ input: asRecord(data.payload)
291
+ });
292
+ };
293
+ const createActionResponseEnvelope = (data, payload, error) => {
294
+ return createResponseEnvelope('action.res', String(data.actionId ?? ''), data.DeviceId, payload, error);
295
+ };
296
+ const createApiResponseEnvelope = (data, payload, error) => {
297
+ return createResponseEnvelope('api.res', String(data.apiId ?? ''), data.DeviceId, payload, error);
298
+ };
299
+ const createEventEnvelope = (data) => {
300
+ const deviceId = typeof data.DeviceId === 'string' ? data.DeviceId : undefined;
301
+ const eventName = typeof data.name === 'string' ? data.name : '';
302
+ const event = { ...data };
303
+ return {
304
+ protocol: 'cbp',
305
+ version: 1,
306
+ type: 'event',
307
+ id: typeof data.MessageId === 'string'
308
+ ? data.MessageId
309
+ : typeof deviceId === 'string'
310
+ ? `${deviceId}:${now()}`
311
+ : `${eventName}:${now()}`,
312
+ timestamp: typeof data.CreateAt === 'number' ? data.CreateAt : now(),
313
+ source: {
314
+ role: 'platform',
315
+ deviceId
316
+ },
317
+ payload: {
318
+ name: eventName,
319
+ event,
320
+ raw: data.value
321
+ },
322
+ meta: {
323
+ routeId: inferEventRouteId(event)
324
+ }
325
+ };
326
+ };
327
+
328
+ export { createActionRequestEnvelope, createActionResponseEnvelope, createApiRequestEnvelope, createApiResponseEnvelope, createEventEnvelope, getNormalizedDeviceId, getNormalizedEventRouteId, isCBPEnvelope, isNormalizedActionRequest, isNormalizedApiRequest, normalizeInboundMessage, toLegacyActionData, toLegacyApiData };
@@ -4,36 +4,38 @@ import 'fs';
4
4
  import 'path';
5
5
  import 'yaml';
6
6
  import { sanitizeForSerialization, createResult } from '../../core/utils.js';
7
- import { generateUniqueId, deviceId, actionResolves, actionTimeouts, timeoutTime } from './config.js';
7
+ import { generateUniqueId, deviceId, actionRequestResolves, actionRequestTimeouts, timeoutTime } from './config.js';
8
8
  import { getDirectSend } from './transport.js';
9
+ import { createActionRequestEnvelope } from '../normalize.js';
9
10
 
10
- const setupActionResolve = (actionId, resolve) => {
11
- actionResolves.set(actionId, resolve);
11
+ const setupActionResolve = (requestId, resolve) => {
12
+ actionRequestResolves.set(requestId, resolve);
12
13
  const timeout = setTimeout(() => {
13
- if (!actionResolves.has(actionId) || !actionTimeouts.has(actionId)) {
14
+ if (!actionRequestResolves.has(requestId) || !actionRequestTimeouts.has(requestId)) {
14
15
  return;
15
16
  }
16
- actionResolves.delete(actionId);
17
- actionTimeouts.delete(actionId);
17
+ actionRequestResolves.delete(requestId);
18
+ actionRequestTimeouts.delete(requestId);
18
19
  resolve([createResult(ResultCode.Fail, '行为超时', null)]);
19
20
  }, timeoutTime);
20
- actionTimeouts.set(actionId, timeout);
21
+ actionRequestTimeouts.set(requestId, timeout);
21
22
  };
22
23
  const sendAction = (data) => {
23
- const actionId = generateUniqueId();
24
+ const requestId = generateUniqueId();
24
25
  return new Promise(resolve => {
25
- data.actionId = actionId;
26
+ data.actionId = requestId;
26
27
  data.DeviceId = deviceId;
27
- const safeData = sanitizeForSerialization(data);
28
+ const envelope = createActionRequestEnvelope(data);
29
+ const safeData = sanitizeForSerialization(envelope);
28
30
  const directSend = getDirectSend();
29
31
  if (directSend) {
30
32
  directSend(safeData);
31
- setupActionResolve(actionId, resolve);
33
+ setupActionResolve(requestId, resolve);
32
34
  return;
33
35
  }
34
36
  if (process.env.__ALEMON_IPC === '1' && typeof process.send === 'function') {
35
37
  process.send({ type: 'ipc:data', data: safeData });
36
- setupActionResolve(actionId, resolve);
38
+ setupActionResolve(requestId, resolve);
37
39
  return;
38
40
  }
39
41
  if (!global.chatbotClient?.send) {
@@ -41,7 +43,7 @@ const sendAction = (data) => {
41
43
  return;
42
44
  }
43
45
  global.chatbotClient?.send(flattedJSON.stringify(safeData));
44
- setupActionResolve(actionId, resolve);
46
+ setupActionResolve(requestId, resolve);
45
47
  });
46
48
  };
47
49
 
@@ -3,37 +3,39 @@ import 'fs';
3
3
  import 'path';
4
4
  import 'yaml';
5
5
  import { sanitizeForSerialization, createResult } from '../../core/utils.js';
6
- import { generateUniqueId, deviceId, apiResolves, apiTimeouts, timeoutTime } from './config.js';
6
+ import { generateUniqueId, deviceId, apiRequestResolves, apiRequestTimeouts, timeoutTime } from './config.js';
7
7
  import * as flattedJSON from 'flatted';
8
8
  import { getDirectSend } from './transport.js';
9
+ import { createApiRequestEnvelope } from '../normalize.js';
9
10
 
10
- const setupApiResolve = (apiId, resolve) => {
11
- apiResolves.set(apiId, resolve);
11
+ const setupApiResolve = (requestId, resolve) => {
12
+ apiRequestResolves.set(requestId, resolve);
12
13
  const timeout = setTimeout(() => {
13
- if (!apiResolves.has(apiId) || !apiTimeouts.has(apiId)) {
14
+ if (!apiRequestResolves.has(requestId) || !apiRequestTimeouts.has(requestId)) {
14
15
  return;
15
16
  }
16
- apiResolves.delete(apiId);
17
- apiTimeouts.delete(apiId);
17
+ apiRequestResolves.delete(requestId);
18
+ apiRequestTimeouts.delete(requestId);
18
19
  resolve([createResult(ResultCode.Fail, '接口超时', null)]);
19
20
  }, timeoutTime);
20
- apiTimeouts.set(apiId, timeout);
21
+ apiRequestTimeouts.set(requestId, timeout);
21
22
  };
22
23
  const sendAPI = (data) => {
23
- const ApiId = generateUniqueId();
24
+ const requestId = generateUniqueId();
24
25
  return new Promise(resolve => {
25
- data.apiId = ApiId;
26
+ data.apiId = requestId;
26
27
  data.DeviceId = deviceId;
27
- const safeData = sanitizeForSerialization(data);
28
+ const envelope = createApiRequestEnvelope(data);
29
+ const safeData = sanitizeForSerialization(envelope);
28
30
  const directSend = getDirectSend();
29
31
  if (directSend) {
30
32
  directSend(safeData);
31
- setupApiResolve(ApiId, resolve);
33
+ setupApiResolve(requestId, resolve);
32
34
  return;
33
35
  }
34
36
  if (process.env.__ALEMON_IPC === '1' && typeof process.send === 'function') {
35
37
  process.send({ type: 'ipc:data', data: safeData });
36
- setupApiResolve(ApiId, resolve);
38
+ setupApiResolve(requestId, resolve);
37
39
  return;
38
40
  }
39
41
  if (!global.chatbotClient?.send) {
@@ -41,7 +43,7 @@ const sendAPI = (data) => {
41
43
  return;
42
44
  }
43
45
  global.chatbotClient?.send(flattedJSON.stringify(safeData));
44
- setupApiResolve(ApiId, resolve);
46
+ setupApiResolve(requestId, resolve);
45
47
  });
46
48
  };
47
49
 
@@ -12,10 +12,14 @@ export declare const USER_AGENT_HEADER_VALUE_MAP: {
12
12
  };
13
13
  export declare const DEVICE_ID_HEADER = "x-device-id";
14
14
  export declare const FULL_RECEIVE_HEADER = "x-full-receive";
15
- type actionResolvesValue = Result[] | PromiseLike<Result[]>;
16
- type actionResolvesValueFunc = (value: actionResolvesValue) => void;
17
- export declare const actionResolves: Map<string, actionResolvesValueFunc>;
18
- export declare const apiResolves: Map<string, actionResolvesValueFunc>;
15
+ type RequestReplyValue = Result[] | PromiseLike<Result[]>;
16
+ type RequestReplyResolve = (value: RequestReplyValue) => void;
17
+ export declare const actionRequestResolves: Map<string, RequestReplyResolve>;
18
+ export declare const apiRequestResolves: Map<string, RequestReplyResolve>;
19
+ export declare const actionRequestTimeouts: Map<string, NodeJS.Timeout>;
20
+ export declare const apiRequestTimeouts: Map<string, NodeJS.Timeout>;
21
+ export declare const actionResolves: Map<string, RequestReplyResolve>;
22
+ export declare const apiResolves: Map<string, RequestReplyResolve>;
19
23
  export declare const actionTimeouts: Map<string, NodeJS.Timeout>;
20
24
  export declare const apiTimeouts: Map<string, NodeJS.Timeout>;
21
25
  export declare const childrenBind: Map<string, string>;
@@ -12,10 +12,14 @@ const USER_AGENT_HEADER_VALUE_MAP = {
12
12
  };
13
13
  const DEVICE_ID_HEADER = 'x-device-id';
14
14
  const FULL_RECEIVE_HEADER = 'x-full-receive';
15
- const actionResolves = new Map();
16
- const apiResolves = new Map();
17
- const actionTimeouts = new Map();
18
- const apiTimeouts = new Map();
15
+ const actionRequestResolves = new Map();
16
+ const apiRequestResolves = new Map();
17
+ const actionRequestTimeouts = new Map();
18
+ const apiRequestTimeouts = new Map();
19
+ const actionResolves = actionRequestResolves;
20
+ const apiResolves = apiRequestResolves;
21
+ const actionTimeouts = actionRequestTimeouts;
22
+ const apiTimeouts = apiRequestTimeouts;
19
23
  const childrenBind = new Map();
20
24
  const clientBindCount = new Map();
21
25
  const bindChannelToClient = (channelId, clientId) => {
@@ -49,4 +53,4 @@ const timeoutTime = 1000 * 60 * 3;
49
53
  const reconnectInterval = 1000 * 6;
50
54
  const HEARTBEAT_INTERVAL = 1000 * 18;
51
55
 
52
- export { DEVICE_ID_HEADER, FULL_RECEIVE_HEADER, HEARTBEAT_INTERVAL, USER_AGENT_HEADER, USER_AGENT_HEADER_VALUE_MAP, actionResolves, actionTimeouts, apiResolves, apiTimeouts, bindChannelToClient, childrenBind, childrenClient, clientBindCount, deviceId, fullClient, generateUniqueId, platformClient, reconnectInterval, timeoutTime, unbindClient };
56
+ export { DEVICE_ID_HEADER, FULL_RECEIVE_HEADER, HEARTBEAT_INTERVAL, USER_AGENT_HEADER, USER_AGENT_HEADER_VALUE_MAP, actionRequestResolves, actionRequestTimeouts, actionResolves, actionTimeouts, apiRequestResolves, apiRequestTimeouts, apiResolves, apiTimeouts, bindChannelToClient, childrenBind, childrenClient, clientBindCount, deviceId, fullClient, generateUniqueId, platformClient, reconnectInterval, timeoutTime, unbindClient };
@@ -11,7 +11,27 @@ import '../../core/utils.js';
11
11
  import { USER_AGENT_HEADER, USER_AGENT_HEADER_VALUE_MAP, DEVICE_ID_HEADER, FULL_RECEIVE_HEADER, platformClient, childrenClient, fullClient, childrenBind, clientBindCount, unbindClient, bindChannelToClient } from '../processor/config.js';
12
12
  import { createTestOneController } from './testone.js';
13
13
  import { getClientChild } from '../../process/ipc-bridge.js';
14
+ import { normalizeInboundMessage, getNormalizedDeviceId, getNormalizedEventRouteId } from '../normalize.js';
14
15
 
16
+ const routeNormalizedMessage = (message, input) => {
17
+ const normalized = normalizeInboundMessage(input);
18
+ if (!normalized) {
19
+ return { normalized: null, handled: false };
20
+ }
21
+ if (normalized.kind === 'api.res' || normalized.kind === 'action.res') {
22
+ const resolvedDeviceId = getNormalizedDeviceId(normalized);
23
+ if (resolvedDeviceId) {
24
+ routeMessageToDevice(resolvedDeviceId, message);
25
+ }
26
+ return { normalized, handled: true };
27
+ }
28
+ if (normalized.kind === 'event') {
29
+ const routeId = getNormalizedEventRouteId(normalized);
30
+ handleEvent(message, routeId || '');
31
+ return { normalized, handled: true };
32
+ }
33
+ return { normalized, handled: false };
34
+ };
15
35
  const routeMessageToDevice = (DeviceId, message) => {
16
36
  if (childrenClient.has(DeviceId)) {
17
37
  const clientWs = childrenClient.get(DeviceId);
@@ -204,24 +224,13 @@ const setPlatformClient = (originId, ws) => {
204
224
  platformClient.set(originId, ws);
205
225
  ws.on('message', (message) => {
206
226
  try {
207
- const parsedMessage = flattedJSON.parse(message.toString());
227
+ const inbound = flattedJSON.parse(message.toString());
228
+ routeNormalizedMessage(message.toString(), inbound);
208
229
  logger.debug({
209
230
  code: ResultCode.Ok,
210
231
  message: '服务端接收到消息',
211
- data: parsedMessage
232
+ data: inbound
212
233
  });
213
- if (parsedMessage.apiId) {
214
- const DeviceId = parsedMessage.DeviceId;
215
- routeMessageToDevice(DeviceId, message);
216
- }
217
- else if (parsedMessage?.actionId) {
218
- const DeviceId = parsedMessage.DeviceId;
219
- routeMessageToDevice(DeviceId, message);
220
- }
221
- else if (parsedMessage?.name) {
222
- const ID = parsedMessage.ChannelId || parsedMessage.GuildId || parsedMessage.DeviceId;
223
- handleEvent(message, ID);
224
- }
225
234
  }
226
235
  catch (error) {
227
236
  logger.error({
@@ -255,26 +264,15 @@ const setTestOnePlatformClient = (ws) => {
255
264
  const controller = createTestOneController(ws);
256
265
  ws.on('message', (message) => {
257
266
  try {
258
- const parsedMessage = flattedJSON.parse(message.toString());
267
+ const inbound = flattedJSON.parse(message.toString());
268
+ const { handled } = routeNormalizedMessage(message.toString(), inbound);
259
269
  logger.debug({
260
270
  code: ResultCode.Ok,
261
271
  message: '测试端接收到消息',
262
- data: parsedMessage
272
+ data: inbound
263
273
  });
264
- if (parsedMessage.apiId) {
265
- const DeviceId = parsedMessage.DeviceId;
266
- routeMessageToDevice(DeviceId, message);
267
- }
268
- else if (parsedMessage?.actionId) {
269
- const DeviceId = parsedMessage.DeviceId;
270
- routeMessageToDevice(DeviceId, message);
271
- }
272
- else if (parsedMessage?.name) {
273
- const ID = parsedMessage.ChannelId || parsedMessage.GuildId || parsedMessage.DeviceId;
274
- handleEvent(message, ID);
275
- }
276
- else {
277
- controller.onMessage(parsedMessage);
274
+ if (!handled) {
275
+ controller.onMessage(inbound);
278
276
  }
279
277
  }
280
278
  catch (error) {