@@ -346,6 +346,20 @@ export class ChatwootService {
346346
347347 return contact ;
348348 } catch ( error ) {
349+ if (
350+ ( error . status === 422 || error . response ?. status === 422 ) &&
351+ ( error . message ?. includes ( 'taken' ) || error . response ?. data ?. message ?. includes ( 'taken' ) ) &&
352+ jid
353+ ) {
354+ this . logger . warn ( `Contact with identifier ${ jid } already exists, trying to find it...` ) ;
355+ const existingContact = await this . findContactByIdentifier ( instance , jid ) ;
356+ if ( existingContact ) {
357+ const contactId = existingContact . id ;
358+ await this . addLabelToContact ( this . provider . nameInbox , contactId ) ;
359+ return existingContact ;
360+ }
361+ }
362+
349363 this . logger . error ( 'Error creating contact' ) ;
350364 console . log ( error ) ;
351365 return null ;
@@ -415,6 +429,55 @@ export class ChatwootService {
415429 }
416430 }
417431
432+ public async findContactByIdentifier ( instance : InstanceDto , identifier : string ) {
433+ const client = await this . clientCw ( instance ) ;
434+
435+ if ( ! client ) {
436+ this . logger . warn ( 'client not found' ) ;
437+ return null ;
438+ }
439+
440+ // Direct search by query (q) - most common way to search by identifier/email/phone
441+ const contact = ( await ( client as any ) . get ( 'contacts/search' , {
442+ params : {
443+ q : identifier ,
444+ sort : 'name' ,
445+ } ,
446+ } ) ) as any ;
447+
448+ if ( contact && contact . data && contact . data . payload && contact . data . payload . length > 0 ) {
449+ return contact . data . payload [ 0 ] ;
450+ }
451+
452+ // Fallback for older API versions or different response structures
453+ if ( contact && contact . payload && contact . payload . length > 0 ) {
454+ return contact . payload [ 0 ] ;
455+ }
456+
457+ // Try search by attribute
458+ const contactByAttr = ( await ( client as any ) . post ( 'contacts/filter' , {
459+ payload : [
460+ {
461+ attribute_key : 'identifier' ,
462+ filter_operator : 'equal_to' ,
463+ values : [ identifier ] ,
464+ query_operator : null ,
465+ } ,
466+ ] ,
467+ } ) ) as any ;
468+
469+ if ( contactByAttr && contactByAttr . payload && contactByAttr . payload . length > 0 ) {
470+ return contactByAttr . payload [ 0 ] ;
471+ }
472+
473+ // Check inside data property if using axios interceptors wrapper
474+ if ( contactByAttr && contactByAttr . data && contactByAttr . data . payload && contactByAttr . data . payload . length > 0 ) {
475+ return contactByAttr . data . payload [ 0 ] ;
476+ }
477+
478+ return null ;
479+ }
480+
418481 public async findContact ( instance : InstanceDto , phoneNumber : string ) {
419482 const client = await this . clientCw ( instance ) ;
420483
@@ -1574,7 +1637,11 @@ export class ChatwootService {
15741637 this . logger . verbose ( `Update result: ${ result } rows affected` ) ;
15751638
15761639 if ( this . isImportHistoryAvailable ( ) ) {
1577- chatwootImport . updateMessageSourceID ( chatwootMessageIds . messageId , key . id ) ;
1640+ try {
1641+ await chatwootImport . updateMessageSourceID ( chatwootMessageIds . messageId , key . id ) ;
1642+ } catch ( error ) {
1643+ this . logger . error ( `Error updating Chatwoot message source ID: ${ error } ` ) ;
1644+ }
15781645 }
15791646 }
15801647
@@ -2024,7 +2091,7 @@ export class ChatwootService {
20242091 if ( body . key . remoteJid . includes ( '@g.us' ) ) {
20252092 const participantName = body . pushName ;
20262093 const rawPhoneNumber =
2027- body . key . addressingMode === 'lid' && ! body . key . fromMe
2094+ body . key . addressingMode === 'lid' && ! body . key . fromMe && body . key . participantAlt
20282095 ? body . key . participantAlt . split ( '@' ) [ 0 ] . split ( ':' ) [ 0 ]
20292096 : body . key . participant . split ( '@' ) [ 0 ] . split ( ':' ) [ 0 ] ;
20302097 const formattedPhoneNumber = parsePhoneNumberFromString ( `+${ rawPhoneNumber } ` ) . formatInternational ( ) ;
@@ -2206,7 +2273,7 @@ export class ChatwootService {
22062273 if ( body . key . remoteJid . includes ( '@g.us' ) ) {
22072274 const participantName = body . pushName ;
22082275 const rawPhoneNumber =
2209- body . key . addressingMode === 'lid' && ! body . key . fromMe
2276+ body . key . addressingMode === 'lid' && ! body . key . fromMe && body . key . participantAlt
22102277 ? body . key . participantAlt . split ( '@' ) [ 0 ] . split ( ':' ) [ 0 ]
22112278 : body . key . participant . split ( '@' ) [ 0 ] . split ( ':' ) [ 0 ] ;
22122279 const formattedPhoneNumber = parsePhoneNumberFromString ( `+${ rawPhoneNumber } ` ) . formatInternational ( ) ;
@@ -2465,7 +2532,10 @@ export class ChatwootService {
24652532 }
24662533
24672534 public getNumberFromRemoteJid ( remoteJid : string ) {
2468- return remoteJid . replace ( / : \d + / , '' ) . split ( '@' ) [ 0 ] ;
2535+ if ( ! remoteJid ) {
2536+ return '' ;
2537+ }
2538+ return remoteJid . replace ( / : \d + / , '' ) . replace ( '@s.whatsapp.net' , '' ) . replace ( '@g.us' , '' ) . replace ( '@lid' , '' ) ;
24692539 }
24702540
24712541 public startImportHistoryMessages ( instance : InstanceDto ) {
0 commit comments