diff --git a/src/channels/feishu.ts b/src/channels/feishu.ts index 11f9ea6..de517b7 100644 --- a/src/channels/feishu.ts +++ b/src/channels/feishu.ts @@ -377,6 +377,11 @@ export class FeishuAdapter implements ChannelAdapter { this.wsClient = new lark.WSClient({ ...baseConfig, loggerLevel: lark.LoggerLevel.info, + pingTimeout: this.config.pingTimeout ?? 30, + onReady: () => console.log('[feishu] WS ready'), + onReconnecting: () => console.log('[feishu] WS reconnecting...'), + onReconnected: () => console.log('[feishu] WS reconnected'), + onError: (err: unknown) => console.error('[feishu] WS error:', (err as Error)?.message), }); await this.wsClient.start({ eventDispatcher }); @@ -635,8 +640,11 @@ export class FeishuAdapter implements ChannelAdapter { } async stop(): Promise { - // WSClient doesn't expose a clean close method in current SDK version; - // setting to null allows GC to collect. + if (this.wsClient) { + try { + this.wsClient.close(); + } catch {} + } this.wsClient = null; this.client = null; } diff --git a/src/workspace.ts b/src/workspace.ts index ee96b1e..94c9d99 100644 --- a/src/workspace.ts +++ b/src/workspace.ts @@ -14,6 +14,8 @@ export interface FeishuChannelConfig { appSecret: string; /** Open platform domain. Use `lark` for Lark global tenants. Default: `feishu`. */ domain?: string; + /** WebSocket pong timeout in seconds. If no pong received within this time, the connection is considered dead and reconnect is triggered. Default: 30. */ + pingTimeout?: number; } export interface DingtalkChannelConfig {