66 DEFAULT_GROUP_HISTORY_LIMIT ,
77 type HistoryEntry ,
88} from "openclaw/plugin-sdk" ;
9- import type { FeishuConfig , FeishuMessageContext , FeishuMediaInfo } from "./types.js" ;
9+ import type { FeishuMessageContext , FeishuMediaInfo , ResolvedFeishuAccount } from "./types.js" ;
10+ import { resolveFeishuAccount } from "./accounts.js" ;
1011import { createFeishuClient } from "./client.js" ;
1112import { downloadMessageResourceFeishu } from "./media.js" ;
1213import { extractMentionTargets , extractMessageBody , isMentionForwardRequest } from "./mention.js" ;
@@ -79,12 +80,13 @@ type SenderNameResult = {
7980} ;
8081
8182async function resolveFeishuSenderName ( params : {
82- feishuCfg ?: FeishuConfig ;
83+ account : ResolvedFeishuAccount ;
8384 senderOpenId : string ;
84- log : ( ...args : unknown [ ] ) => void ;
85+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- generic log function
86+ log : ( ...args : any [ ] ) => void ;
8587} ) : Promise < SenderNameResult > {
86- const { feishuCfg , senderOpenId, log } = params ;
87- if ( ! feishuCfg ) {
88+ const { account , senderOpenId, log } = params ;
89+ if ( ! account . configured ) {
8890 return { } ;
8991 }
9092 if ( ! senderOpenId ) {
@@ -98,10 +100,11 @@ async function resolveFeishuSenderName(params: {
98100 }
99101
100102 try {
101- const client = createFeishuClient ( feishuCfg ) ;
103+ const client = createFeishuClient ( account ) ;
102104
103105 // contact/v3/users/:user_id?user_id_type=open_id
104- const res = await client . contact . user . get ( {
106+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- SDK response type
107+ const res : any = await client . contact . user . get ( {
105108 path : { user_id : senderOpenId } ,
106109 params : { user_id_type : "open_id" } ,
107110 } ) ;
@@ -325,8 +328,9 @@ async function resolveFeishuMediaList(params: {
325328 content : string ;
326329 maxBytes : number ;
327330 log ?: ( msg : string ) => void ;
331+ accountId ?: string ;
328332} ) : Promise < FeishuMediaInfo [ ] > {
329- const { cfg, messageId, messageType, content, maxBytes, log } = params ;
333+ const { cfg, messageId, messageType, content, maxBytes, log, accountId } = params ;
330334
331335 // Only process media message types (including post for embedded images)
332336 const mediaTypes = [ "image" , "file" , "audio" , "video" , "sticker" , "post" ] ;
@@ -354,6 +358,7 @@ async function resolveFeishuMediaList(params: {
354358 messageId,
355359 fileKey : imageKey ,
356360 type : "image" ,
361+ accountId,
357362 } ) ;
358363
359364 let contentType = result . contentType ;
@@ -407,6 +412,7 @@ async function resolveFeishuMediaList(params: {
407412 messageId,
408413 fileKey,
409414 type : resourceType ,
415+ accountId,
410416 } ) ;
411417 buffer = result . buffer ;
412418 contentType = result . contentType ;
@@ -506,9 +512,14 @@ export async function handleFeishuMessage(params: {
506512 botOpenId ?: string ;
507513 runtime ?: RuntimeEnv ;
508514 chatHistories ?: Map < string , HistoryEntry [ ] > ;
515+ accountId ?: string ;
509516} ) : Promise < void > {
510- const { cfg, event, botOpenId, runtime, chatHistories } = params ;
511- const feishuCfg = cfg . channels ?. feishu as FeishuConfig | undefined ;
517+ const { cfg, event, botOpenId, runtime, chatHistories, accountId } = params ;
518+
519+ // Resolve account with merged config
520+ const account = resolveFeishuAccount ( { cfg, accountId } ) ;
521+ const feishuCfg = account . config ;
522+
512523 const log = runtime ?. log ?? console . log ;
513524 const error = runtime ?. error ?? console . error ;
514525
@@ -517,7 +528,7 @@ export async function handleFeishuMessage(params: {
517528
518529 // Resolve sender display name (best-effort) so the agent can attribute messages correctly.
519530 const senderResult = await resolveFeishuSenderName ( {
520- feishuCfg ,
531+ account ,
521532 senderOpenId : ctx . senderOpenId ,
522533 log,
523534 } ) ;
@@ -528,7 +539,7 @@ export async function handleFeishuMessage(params: {
528539 // Track permission error to inform agent later (with cooldown to avoid repetition)
529540 let permissionErrorForAgent : PermissionError | undefined ;
530541 if ( senderResult . permissionError ) {
531- const appKey = feishuCfg ? .appId ?? "default" ;
542+ const appKey = account . appId ?? "default" ;
532543 const now = Date . now ( ) ;
533544 const lastNotified = permissionErrorNotifiedAt . get ( appKey ) ?? 0 ;
534545
@@ -538,12 +549,14 @@ export async function handleFeishuMessage(params: {
538549 }
539550 }
540551
541- log ( `feishu: received message from ${ ctx . senderOpenId } in ${ ctx . chatId } (${ ctx . chatType } )` ) ;
552+ log (
553+ `feishu[${ account . accountId } ]: received message from ${ ctx . senderOpenId } in ${ ctx . chatId } (${ ctx . chatType } )` ,
554+ ) ;
542555
543556 // Log mention targets if detected
544557 if ( ctx . mentionTargets && ctx . mentionTargets . length > 0 ) {
545558 const names = ctx . mentionTargets . map ( ( t ) => t . name ) . join ( ", " ) ;
546- log ( `feishu: detected @ forward request, targets: [${ names } ]` ) ;
559+ log ( `feishu[ ${ account . accountId } ] : detected @ forward request, targets: [${ names } ]` ) ;
547560 }
548561
549562 const historyLimit = Math . max (
@@ -554,6 +567,7 @@ export async function handleFeishuMessage(params: {
554567 if ( isGroup ) {
555568 const groupPolicy = feishuCfg ?. groupPolicy ?? "open" ;
556569 const groupAllowFrom = feishuCfg ?. groupAllowFrom ?? [ ] ;
570+ // DEBUG: log(`feishu[${account.accountId}]: groupPolicy=${groupPolicy}`);
557571 const groupConfig = resolveFeishuGroupConfig ( { cfg : feishuCfg , groupId : ctx . chatId } ) ;
558572
559573 // Check if this GROUP is allowed (groupAllowFrom contains group IDs like oc_xxx, not user IDs)
@@ -565,7 +579,7 @@ export async function handleFeishuMessage(params: {
565579 } ) ;
566580
567581 if ( ! groupAllowed ) {
568- log ( `feishu: group ${ ctx . chatId } not in allowlist` ) ;
582+ log ( `feishu[ ${ account . accountId } ]: sender ${ ctx . senderOpenId } not in group allowlist` ) ;
569583 return ;
570584 }
571585
@@ -591,7 +605,9 @@ export async function handleFeishuMessage(params: {
591605 } ) ;
592606
593607 if ( requireMention && ! ctx . mentionedBot ) {
594- log ( `feishu: message in group ${ ctx . chatId } did not mention bot, recording to history` ) ;
608+ log (
609+ `feishu[${ account . accountId } ]: message in group ${ ctx . chatId } did not mention bot, recording to history` ,
610+ ) ;
595611 if ( chatHistories ) {
596612 recordPendingHistoryEntryIfEnabled ( {
597613 historyMap : chatHistories ,
@@ -617,7 +633,7 @@ export async function handleFeishuMessage(params: {
617633 senderId : ctx . senderOpenId ,
618634 } ) ;
619635 if ( ! match . allowed ) {
620- log ( `feishu: sender ${ ctx . senderOpenId } not in DM allowlist` ) ;
636+ log ( `feishu[ ${ account . accountId } ] : sender ${ ctx . senderOpenId } not in DM allowlist` ) ;
621637 return ;
622638 }
623639 }
@@ -634,6 +650,7 @@ export async function handleFeishuMessage(params: {
634650 const route = core . channel . routing . resolveAgentRoute ( {
635651 cfg,
636652 channel : "feishu" ,
653+ accountId : account . accountId ,
637654 peer : {
638655 kind : isGroup ? "group" : "dm" ,
639656 id : isGroup ? ctx . chatId : ctx . senderOpenId ,
@@ -642,8 +659,8 @@ export async function handleFeishuMessage(params: {
642659
643660 const preview = ctx . content . replace ( / \s + / g, " " ) . slice ( 0 , 160 ) ;
644661 const inboundLabel = isGroup
645- ? `Feishu message in group ${ ctx . chatId } `
646- : `Feishu DM from ${ ctx . senderOpenId } ` ;
662+ ? `Feishu[ ${ account . accountId } ] message in group ${ ctx . chatId } `
663+ : `Feishu[ ${ account . accountId } ] DM from ${ ctx . senderOpenId } ` ;
647664
648665 core . system . enqueueSystemEvent ( `${ inboundLabel } : ${ preview } ` , {
649666 sessionKey : route . sessionKey ,
@@ -659,20 +676,27 @@ export async function handleFeishuMessage(params: {
659676 content : event . message . content ,
660677 maxBytes : mediaMaxBytes ,
661678 log,
679+ accountId : account . accountId ,
662680 } ) ;
663681 const mediaPayload = buildFeishuMediaPayload ( mediaList ) ;
664682
665683 // Fetch quoted/replied message content if parentId exists
666684 let quotedContent : string | undefined ;
667685 if ( ctx . parentId ) {
668686 try {
669- const quotedMsg = await getMessageFeishu ( { cfg, messageId : ctx . parentId } ) ;
687+ const quotedMsg = await getMessageFeishu ( {
688+ cfg,
689+ messageId : ctx . parentId ,
690+ accountId : account . accountId ,
691+ } ) ;
670692 if ( quotedMsg ) {
671693 quotedContent = quotedMsg . content ;
672- log ( `feishu: fetched quoted message: ${ quotedContent ?. slice ( 0 , 100 ) } ` ) ;
694+ log (
695+ `feishu[${ account . accountId } ]: fetched quoted message: ${ quotedContent ?. slice ( 0 , 100 ) } ` ,
696+ ) ;
673697 }
674698 } catch ( err ) {
675- log ( `feishu: failed to fetch quoted message: ${ String ( err ) } ` ) ;
699+ log ( `feishu[ ${ account . accountId } ] : failed to fetch quoted message: ${ String ( err ) } ` ) ;
676700 }
677701 }
678702
@@ -742,9 +766,10 @@ export async function handleFeishuMessage(params: {
742766 runtime : runtime as RuntimeEnv ,
743767 chatId : ctx . chatId ,
744768 replyToMessageId : ctx . messageId ,
769+ accountId : account . accountId ,
745770 } ) ;
746771
747- log ( `feishu: dispatching permission error notification to agent` ) ;
772+ log ( `feishu[ ${ account . accountId } ] : dispatching permission error notification to agent` ) ;
748773
749774 await core . channel . reply . dispatchReplyFromConfig ( {
750775 ctx : permissionCtx ,
@@ -815,9 +840,10 @@ export async function handleFeishuMessage(params: {
815840 chatId : ctx . chatId ,
816841 replyToMessageId : ctx . messageId ,
817842 mentionTargets : ctx . mentionTargets ,
843+ accountId : account . accountId ,
818844 } ) ;
819845
820- log ( `feishu: dispatching to agent (session=${ route . sessionKey } )` ) ;
846+ log ( `feishu[ ${ account . accountId } ] : dispatching to agent (session=${ route . sessionKey } )` ) ;
821847
822848 const { queuedFinal, counts } = await core . channel . reply . dispatchReplyFromConfig ( {
823849 ctx : ctxPayload ,
@@ -836,8 +862,10 @@ export async function handleFeishuMessage(params: {
836862 } ) ;
837863 }
838864
839- log ( `feishu: dispatch complete (queuedFinal=${ queuedFinal } , replies=${ counts . final } )` ) ;
865+ log (
866+ `feishu[${ account . accountId } ]: dispatch complete (queuedFinal=${ queuedFinal } , replies=${ counts . final } )` ,
867+ ) ;
840868 } catch ( err ) {
841- error ( `feishu: failed to dispatch message: ${ String ( err ) } ` ) ;
869+ error ( `feishu[ ${ account . accountId } ] : failed to dispatch message: ${ String ( err ) } ` ) ;
842870 }
843871}
0 commit comments