@workclaw/openclaw-workchat 1.0.0 → 1.0.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/src/api/api.ts CHANGED
@@ -1,260 +1,260 @@
1
- import { Agent, fetch as undiciFetch } from "undici";
2
-
3
- import { DEFAULT_BASE_URL, DEFAULT_WS_URL, RequestDefaults } from "./types.js";
4
- import { logger } from "../util/logger.js";
5
- import { redactBody, redactUrl } from "../util/redact.js";
6
-
7
- export type WorkChatApiOptions = {
8
- baseUrl: string;
9
- appKey?: string;
10
- appSecret?: string;
11
- timeoutMs?: number;
12
- allowInsecureTls?: boolean;
13
- };
14
-
15
- // ---------------------------------------------------------------------------
16
- // Transport
17
- // ---------------------------------------------------------------------------
18
-
19
- async function fetchJson<T>(params: {
20
- url: string;
21
- init: RequestInit;
22
- timeoutMs: number;
23
- allowInsecureTls?: boolean;
24
- }): Promise<T> {
25
- const { url, init, timeoutMs, allowInsecureTls } = params;
26
- const dispatcher = allowInsecureTls
27
- ? new Agent({ connect: { rejectUnauthorized: false } })
28
- : undefined;
29
- const fetcher = allowInsecureTls ? undiciFetch : globalThis.fetch;
30
- const controller = new AbortController();
31
- const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
32
-
33
- let response: any;
34
- let text = "";
35
- try {
36
- response = await fetcher(url, {
37
- ...init,
38
- signal: controller.signal,
39
- ...(dispatcher ? { dispatcher } : {}),
40
- } as any);
41
- text = await response.text().catch(() => "");
42
- } finally {
43
- clearTimeout(timeoutId);
44
- }
45
-
46
- let data: any = {};
47
- if (text) {
48
- try {
49
- data = JSON.parse(text);
50
- } catch {
51
- data = {};
52
- }
53
- }
54
-
55
- if (!response.ok) {
56
- const message = data?.message || text || `HTTP ${response.status}`;
57
- logger.error(`api: ${redactUrl(url)} HTTP ${response.status} ${redactBody(message)}`);
58
- throw new Error(message);
59
- }
60
- return data as T;
61
- }
62
-
63
- /** POST JSON with Bearer auth. */
64
- export async function apiPost<T = unknown>(params: {
65
- url: string;
66
- token?: string;
67
- body?: unknown;
68
- opts: WorkChatApiOptions;
69
- }): Promise<T> {
70
- return fetchJson<T>({
71
- url: params.url,
72
- timeoutMs: params.opts.timeoutMs ?? RequestDefaults.TimeoutMs,
73
- allowInsecureTls: params.opts.allowInsecureTls,
74
- init: {
75
- method: "POST",
76
- headers: {
77
- "Content-Type": "application/json",
78
- ...(params.token ? { Authorization: `Bearer ${params.token}` } : {}),
79
- },
80
- body: params.body === undefined ? undefined : JSON.stringify(params.body),
81
- },
82
- });
83
- }
84
-
85
- /** Envelope helper: unwrap { code, data } or throw with message. */
86
- export function unwrapEnvelope<T>(resp: { code?: number; message?: string; errMsg?: string; data?: T }): T {
87
- if (resp.code !== 200) {
88
- throw new Error(String(resp.message || resp.errMsg || `WorkChat API code=${resp.code}`));
89
- }
90
- return resp.data as T;
91
- }
92
-
93
- export function normalizeBaseUrl(baseUrl: string | undefined): string {
94
- const raw = (baseUrl || DEFAULT_BASE_URL).trim();
95
- return raw.endsWith("/") ? raw.slice(0, -1) : raw;
96
- }
97
-
98
- // ---------------------------------------------------------------------------
99
- // Access token (with cache)
100
- // ---------------------------------------------------------------------------
101
-
102
- interface TokenCacheEntry {
103
- token: string;
104
- expiresAt: number;
105
- pending?: Promise<string>;
106
- }
107
-
108
- const tokenCache = new Map<string, TokenCacheEntry>();
109
-
110
- export function clearWorkChatTokenCache(cacheKey: string): void {
111
- tokenCache.delete(cacheKey);
112
- }
113
-
114
- /**
115
- * POST {base}/authen/v1/access_token/internal with app_key/app_secret.
116
- * Cached per appKey with a 5-minute pre-expiry refresh and single-flight.
117
- */
118
- export async function getAccessToken(opts: WorkChatApiOptions): Promise<string> {
119
- const cacheKey = opts.appKey || "default";
120
- const cached = tokenCache.get(cacheKey);
121
-
122
- if (cached?.token) {
123
- const refreshAt = cached.expiresAt - 5 * 60_000;
124
- if (Date.now() < refreshAt) return cached.token;
125
- }
126
- if (cached?.pending) return cached.pending;
127
-
128
- if (!opts.appKey || !opts.appSecret) {
129
- throw new Error(
130
- "workchat: missing appKey/appSecret (check WORKCHAT_API_KEY / WORKCHAT_APP_SECRET injection)",
131
- );
132
- }
133
-
134
- const pending = (async (): Promise<string> => {
135
- const resp = await apiPost<{ code?: number; message?: string; data?: { accessToken?: string; expiresIn?: number } }>({
136
- url: `${normalizeBaseUrl(opts.baseUrl)}/authen/v1/access_token/internal`,
137
- body: { app_key: opts.appKey, app_secret: opts.appSecret },
138
- opts,
139
- });
140
- const data = unwrapEnvelope(resp);
141
- if (!data?.accessToken) throw new Error("workchat: accessToken missing in response");
142
- const token = String(data.accessToken);
143
- const expiresIn = Number(data.expiresIn || 0);
144
- tokenCache.set(cacheKey, {
145
- token,
146
- expiresAt: Date.now() + (expiresIn > 0 ? expiresIn * 1000 : 0),
147
- });
148
- logger.info(`access token acquired tokenLen=${token.length} expiresInSec=${expiresIn}`);
149
- return token;
150
- })();
151
-
152
- tokenCache.set(cacheKey, {
153
- token: cached?.token || "",
154
- expiresAt: cached?.expiresAt || 0,
155
- pending,
156
- });
157
-
158
- try {
159
- return await pending;
160
- } catch (err) {
161
- logger.error(`getAccessToken failed: ${String(err)}`);
162
- tokenCache.delete(cacheKey);
163
- throw err;
164
- }
165
- }
166
-
167
- // ---------------------------------------------------------------------------
168
- // Connection open (WebSocket ticket)
169
- // ---------------------------------------------------------------------------
170
-
171
- /** POST {base}/open-apis/v1/connections/open — returns endpoint + ticket. */
172
- export async function openConnection(opts: WorkChatApiOptions & {
173
- websocketUrl?: string;
174
- localIp?: string;
175
- }): Promise<{ endpoint: string; ticket: string }> {
176
- const token = await getAccessToken(opts);
177
- const resp = await apiPost<{ code?: number; message?: string; data?: { endpoint?: string; ticket?: string } }>({
178
- url: `${normalizeBaseUrl(opts.baseUrl)}/open-apis/v1/connections/open`,
179
- token,
180
- body: {
181
- appKey: opts.appKey,
182
- appSecret: opts.appSecret,
183
- subscriptions: [
184
- { type: "CALLBACK", topic: "AGENT_MESSAGE" },
185
- { type: "EVENT", topic: "*" },
186
- { type: "SYSTEM", topic: "*" },
187
- ],
188
- ...(opts.localIp ? { localIp: opts.localIp } : {}),
189
- },
190
- opts,
191
- });
192
- const data = unwrapEnvelope(resp);
193
- const ticket = data?.ticket ? String(data.ticket) : "";
194
- if (!ticket) throw new Error("workchat: ticket missing in connections/open response");
195
-
196
- const endpoint = opts.websocketUrl || data.endpoint || DEFAULT_WS_URL;
197
- logger.info(
198
- `connection opened endpointSource=${opts.websocketUrl ? "config" : data.endpoint ? "api" : "default"} ticketLen=${ticket.length}`,
199
- );
200
- return { endpoint, ticket };
201
- }
202
-
203
- // ---------------------------------------------------------------------------
204
- // Messaging
205
- // ---------------------------------------------------------------------------
206
-
207
- /** POST {base}/open-apis/im/v1/messages — proactive push. */
208
- export async function sendWorkChatMessage(params: {
209
- opts: WorkChatApiOptions;
210
- body: import("./types.js").SendMessageReq;
211
- }): Promise<{ msgId: string }> {
212
- const token = await getAccessToken(params.opts);
213
- const resp = await apiPost<{ code?: number; message?: string; data?: { msgId?: string } }>({
214
- url: `${normalizeBaseUrl(params.opts.baseUrl)}/open-apis/im/v1/messages`,
215
- token,
216
- body: params.body,
217
- opts: params.opts,
218
- });
219
- const data = unwrapEnvelope(resp);
220
- if (!data?.msgId) throw new Error("workchat: msgId missing in send response");
221
- return { msgId: String(data.msgId) };
222
- }
223
-
224
- /** POST {base}/open-apis/im/v1/messages/{messageId}/reply — user-triggered reply. */
225
- export async function sendWorkChatReplyMessage(params: {
226
- opts: WorkChatApiOptions;
227
- messageId: string;
228
- body: import("./types.js").SendMessageReq;
229
- }): Promise<{ msgId: string }> {
230
- const token = await getAccessToken(params.opts);
231
- const resp = await apiPost<{ code?: number; message?: string; data?: { msgId?: string } }>({
232
- url: `${normalizeBaseUrl(params.opts.baseUrl)}/open-apis/im/v1/messages/${encodeURIComponent(params.messageId)}/reply`,
233
- token,
234
- body: params.body,
235
- opts: params.opts,
236
- });
237
- const data = unwrapEnvelope(resp);
238
- if (!data?.msgId) throw new Error("workchat: msgId missing in reply response");
239
- return { msgId: String(data.msgId) };
240
- }
241
-
242
- // ---------------------------------------------------------------------------
243
- // Agent lifecycle
244
- // ---------------------------------------------------------------------------
245
-
246
- /** POST {base}/open-apis/instance/agent-created/status — ack local agent creation (best-effort). */
247
- export async function notifyAgentCreatedStatus(opts: WorkChatApiOptions, agentId: string): Promise<void> {
248
- try {
249
- const token = await getAccessToken(opts);
250
- const resp = await apiPost<{ code?: number }>({
251
- url: `${normalizeBaseUrl(opts.baseUrl)}/open-apis/instance/agent-created/status`,
252
- token,
253
- body: { agentId, success: true },
254
- opts,
255
- });
256
- logger.info(`agent-created/status response code=${String(resp?.code ?? "")}`);
257
- } catch (err) {
258
- logger.error(`agent-created/status failed: ${String(err)}`);
259
- }
260
- }
1
+ import { Agent, fetch as undiciFetch } from "undici";
2
+
3
+ import { DEFAULT_BASE_URL, DEFAULT_WS_URL, RequestDefaults } from "./types.js";
4
+ import { logger } from "../util/logger.js";
5
+ import { redactBody, redactUrl } from "../util/redact.js";
6
+
7
+ export type WorkChatApiOptions = {
8
+ baseUrl: string;
9
+ appKey?: string;
10
+ appSecret?: string;
11
+ timeoutMs?: number;
12
+ allowInsecureTls?: boolean;
13
+ };
14
+
15
+ // ---------------------------------------------------------------------------
16
+ // Transport
17
+ // ---------------------------------------------------------------------------
18
+
19
+ async function fetchJson<T>(params: {
20
+ url: string;
21
+ init: RequestInit;
22
+ timeoutMs: number;
23
+ allowInsecureTls?: boolean;
24
+ }): Promise<T> {
25
+ const { url, init, timeoutMs, allowInsecureTls } = params;
26
+ const dispatcher = allowInsecureTls
27
+ ? new Agent({ connect: { rejectUnauthorized: false } })
28
+ : undefined;
29
+ const fetcher = allowInsecureTls ? undiciFetch : globalThis.fetch;
30
+ const controller = new AbortController();
31
+ const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
32
+
33
+ let response: any;
34
+ let text = "";
35
+ try {
36
+ response = await fetcher(url, {
37
+ ...init,
38
+ signal: controller.signal,
39
+ ...(dispatcher ? { dispatcher } : {}),
40
+ } as any);
41
+ text = await response.text().catch(() => "");
42
+ } finally {
43
+ clearTimeout(timeoutId);
44
+ }
45
+
46
+ let data: any = {};
47
+ if (text) {
48
+ try {
49
+ data = JSON.parse(text);
50
+ } catch {
51
+ data = {};
52
+ }
53
+ }
54
+
55
+ if (!response.ok) {
56
+ const message = data?.message || text || `HTTP ${response.status}`;
57
+ logger.error(`api: ${redactUrl(url)} HTTP ${response.status} ${redactBody(message)}`);
58
+ throw new Error(message);
59
+ }
60
+ return data as T;
61
+ }
62
+
63
+ /** POST JSON with Bearer auth. */
64
+ export async function apiPost<T = unknown>(params: {
65
+ url: string;
66
+ token?: string;
67
+ body?: unknown;
68
+ opts: WorkChatApiOptions;
69
+ }): Promise<T> {
70
+ return fetchJson<T>({
71
+ url: params.url,
72
+ timeoutMs: params.opts.timeoutMs ?? RequestDefaults.TimeoutMs,
73
+ allowInsecureTls: params.opts.allowInsecureTls,
74
+ init: {
75
+ method: "POST",
76
+ headers: {
77
+ "Content-Type": "application/json",
78
+ ...(params.token ? { Authorization: `Bearer ${params.token}` } : {}),
79
+ },
80
+ body: params.body === undefined ? undefined : JSON.stringify(params.body),
81
+ },
82
+ });
83
+ }
84
+
85
+ /** Envelope helper: unwrap { code, data } or throw with message. */
86
+ export function unwrapEnvelope<T>(resp: { code?: number; message?: string; errMsg?: string; data?: T }): T {
87
+ if (resp.code !== 200) {
88
+ throw new Error(String(resp.message || resp.errMsg || `WorkChat API code=${resp.code}`));
89
+ }
90
+ return resp.data as T;
91
+ }
92
+
93
+ export function normalizeBaseUrl(baseUrl: string | undefined): string {
94
+ const raw = (baseUrl || DEFAULT_BASE_URL).trim();
95
+ return raw.endsWith("/") ? raw.slice(0, -1) : raw;
96
+ }
97
+
98
+ // ---------------------------------------------------------------------------
99
+ // Access token (with cache)
100
+ // ---------------------------------------------------------------------------
101
+
102
+ interface TokenCacheEntry {
103
+ token: string;
104
+ expiresAt: number;
105
+ pending?: Promise<string>;
106
+ }
107
+
108
+ const tokenCache = new Map<string, TokenCacheEntry>();
109
+
110
+ export function clearWorkChatTokenCache(cacheKey: string): void {
111
+ tokenCache.delete(cacheKey);
112
+ }
113
+
114
+ /**
115
+ * POST {base}/authen/v1/access_token/internal with app_key/app_secret.
116
+ * Cached per appKey with a 5-minute pre-expiry refresh and single-flight.
117
+ */
118
+ export async function getAccessToken(opts: WorkChatApiOptions): Promise<string> {
119
+ const cacheKey = opts.appKey || "default";
120
+ const cached = tokenCache.get(cacheKey);
121
+
122
+ if (cached?.token) {
123
+ const refreshAt = cached.expiresAt - 5 * 60_000;
124
+ if (Date.now() < refreshAt) return cached.token;
125
+ }
126
+ if (cached?.pending) return cached.pending;
127
+
128
+ if (!opts.appKey || !opts.appSecret) {
129
+ throw new Error(
130
+ "workchat: missing appKey/appSecret (check WORKCHAT_API_KEY / WORKCHAT_APP_SECRET injection)",
131
+ );
132
+ }
133
+
134
+ const pending = (async (): Promise<string> => {
135
+ const resp = await apiPost<{ code?: number; message?: string; data?: { accessToken?: string; expiresIn?: number } }>({
136
+ url: `${normalizeBaseUrl(opts.baseUrl)}/authen/v1/access_token/internal`,
137
+ body: { app_key: opts.appKey, app_secret: opts.appSecret },
138
+ opts,
139
+ });
140
+ const data = unwrapEnvelope(resp);
141
+ if (!data?.accessToken) throw new Error("workchat: accessToken missing in response");
142
+ const token = String(data.accessToken);
143
+ const expiresIn = Number(data.expiresIn || 0);
144
+ tokenCache.set(cacheKey, {
145
+ token,
146
+ expiresAt: Date.now() + (expiresIn > 0 ? expiresIn * 1000 : 0),
147
+ });
148
+ logger.info(`access token acquired tokenLen=${token.length} expiresInSec=${expiresIn}`);
149
+ return token;
150
+ })();
151
+
152
+ tokenCache.set(cacheKey, {
153
+ token: cached?.token || "",
154
+ expiresAt: cached?.expiresAt || 0,
155
+ pending,
156
+ });
157
+
158
+ try {
159
+ return await pending;
160
+ } catch (err) {
161
+ logger.error(`getAccessToken failed: ${String(err)}`);
162
+ tokenCache.delete(cacheKey);
163
+ throw err;
164
+ }
165
+ }
166
+
167
+ // ---------------------------------------------------------------------------
168
+ // Connection open (WebSocket ticket)
169
+ // ---------------------------------------------------------------------------
170
+
171
+ /** POST {base}/open-apis/v1/connections/open — returns endpoint + ticket. */
172
+ export async function openConnection(opts: WorkChatApiOptions & {
173
+ websocketUrl?: string;
174
+ localIp?: string;
175
+ }): Promise<{ endpoint: string; ticket: string }> {
176
+ const token = await getAccessToken(opts);
177
+ const resp = await apiPost<{ code?: number; message?: string; data?: { endpoint?: string; ticket?: string } }>({
178
+ url: `${normalizeBaseUrl(opts.baseUrl)}/open-apis/v1/connections/open`,
179
+ token,
180
+ body: {
181
+ appKey: opts.appKey,
182
+ appSecret: opts.appSecret,
183
+ subscriptions: [
184
+ { type: "CALLBACK", topic: "AGENT_MESSAGE" },
185
+ { type: "EVENT", topic: "*" },
186
+ { type: "SYSTEM", topic: "*" },
187
+ ],
188
+ ...(opts.localIp ? { localIp: opts.localIp } : {}),
189
+ },
190
+ opts,
191
+ });
192
+ const data = unwrapEnvelope(resp);
193
+ const ticket = data?.ticket ? String(data.ticket) : "";
194
+ if (!ticket) throw new Error("workchat: ticket missing in connections/open response");
195
+
196
+ const endpoint = opts.websocketUrl || data.endpoint || DEFAULT_WS_URL;
197
+ logger.info(
198
+ `connection opened endpointSource=${opts.websocketUrl ? "config" : data.endpoint ? "api" : "default"} ticketLen=${ticket.length}`,
199
+ );
200
+ return { endpoint, ticket };
201
+ }
202
+
203
+ // ---------------------------------------------------------------------------
204
+ // Messaging
205
+ // ---------------------------------------------------------------------------
206
+
207
+ /** POST {base}/open-apis/im/v1/messages — proactive push. */
208
+ export async function sendWorkChatMessage(params: {
209
+ opts: WorkChatApiOptions;
210
+ body: import("./types.js").SendMessageReq;
211
+ }): Promise<{ msgId: string }> {
212
+ const token = await getAccessToken(params.opts);
213
+ const resp = await apiPost<{ code?: number; message?: string; data?: { msgId?: string } }>({
214
+ url: `${normalizeBaseUrl(params.opts.baseUrl)}/open-apis/im/v1/messages`,
215
+ token,
216
+ body: params.body,
217
+ opts: params.opts,
218
+ });
219
+ const data = unwrapEnvelope(resp);
220
+ if (!data?.msgId) throw new Error("workchat: msgId missing in send response");
221
+ return { msgId: String(data.msgId) };
222
+ }
223
+
224
+ /** POST {base}/open-apis/im/v1/messages/{messageId}/reply — user-triggered reply. */
225
+ export async function sendWorkChatReplyMessage(params: {
226
+ opts: WorkChatApiOptions;
227
+ messageId: string;
228
+ body: import("./types.js").SendMessageReq;
229
+ }): Promise<{ msgId: string }> {
230
+ const token = await getAccessToken(params.opts);
231
+ const resp = await apiPost<{ code?: number; message?: string; data?: { msgId?: string } }>({
232
+ url: `${normalizeBaseUrl(params.opts.baseUrl)}/open-apis/im/v1/messages/${encodeURIComponent(params.messageId)}/reply`,
233
+ token,
234
+ body: params.body,
235
+ opts: params.opts,
236
+ });
237
+ const data = unwrapEnvelope(resp);
238
+ if (!data?.msgId) throw new Error("workchat: msgId missing in reply response");
239
+ return { msgId: String(data.msgId) };
240
+ }
241
+
242
+ // ---------------------------------------------------------------------------
243
+ // Agent lifecycle
244
+ // ---------------------------------------------------------------------------
245
+
246
+ /** POST {base}/open-apis/instance/agent-created/status — ack local agent creation (best-effort). */
247
+ export async function notifyAgentCreatedStatus(opts: WorkChatApiOptions, agentId: string): Promise<void> {
248
+ try {
249
+ const token = await getAccessToken(opts);
250
+ const resp = await apiPost<{ code?: number }>({
251
+ url: `${normalizeBaseUrl(opts.baseUrl)}/open-apis/instance/agent-created/status`,
252
+ token,
253
+ body: { agentId, success: true },
254
+ opts,
255
+ });
256
+ logger.info(`agent-created/status response code=${String(resp?.code ?? "")}`);
257
+ } catch (err) {
258
+ logger.error(`agent-created/status failed: ${String(err)}`);
259
+ }
260
+ }
package/src/api/types.ts CHANGED
@@ -1,56 +1,56 @@
1
- /**
2
- * WorkChat open-platform protocol types.
3
- *
4
- * Envelope (WebSocket / HTTP responses):
5
- * { code, message, data, errCode?, errMsg? }
6
- * Frames:
7
- * { specVersion, type: CALLBACK|EVENT|SYSTEM, metadata: { topic?, event?, contentType }, data }
8
- */
9
-
10
- /** WorkChat API base URL (prod). */
11
- export const DEFAULT_BASE_URL = "https://workbrain.cn/backend-api";
12
-
13
- /** WebSocket endpoint used when the open-connection API returns none. */
14
- export const DEFAULT_WS_URL = "wss://workbrain.cn/backend-api/open-apis/connect";
15
-
16
- /** msgType codes accepted by /open-apis/im/v1/messages. */
17
- export const WorkChatMsgType = {
18
- Text: "1",
19
- Rich: "26",
20
- } as const;
21
-
22
- export const RequestDefaults = {
23
- TimeoutMs: 30_000,
24
- } as const;
25
-
26
- /** POST /open-apis/im/v1/messages request. */
27
- export interface SendMessageReq {
28
- agentId: string | number;
29
- receiveId: string | number;
30
- msgType: string;
31
- content: string;
32
- conversationId?: string;
33
- is_last?: boolean;
34
- }
35
-
36
- /** CALLBACK/AGENT_MESSAGE payload (data field, JSON-decoded). */
37
- export interface AgentMessagePayload {
38
- userId?: string | number;
39
- agentId?: string | number;
40
- conversationId?: string;
41
- msgId?: string | number;
42
- message?: string | { content?: string };
43
- }
44
-
45
- /** EVENT/AGENT_CREATED|INIT_AGENT payload. */
46
- export interface AgentEventPayload {
47
- id?: string | number;
48
- agentId?: string | number;
49
- futureId?: string | number;
50
- userId?: string | number;
51
- nickName?: string;
52
- name?: string;
53
- phone?: string;
54
- status?: string;
55
- introduction?: string;
56
- }
1
+ /**
2
+ * WorkChat open-platform protocol types.
3
+ *
4
+ * Envelope (WebSocket / HTTP responses):
5
+ * { code, message, data, errCode?, errMsg? }
6
+ * Frames:
7
+ * { specVersion, type: CALLBACK|EVENT|SYSTEM, metadata: { topic?, event?, contentType }, data }
8
+ */
9
+
10
+ /** WorkChat API base URL (prod). */
11
+ export const DEFAULT_BASE_URL = "https://workbrain.cn/backend-api";
12
+
13
+ /** WebSocket endpoint used when the open-connection API returns none. */
14
+ export const DEFAULT_WS_URL = "wss://workbrain.cn/backend-api/open-apis/connect";
15
+
16
+ /** msgType codes accepted by /open-apis/im/v1/messages. */
17
+ export const WorkChatMsgType = {
18
+ Text: "1",
19
+ Rich: "26",
20
+ } as const;
21
+
22
+ export const RequestDefaults = {
23
+ TimeoutMs: 30_000,
24
+ } as const;
25
+
26
+ /** POST /open-apis/im/v1/messages request. */
27
+ export interface SendMessageReq {
28
+ agentId: string | number;
29
+ receiveId: string | number;
30
+ msgType: string;
31
+ content: string;
32
+ conversationId?: string;
33
+ is_last?: boolean;
34
+ }
35
+
36
+ /** CALLBACK/AGENT_MESSAGE payload (data field, JSON-decoded). */
37
+ export interface AgentMessagePayload {
38
+ userId?: string | number;
39
+ agentId?: string | number;
40
+ conversationId?: string;
41
+ msgId?: string | number;
42
+ message?: string | { content?: string };
43
+ }
44
+
45
+ /** EVENT/AGENT_CREATED|INIT_AGENT payload. */
46
+ export interface AgentEventPayload {
47
+ id?: string | number;
48
+ agentId?: string | number;
49
+ futureId?: string | number;
50
+ userId?: string | number;
51
+ nickName?: string;
52
+ name?: string;
53
+ phone?: string;
54
+ status?: string;
55
+ introduction?: string;
56
+ }