@dcrays/dcgchat 0.1.6 → 0.1.8

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/index.ts CHANGED
@@ -2,6 +2,7 @@ import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
2
2
  import { emptyPluginConfigSchema } from "openclaw/plugin-sdk";
3
3
  import { dcgchatPlugin } from "./src/channel.js";
4
4
  import { setDcgchatRuntime } from "./src/runtime.js";
5
+ import { monitoringToolMessage } from "./src/tool.js";
5
6
 
6
7
  const plugin = {
7
8
  id: "dcgchat",
@@ -10,6 +11,7 @@ const plugin = {
10
11
  configSchema: emptyPluginConfigSchema(),
11
12
  register(api: OpenClawPluginApi) {
12
13
  setDcgchatRuntime(api.runtime);
14
+ monitoringToolMessage(api);
13
15
  api.registerChannel({ plugin: dcgchatPlugin });
14
16
  },
15
17
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dcrays/dcgchat",
3
- "version": "0.1.6",
3
+ "version": "0.1.8",
4
4
  "type": "module",
5
5
  "description": "OpenClaw channel plugin for DCG Chat (WebSocket)",
6
6
  "main": "index.ts",
package/src/bot.ts CHANGED
@@ -4,6 +4,7 @@ import { createReplyPrefixContext } from "openclaw/plugin-sdk";
4
4
  import type { InboundMessage, OutboundReply } from "./types.js";
5
5
  import { getDcgchatRuntime } from "./runtime.js";
6
6
  import { resolveAccount } from "./channel.js";
7
+ import { setMsgParams } from "./tool.js";
7
8
 
8
9
  type MediaInfo = {
9
10
  path: string;
@@ -244,6 +245,10 @@ export async function handleDcgchatMessage(params: {
244
245
  state: 'final',
245
246
  },
246
247
  });
248
+ setMsgParams({
249
+ sessionId: '',
250
+ messageId: ''
251
+ });
247
252
  log(`dcgchat[${accountId}]: final state sent`);
248
253
 
249
254
  markDispatchIdle();
package/src/channel.ts CHANGED
@@ -4,6 +4,7 @@ import type { ResolvedDcgchatAccount, DcgchatConfig } from "./types.js";
4
4
  import { logDcgchat } from "./log.js";
5
5
  import { getWsConnection } from "./connection.js";
6
6
  import { ossUpload } from "./oss.js";
7
+ import { getMsgParams } from "./tool.js";
7
8
 
8
9
  export function resolveAccount(cfg: OpenClawConfig, accountId?: string | null): ResolvedDcgchatAccount {
9
10
  const id = accountId ?? DEFAULT_ACCOUNT_ID;
@@ -15,6 +16,8 @@ export function resolveAccount(cfg: OpenClawConfig, accountId?: string | null):
15
16
  wsUrl: raw.wsUrl ?? "",
16
17
  botToken: raw.botToken ?? "",
17
18
  userId: raw.userId ?? "",
19
+ domainId: raw.domainId ?? "",
20
+ appId: raw.appId ?? "",
18
21
  };
19
22
  }
20
23
 
@@ -35,9 +38,10 @@ export const dcgchatPlugin: ChannelPlugin<ResolvedDcgchatAccount> = {
35
38
  threads: true,
36
39
  media: true,
37
40
  nativeCommands: true,
38
- reactions: false,
41
+ reactions: true,
39
42
  edit: false,
40
43
  reply: true,
44
+ effects: true,
41
45
  // blockStreaming: true,
42
46
  },
43
47
  reload: { configPrefixes: ["channels.dcgchat"] },
@@ -50,6 +54,8 @@ export const dcgchatPlugin: ChannelPlugin<ResolvedDcgchatAccount> = {
50
54
  wsUrl: { type: "string" },
51
55
  botToken: { type: "string" },
52
56
  userId: { type: "string" },
57
+ appId: { type: "string" },
58
+ domainId: { type: "string" },
53
59
  capabilities: { type: "array", items: { type: "string" } },
54
60
  },
55
61
  },
@@ -76,6 +82,8 @@ export const dcgchatPlugin: ChannelPlugin<ResolvedDcgchatAccount> = {
76
82
  wsUrl: account.wsUrl,
77
83
  botToken: account.botToken ? "***" : "",
78
84
  userId: account.userId,
85
+ domainId: account.domainId,
86
+ appId: account.appId,
79
87
  }),
80
88
  },
81
89
  messaging: {
@@ -91,8 +99,8 @@ export const dcgchatPlugin: ChannelPlugin<ResolvedDcgchatAccount> = {
91
99
  textChunkLimit: 4000,
92
100
  sendText: async (ctx) => {
93
101
  const target = ctx.to || "(implicit)";
94
- logDcgchat.info(`[dcgchat][${ctx.accountId ?? DEFAULT_ACCOUNT_ID}] outbound -> sendText ${target}: ${ctx.text}`);
95
102
  const ws = getWsConnection()
103
+ const params = getMsgParams();
96
104
  if (ws?.readyState === WebSocket.OPEN) {
97
105
  const {botToken} = resolveAccount(ctx.cfg, ctx.accountId);
98
106
  const content = {
@@ -102,12 +110,14 @@ export const dcgchatPlugin: ChannelPlugin<ResolvedDcgchatAccount> = {
102
110
  content: {
103
111
  bot_token: botToken,
104
112
  response: ctx.text,
105
- session_id:ctx.accountId || Date.now().toString(),
106
- message_id: Date.now().toString(),
113
+ session_id: params.sessionId || Date.now().toString(),
114
+ message_id: params.messageId ||Date.now().toString(),
107
115
  },
108
116
  };
109
117
  ws.send(JSON.stringify(content));
110
118
  logDcgchat.info(`dcgchat[${ctx.accountId}]: sendText to ${target}, ${JSON.stringify(content)}`);
119
+ } else {
120
+ logDcgchat.warn(`[dcgchat][${ctx.accountId ?? DEFAULT_ACCOUNT_ID}] outbound -> ${ws?.readyState}: ${ctx.text}`);
111
121
  }
112
122
  return {
113
123
  channel: "dcgchat",
@@ -117,8 +127,8 @@ export const dcgchatPlugin: ChannelPlugin<ResolvedDcgchatAccount> = {
117
127
  },
118
128
  sendMedia: async (ctx) => {
119
129
  const target = ctx.to || "(implicit)";
120
- logDcgchat.info(`[dcgchat][${ctx.accountId ?? DEFAULT_ACCOUNT_ID}] outbound -> sendMedia ${target}: ${ctx.text + ctx.mediaUrl}`);
121
130
  const ws = getWsConnection()
131
+ const params = getMsgParams();
122
132
  if (ws?.readyState === WebSocket.OPEN) {
123
133
  const {botToken} = resolveAccount(ctx.cfg, ctx.accountId);
124
134
  try {
@@ -131,12 +141,12 @@ export const dcgchatPlugin: ChannelPlugin<ResolvedDcgchatAccount> = {
131
141
  content: {
132
142
  bot_token: botToken,
133
143
  response: ctx.text + '\n' + `[${fileName}](${url})`,
134
- session_id:ctx.accountId || Date.now().toString(),
135
- message_id: Date.now().toString(),
144
+ session_id: params.sessionId || Date.now().toString(),
145
+ message_id: params.messageId ||Date.now().toString(),
136
146
  },
137
147
  };
138
148
  ws.send(JSON.stringify(content));
139
- logDcgchat.info(`dcgchat[${ctx.accountId}]: sendText to ${target}, ${JSON.stringify(content)}`);
149
+ logDcgchat.info(`dcgchat[${ctx.accountId}]: sendMedia to ${target}, ${JSON.stringify(content)}`);
140
150
  } catch (error) {
141
151
  const content = {
142
152
  messageType: "openclaw_bot_chat",
@@ -145,13 +155,15 @@ export const dcgchatPlugin: ChannelPlugin<ResolvedDcgchatAccount> = {
145
155
  content: {
146
156
  bot_token: botToken,
147
157
  response: ctx.text + '\n' + ctx.mediaUrl,
148
- session_id:ctx.accountId || Date.now().toString(),
149
- message_id: Date.now().toString(),
158
+ session_id: params.sessionId || Date.now().toString(),
159
+ message_id: params.messageId ||Date.now().toString(),
150
160
  },
151
161
  };
152
162
  ws.send(JSON.stringify(content));
153
- logDcgchat.info(`dcgchat[${ctx.accountId}]: sendText to ${target}, ${JSON.stringify(content)}`);
163
+ logDcgchat.info(`dcgchat[${ctx.accountId}]: sendMedia to ${target}, ${JSON.stringify(content)}`);
154
164
  }
165
+ } else {
166
+ logDcgchat.warn(`[dcgchat][${ctx.accountId ?? DEFAULT_ACCOUNT_ID}] outbound -> ${ws?.readyState}: ${ctx.text}`);
155
167
  }
156
168
  return {
157
169
  channel: "dcgchat",
package/src/monitor.ts CHANGED
@@ -4,6 +4,7 @@ import { handleDcgchatMessage } from "./bot.js";
4
4
  import { resolveAccount } from "./channel.js";
5
5
  import { setWsConnection } from "./connection.js";
6
6
  import type { InboundMessage, OutboundReply } from "./types.js";
7
+ import { setMsgParams } from "./tool.js";
7
8
 
8
9
  export type MonitorDcgchatOpts = {
9
10
  config?: ClawdbotConfig;
@@ -15,17 +16,19 @@ export type MonitorDcgchatOpts = {
15
16
  const RECONNECT_DELAY_MS = 3000;
16
17
  const HEARTBEAT_INTERVAL_MS = 30_000;
17
18
 
18
- function buildConnectUrl(wsUrl: string, botToken: string, userId: string): string {
19
+ function buildConnectUrl(account: Record<string, string>): string {
20
+ const { wsUrl, botToken, userId, domainId, appId } = account;
19
21
  const url = new URL(wsUrl);
20
22
  if (botToken) url.searchParams.set("bot_token", botToken);
21
23
  if (userId) url.searchParams.set("_userId", userId);
22
- url.searchParams.set("_domainId", "1000");
23
- url.searchParams.set("_appId", "100");
24
+ url.searchParams.set("_domainId", domainId || "1000");
25
+ url.searchParams.set("_appId", appId || "100");
24
26
  return url.toString();
25
27
  }
26
28
 
27
29
  export async function monitorDcgchatProvider(opts: MonitorDcgchatOpts): Promise<void> {
28
30
  const { config, runtime, abortSignal, accountId } = opts;
31
+ // @ts-ignore
29
32
  const cfg = config ?? (runtime?.config?.() as ClawdbotConfig | undefined);
30
33
  if (!cfg) {
31
34
  runtime?.error?.("dcgchat: no config available");
@@ -74,7 +77,7 @@ export async function monitorDcgchatProvider(opts: MonitorDcgchatOpts): Promise<
74
77
  const connect = () => {
75
78
  if (!shouldReconnect) return;
76
79
 
77
- const connectUrl = buildConnectUrl(account.wsUrl, account.botToken, account.userId);
80
+ const connectUrl = buildConnectUrl(account as Record<string, any>);
78
81
  log(`dcgchat[${account.accountId}]: connecting to ${connectUrl}`);
79
82
  ws = new WebSocket(connectUrl);
80
83
 
@@ -107,6 +110,12 @@ export async function monitorDcgchatProvider(opts: MonitorDcgchatOpts): Promise<
107
110
  parsed.content = JSON.parse(parsed.content);
108
111
 
109
112
  const msg = parsed as unknown as InboundMessage;
113
+ setMsgParams({
114
+ userId: msg._userId,
115
+ token: msg.content.bot_token,
116
+ sessionId: msg.content.session_id,
117
+ messageId: msg.content.message_id,
118
+ });
110
119
  await handleDcgchatMessage({
111
120
  cfg,
112
121
  msg,
package/src/tool.ts ADDED
@@ -0,0 +1,65 @@
1
+
2
+ import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
3
+ import { getWsConnection } from "./connection.js";
4
+ import { logDcgchat } from "./log.js";
5
+
6
+ let msgParams = {} as {
7
+ userId: number;
8
+ token: string
9
+ sessionId: string
10
+ messageId: string
11
+ }
12
+
13
+ export function setMsgParams(params: any) {
14
+ msgParams = params;
15
+ }
16
+
17
+ export function getMsgParams() {
18
+ return msgParams;
19
+ }
20
+
21
+ export function monitoringToolMessage(api: OpenClawPluginApi) {
22
+ api.on("after_tool_call", (event, payload) => {
23
+ const ws = getWsConnection()
24
+ const params = getMsgParams();
25
+ if (ws?.readyState === WebSocket.OPEN && params?.sessionId) {
26
+ ws.send(JSON.stringify({
27
+ messageType: "openclaw_bot_chat",
28
+ _userId: params?.userId,
29
+ source: "client",
30
+ content: {
31
+ bot_token: params?.token,
32
+ response: 'all_finished',
33
+ session_id:params?.sessionId,
34
+ message_id: params?.messageId || Date.now().toString()
35
+ },
36
+ }));
37
+ ws.send(JSON.stringify({
38
+ messageType: "openclaw_bot_chat",
39
+ _userId: params?.userId,
40
+ source: "client",
41
+ content: {
42
+ bot_token: params?.token,
43
+ response: JSON.stringify({
44
+ type: 'tool_call',
45
+ ...event
46
+ }),
47
+ session_id:params?.sessionId,
48
+ message_id: params?.messageId || Date.now().toString()
49
+ },
50
+ }));
51
+ ws.send(JSON.stringify({
52
+ messageType: "openclaw_bot_chat",
53
+ _userId: params?.userId,
54
+ source: "client",
55
+ content: {
56
+ bot_token: params?.token,
57
+ response: 'all_finished',
58
+ session_id:params?.sessionId,
59
+ message_id: params?.messageId || Date.now().toString()
60
+ },
61
+ }));
62
+ logDcgchat.info(`dcgchat: tool message to ${params?.sessionId}, ${JSON.stringify(event)}`);
63
+ }
64
+ });
65
+ }
package/src/types.ts CHANGED
@@ -9,6 +9,8 @@ export type DcgchatConfig = {
9
9
  botToken?: string;
10
10
  /** 用户标识 */
11
11
  userId?: string;
12
+ domainId?: string;
13
+ appId?: string;
12
14
  };
13
15
 
14
16
  export type ResolvedDcgchatAccount = {
@@ -18,6 +20,8 @@ export type ResolvedDcgchatAccount = {
18
20
  wsUrl: string;
19
21
  botToken: string;
20
22
  userId: string;
23
+ domainId?: string;
24
+ appId?: string;
21
25
  };
22
26
 
23
27
  /**