@@ -42,8 +42,10 @@ import {
4242 decodeSticker ,
4343 decodeText ,
4444 decodeVideo ,
45+ rawMentionsOf ,
4546 type DecodeContext ,
4647} from './decoders/messages.js'
48+ import { isLidJid } from './decoders/_shared.js'
4749import {
4850 decodeDelete ,
4951 decodeEdit ,
@@ -70,6 +72,7 @@ export interface InboundPipelineContext {
7072 groupMetadata ?: ( groupId : string ) => Promise < { subject ?: string } | null >
7173 receiverName ?: ( ) => Promise < string | null >
7274 resolveQuoted ?: ( id : string , remoteJid : string ) => Promise < WAMessage | null >
75+ resolveLidToPn ?: ( lid : string ) => Promise < string | null >
7376 sendReply ?: ( target : string , content : string , opts : TextOptions | undefined , quoted : WAMessage ) => Promise < WAMessageKey >
7477 react ?: ( key : WAMessageKey , emoji : string ) => Promise < WAMessageKey >
7578 ignoreMe ?: boolean
@@ -145,20 +148,39 @@ export function attachInboundPipeline(
145148 cleanups . push ( ( ) => socket . ev . off ( event , wrapped ) )
146149 }
147150
148- const runMessage = ( msg : WAMessage ) : void => {
149- tryEmit ( ( ) => decodeMessage ( msg , decodeCtx ) , ( p ) => client . emit ( 'message' , p ) )
150- tryEmit ( ( ) => decodeText ( msg , decodeCtx ) , ( p ) => client . emit ( 'text' , p ) )
151- tryEmit ( ( ) => decodeImage ( msg , decodeCtx ) , ( p ) => client . emit ( 'image' , p ) )
152- tryEmit ( ( ) => decodeVideo ( msg , decodeCtx ) , ( p ) => client . emit ( 'video' , p ) )
153- tryEmit ( ( ) => decodeAudio ( msg , decodeCtx ) , ( p ) => client . emit ( 'audio' , p ) )
154- tryEmit ( ( ) => decodeDocument ( msg , decodeCtx ) , ( p ) => client . emit ( 'document' , p ) )
155- tryEmit ( ( ) => decodeSticker ( msg , decodeCtx ) , ( p ) => client . emit ( 'sticker' , p ) )
156- tryEmit ( ( ) => decodeMention ( msg , decodeCtx ) , ( p ) => client . emit ( 'mention' , p ) )
157- tryEmit ( ( ) => decodeMentionAll ( msg , decodeCtx ) , ( p ) => client . emit ( 'mention-all' , p ) )
151+ const runMessage = ( msg : WAMessage , msgCtx : DecodeContext ) : void => {
152+ tryEmit ( ( ) => decodeMessage ( msg , msgCtx ) , ( p ) => client . emit ( 'message' , p ) )
153+ tryEmit ( ( ) => decodeText ( msg , msgCtx ) , ( p ) => client . emit ( 'text' , p ) )
154+ tryEmit ( ( ) => decodeImage ( msg , msgCtx ) , ( p ) => client . emit ( 'image' , p ) )
155+ tryEmit ( ( ) => decodeVideo ( msg , msgCtx ) , ( p ) => client . emit ( 'video' , p ) )
156+ tryEmit ( ( ) => decodeAudio ( msg , msgCtx ) , ( p ) => client . emit ( 'audio' , p ) )
157+ tryEmit ( ( ) => decodeDocument ( msg , msgCtx ) , ( p ) => client . emit ( 'document' , p ) )
158+ tryEmit ( ( ) => decodeSticker ( msg , msgCtx ) , ( p ) => client . emit ( 'sticker' , p ) )
159+ tryEmit ( ( ) => decodeMention ( msg , msgCtx ) , ( p ) => client . emit ( 'mention' , p ) )
160+ tryEmit ( ( ) => decodeMentionAll ( msg , msgCtx ) , ( p ) => client . emit ( 'mention-all' , p ) )
158161 tryEmit ( ( ) => decodeButtonClick ( msg , interactiveCtx ) , ( p ) => client . emit ( 'button-click' , p ) )
159162 tryEmit ( ( ) => decodeListSelect ( msg , interactiveCtx ) , ( p ) => client . emit ( 'list-select' , p ) )
160163 }
161164
165+ const buildMentionMap = async ( msg : WAMessage ) : Promise < Map < string , string > | undefined > => {
166+ const resolve = ctx . resolveLidToPn
167+ if ( resolve == null ) return undefined
168+ const lids = [ ...new Set ( rawMentionsOf ( msg ) . filter ( isLidJid ) ) ]
169+ if ( lids . length === 0 ) return undefined
170+ const map = new Map < string , string > ( )
171+ await Promise . all (
172+ lids . map ( async ( lid ) => {
173+ try {
174+ const pn = await resolve ( lid )
175+ if ( pn != null && pn . length > 0 ) map . set ( lid , pn )
176+ } catch ( err ) {
177+ ctx . logger ?. warn ( err , 'inbound pipeline: lid->pn resolve threw' )
178+ }
179+ } ) ,
180+ )
181+ return map . size > 0 ? map : undefined
182+ }
183+
162184 const tryEmit = < T > ( decode : ( ) => T | null , emit : ( payload : T ) => void ) : void => {
163185 let payload : T | null
164186 try {
@@ -175,7 +197,15 @@ export function attachInboundPipeline(
175197 const upsert = dropSpoofedSelfOnly ( raw as UpsertPayload )
176198 for ( const msg of upsert . messages ) {
177199 if ( ctx . ignoreMe === true && msg . key ?. fromMe === true ) continue
178- runMessage ( msg )
200+ const needsResolve =
201+ ctx . resolveLidToPn != null && rawMentionsOf ( msg ) . some ( isLidJid )
202+ if ( ! needsResolve ) {
203+ runMessage ( msg , decodeCtx )
204+ continue
205+ }
206+ void buildMentionMap ( msg ) . then ( ( mentionMap ) =>
207+ runMessage ( msg , mentionMap != null ? { ...decodeCtx , mentionMap } : decodeCtx ) ,
208+ )
179209 }
180210 } )
181211
0 commit comments