Skip to content

Commit 10f1be1

Browse files
ClawbornClawbornTakhoffman
authored
fix(feishu): replace console.log with runtime log for typing indicator errors (#18841) thanks @Clawborn
Verified: - pnpm install --frozen-lockfile - pnpm build - pnpm check - pnpm test:macmini Co-authored-by: Clawborn <[email protected]> Co-authored-by: Tak Hoffman <[email protected]>
1 parent a5b1e86 commit 10f1be1

File tree

4 files changed

+44
-19
lines changed

4 files changed

+44
-19
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ Docs: https://docs.openclaw.ai
2424
- Feishu/Group session routing: add configurable group session scopes (`group`, `group_sender`, `group_topic`, `group_topic_sender`) with legacy `topicSessionMode=enabled` compatibility so Feishu group conversations can isolate sessions by sender/topic as configured. (#17798)
2525
- Feishu/Reply-in-thread routing: add `replyInThread` config (`disabled|enabled`) for group replies, propagate `reply_in_thread` across text/card/media/streaming sends, and align topic-scoped session routing so newly created reply threads stay on the same session root. (#27325)
2626
- Feishu/Typing backoff: re-throw Feishu typing add/remove rate-limit and quota errors (`429`, `99991400`, `99991403`) and detect SDK non-throwing backoff responses so the typing keepalive circuit breaker can stop retries instead of looping indefinitely. (#28494)
27+
- Feishu/Zalo runtime logging: replace direct `console.log/error` usage in Feishu typing-indicator paths and Zalo monitor paths with runtime-gated logger calls so verbosity controls are respected while preserving typing backoff behavior. (#18841) Thanks @Clawborn.
2728
- Feishu/Probe status caching: cache successful `probeFeishu()` bot-info results for 10 minutes (bounded cache with per-account keying) to reduce repeated status/onboarding probe API calls, while bypassing cache for failures and exceptions. (#28907) Thanks @Glucksberg.
2829
- Feishu/Opus media send type: send `.opus` attachments with `msg_type: "audio"` (instead of `"media"`) so Feishu voice messages deliver correctly while `.mp4` remains `msg_type: "media"` and documents remain `msg_type: "file"`. (#28269) Thanks @Glucksberg.
2930
- Feishu/Mobile video media type: treat inbound `message_type: "media"` as video-equivalent for media key extraction, placeholder inference, and media download resolution so mobile-app video sends ingest correctly. (#25502) Thanks @4ier.

extensions/feishu/src/reply-dispatcher.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,18 @@ export function createFeishuReplyDispatcher(params: CreateFeishuReplyDispatcherP
5959
if (!replyToMessageId) {
6060
return;
6161
}
62-
typingState = await addTypingIndicator({ cfg, messageId: replyToMessageId, accountId });
62+
typingState = await addTypingIndicator({
63+
cfg,
64+
messageId: replyToMessageId,
65+
accountId,
66+
runtime: params.runtime,
67+
});
6368
},
6469
stop: async () => {
6570
if (!typingState) {
6671
return;
6772
}
68-
await removeTypingIndicator({ cfg, state: typingState, accountId });
73+
await removeTypingIndicator({ cfg, state: typingState, accountId, runtime: params.runtime });
6974
typingState = null;
7075
},
7176
onStartError: (err) =>

extensions/feishu/src/typing.ts

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
import type { ClawdbotConfig } from "openclaw/plugin-sdk";
1+
import type { ClawdbotConfig, RuntimeEnv } from "openclaw/plugin-sdk";
22
import { resolveFeishuAccount } from "./accounts.js";
33
import { createFeishuClient } from "./client.js";
4+
import { getFeishuRuntime } from "./runtime.js";
45

56
// Feishu emoji types for typing indicator
67
// See: https://open.feishu.cn/document/server-docs/im-v1/message-reaction/emojis-introduce
@@ -103,8 +104,9 @@ export async function addTypingIndicator(params: {
103104
cfg: ClawdbotConfig;
104105
messageId: string;
105106
accountId?: string;
107+
runtime?: RuntimeEnv;
106108
}): Promise<TypingIndicatorState> {
107-
const { cfg, messageId, accountId } = params;
109+
const { cfg, messageId, accountId, runtime } = params;
108110
const account = resolveFeishuAccount({ cfg, accountId });
109111
if (!account.configured) {
110112
return { messageId, reactionId: null };
@@ -124,9 +126,11 @@ export async function addTypingIndicator(params: {
124126
// instead of throwing. Detect backoff codes and throw to trip the breaker.
125127
const backoffCode = getBackoffCodeFromResponse(response);
126128
if (backoffCode !== undefined) {
127-
console.log(
128-
`[feishu] typing indicator response contains backoff code ${backoffCode}, stopping keepalive`,
129-
);
129+
if (getFeishuRuntime().logging.shouldLogVerbose()) {
130+
runtime?.log?.(
131+
`[feishu] typing indicator response contains backoff code ${backoffCode}, stopping keepalive`,
132+
);
133+
}
130134
throw new FeishuBackoffError(backoffCode);
131135
}
132136

@@ -135,11 +139,15 @@ export async function addTypingIndicator(params: {
135139
return { messageId, reactionId };
136140
} catch (err) {
137141
if (isFeishuBackoffError(err)) {
138-
console.log(`[feishu] typing indicator hit rate-limit/quota, stopping keepalive`);
142+
if (getFeishuRuntime().logging.shouldLogVerbose()) {
143+
runtime?.log?.("[feishu] typing indicator hit rate-limit/quota, stopping keepalive");
144+
}
139145
throw err;
140146
}
141147
// Silently fail for other non-critical errors (e.g. message deleted, permission issues)
142-
console.log(`[feishu] failed to add typing indicator: ${err}`);
148+
if (getFeishuRuntime().logging.shouldLogVerbose()) {
149+
runtime?.log?.(`[feishu] failed to add typing indicator: ${String(err)}`);
150+
}
143151
return { messageId, reactionId: null };
144152
}
145153
}
@@ -153,8 +161,9 @@ export async function removeTypingIndicator(params: {
153161
cfg: ClawdbotConfig;
154162
state: TypingIndicatorState;
155163
accountId?: string;
164+
runtime?: RuntimeEnv;
156165
}): Promise<void> {
157-
const { cfg, state, accountId } = params;
166+
const { cfg, state, accountId, runtime } = params;
158167
if (!state.reactionId) {
159168
return;
160169
}
@@ -177,17 +186,25 @@ export async function removeTypingIndicator(params: {
177186
// Check for backoff codes in non-throwing SDK responses
178187
const backoffCode = getBackoffCodeFromResponse(result);
179188
if (backoffCode !== undefined) {
180-
console.log(
181-
`[feishu] typing indicator removal response contains backoff code ${backoffCode}, stopping keepalive`,
182-
);
189+
if (getFeishuRuntime().logging.shouldLogVerbose()) {
190+
runtime?.log?.(
191+
`[feishu] typing indicator removal response contains backoff code ${backoffCode}, stopping keepalive`,
192+
);
193+
}
183194
throw new FeishuBackoffError(backoffCode);
184195
}
185196
} catch (err) {
186197
if (isFeishuBackoffError(err)) {
187-
console.log(`[feishu] typing indicator removal hit rate-limit/quota, stopping keepalive`);
198+
if (getFeishuRuntime().logging.shouldLogVerbose()) {
199+
runtime?.log?.(
200+
"[feishu] typing indicator removal hit rate-limit/quota, stopping keepalive",
201+
);
202+
}
188203
throw err;
189204
}
190205
// Silently fail for other non-critical errors
191-
console.log(`[feishu] failed to remove typing indicator: ${err}`);
206+
if (getFeishuRuntime().logging.shouldLogVerbose()) {
207+
runtime?.log?.(`[feishu] failed to remove typing indicator: ${String(err)}`);
208+
}
192209
}
193210
}

extensions/zalo/src/monitor.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ function startPollingLoop(params: {
143143
if (err instanceof ZaloApiError && err.isPollingTimeout) {
144144
// no updates
145145
} else if (!isStopped() && !abortSignal.aborted) {
146-
console.error(`[${account.accountId}] Zalo polling error:`, err);
146+
runtime.error?.(`[${account.accountId}] Zalo polling error: ${String(err)}`);
147147
await new Promise((resolve) => setTimeout(resolve, 5000));
148148
}
149149
}
@@ -190,10 +190,12 @@ async function processUpdate(
190190
);
191191
break;
192192
case "message.sticker.received":
193-
console.log(`[${account.accountId}] Received sticker from ${message.from.id}`);
193+
logVerbose(core, runtime, `[${account.accountId}] Received sticker from ${message.from.id}`);
194194
break;
195195
case "message.unsupported.received":
196-
console.log(
196+
logVerbose(
197+
core,
198+
runtime,
197199
`[${account.accountId}] Received unsupported message type from ${message.from.id}`,
198200
);
199201
break;
@@ -259,7 +261,7 @@ async function handleImageMessage(
259261
mediaPath = saved.path;
260262
mediaType = saved.contentType;
261263
} catch (err) {
262-
console.error(`[${account.accountId}] Failed to download Zalo image:`, err);
264+
runtime.error?.(`[${account.accountId}] Failed to download Zalo image: ${String(err)}`);
263265
}
264266
}
265267

0 commit comments

Comments
 (0)