@@ -7,8 +7,7 @@ const logger = createLogger('MicrosoftTeamsUtils')
77interface  ParsedMention  { 
88  name : string 
99  fullTag : string 
10-   startIndex : number 
11-   endIndex : number 
10+   mentionId : number 
1211} 
1312
1413interface  TeamMember  { 
@@ -17,13 +16,22 @@ interface TeamMember {
1716  userIdentityType ?: string 
1817} 
1918
20- export  interface  MentionEntity  { 
21-   type : 'mention' 
22-   mentioned : { 
23-     id : string 
24-     name : string 
25-   } 
26-   text : string 
19+ export  interface  TeamsMention  { 
20+   id : number 
21+   mentionText : string 
22+   mentioned :
23+     |  { 
24+         id : string 
25+         name : string 
26+         userIdentityType ?: string 
27+       } 
28+     |  { 
29+         application : { 
30+           displayName : string 
31+           id : string 
32+           applicationIdentityType : 'bot' 
33+         } 
34+       } 
2735} 
2836
2937/** 
@@ -126,15 +134,15 @@ function parseMentions(content: string): ParsedMention[] {
126134  const  mentions : ParsedMention [ ]  =  [ ] 
127135  const  mentionRegex  =  / < a t > ( [ ^ < ] + ) < \/ a t > / gi
128136  let  match : RegExpExecArray  |  null 
137+   let  mentionId  =  0 
129138
130139  while  ( ( match  =  mentionRegex . exec ( content ) )  !==  null )  { 
131140    const  name  =  match [ 1 ] . trim ( ) 
132141    if  ( name )  { 
133142      mentions . push ( { 
134143        name, 
135144        fullTag : match [ 0 ] , 
136-         startIndex : match . index , 
137-         endIndex : match . index  +  match [ 0 ] . length , 
145+         mentionId : mentionId ++ , 
138146      } ) 
139147    } 
140148  } 
@@ -201,40 +209,63 @@ export async function resolveMentionsForChat(
201209  content : string , 
202210  chatId : string , 
203211  accessToken : string 
204- ) : Promise < {  entities :  MentionEntity [ ] ;  hasMentions : boolean  } >  { 
212+ ) : Promise < {  mentions :  TeamsMention [ ] ;  hasMentions : boolean ;   updatedContent :  string  } >  { 
205213  const  parsedMentions  =  parseMentions ( content ) 
206214
207215  if  ( parsedMentions . length  ===  0 )  { 
208-     return  {  entities : [ ] ,  hasMentions : false  } 
216+     return  {  mentions : [ ] ,  hasMentions : false ,   updatedContent :  content  } 
209217  } 
210218
211219  const  members  =  await  fetchChatMembers ( chatId ,  accessToken ) 
212-   const  entities : MentionEntity [ ]  =  [ ] 
213-   const  resolvedNames  =  new  Set < string > ( ) 
220+   const  mentions : TeamsMention [ ]  =  [ ] 
221+   const  resolvedTags  =  new  Set < string > ( ) 
222+   let  updatedContent  =  content 
214223
215224  for  ( const  mention  of  parsedMentions )  { 
216-     if  ( resolvedNames . has ( mention . fullTag ) )  { 
225+     if  ( resolvedTags . has ( mention . fullTag ) )  { 
217226      continue 
218227    } 
219228
220229    const  member  =  findMemberByName ( members ,  mention . name ) 
221230
222231    if  ( member )  { 
223-       entities . push ( { 
224-         type : 'mention' , 
225-         mentioned : { 
226-           id : member . id , 
227-           name : member . displayName , 
228-         } , 
229-         text : mention . fullTag , 
230-       } ) 
231-       resolvedNames . add ( mention . fullTag ) 
232+       const  isBot  =  member . userIdentityType  ===  'bot' 
233+ 
234+       if  ( isBot )  { 
235+         mentions . push ( { 
236+           id : mention . mentionId , 
237+           mentionText : mention . name , 
238+           mentioned : { 
239+             application : { 
240+               displayName : member . displayName , 
241+               id : member . id , 
242+               applicationIdentityType : 'bot' , 
243+             } , 
244+           } , 
245+         } ) 
246+       }  else  { 
247+         mentions . push ( { 
248+           id : mention . mentionId , 
249+           mentionText : mention . name , 
250+           mentioned : { 
251+             id : member . id , 
252+             name : member . displayName , 
253+             userIdentityType : member . userIdentityType , 
254+           } , 
255+         } ) 
256+       } 
257+       resolvedTags . add ( mention . fullTag ) 
258+       updatedContent  =  updatedContent . replace ( 
259+         mention . fullTag , 
260+         `<at id="${ mention . mentionId } ${ mention . name }  
261+       ) 
232262    } 
233263  } 
234264
235265  return  { 
236-     entities, 
237-     hasMentions : entities . length  >  0 , 
266+     mentions, 
267+     hasMentions : mentions . length  >  0 , 
268+     updatedContent, 
238269  } 
239270} 
240271
@@ -243,39 +274,62 @@ export async function resolveMentionsForChannel(
243274  teamId : string , 
244275  channelId : string , 
245276  accessToken : string 
246- ) : Promise < {  entities :  MentionEntity [ ] ;  hasMentions : boolean  } >  { 
277+ ) : Promise < {  mentions :  TeamsMention [ ] ;  hasMentions : boolean ;   updatedContent :  string  } >  { 
247278  const  parsedMentions  =  parseMentions ( content ) 
248279
249280  if  ( parsedMentions . length  ===  0 )  { 
250-     return  {  entities : [ ] ,  hasMentions : false  } 
281+     return  {  mentions : [ ] ,  hasMentions : false ,   updatedContent :  content  } 
251282  } 
252283
253284  const  members  =  await  fetchChannelMembers ( teamId ,  channelId ,  accessToken ) 
254-   const  entities : MentionEntity [ ]  =  [ ] 
255-   const  resolvedNames  =  new  Set < string > ( ) 
285+   const  mentions : TeamsMention [ ]  =  [ ] 
286+   const  resolvedTags  =  new  Set < string > ( ) 
287+   let  updatedContent  =  content 
256288
257289  for  ( const  mention  of  parsedMentions )  { 
258-     if  ( resolvedNames . has ( mention . fullTag ) )  { 
290+     if  ( resolvedTags . has ( mention . fullTag ) )  { 
259291      continue 
260292    } 
261293
262294    const  member  =  findMemberByName ( members ,  mention . name ) 
263295
264296    if  ( member )  { 
265-       entities . push ( { 
266-         type : 'mention' , 
267-         mentioned : { 
268-           id : member . id , 
269-           name : member . displayName , 
270-         } , 
271-         text : mention . fullTag , 
272-       } ) 
273-       resolvedNames . add ( mention . fullTag ) 
297+       const  isBot  =  member . userIdentityType  ===  'bot' 
298+ 
299+       if  ( isBot )  { 
300+         mentions . push ( { 
301+           id : mention . mentionId , 
302+           mentionText : mention . name , 
303+           mentioned : { 
304+             application : { 
305+               displayName : member . displayName , 
306+               id : member . id , 
307+               applicationIdentityType : 'bot' , 
308+             } , 
309+           } , 
310+         } ) 
311+       }  else  { 
312+         mentions . push ( { 
313+           id : mention . mentionId , 
314+           mentionText : mention . name , 
315+           mentioned : { 
316+             id : member . id , 
317+             name : member . displayName , 
318+             userIdentityType : member . userIdentityType , 
319+           } , 
320+         } ) 
321+       } 
322+       resolvedTags . add ( mention . fullTag ) 
323+       updatedContent  =  updatedContent . replace ( 
324+         mention . fullTag , 
325+         `<at id="${ mention . mentionId } ${ mention . name }  
326+       ) 
274327    } 
275328  } 
276329
277330  return  { 
278-     entities, 
279-     hasMentions : entities . length  >  0 , 
331+     mentions, 
332+     hasMentions : mentions . length  >  0 , 
333+     updatedContent, 
280334  } 
281335} 
0 commit comments