之前有好些看博客的開發者問我有什么較好的方法來解析 at 信息。用戶在channel里發消息給 bot 的時候,通常需要 at bot的名字,當然在消息文字中可能還會 at 其他用戶,比如 bot的名字是 MyBot,那 bot 收到的 Activity 里的 Text 值類似于:
<at>MyBot</at> 請幫我查看一下 <at>Tom</at> 的明天有空時間。
可以看到 Teams 使用了 at tag 來把用戶 at 的信息包含起來。
看到這里,大家可能會想,這個簡單啊,可以分析一下字符串,把 <at> 的內容find到,然后在找到結束的 tag </at> 。但是如果你仔細想想,怎么寫循環,也不簡單把,至少需要 5 到 10 行的c#代碼,可能大家還會想到使用正則表達式,對,正則會簡單一些,但是你要快速的寫出這個正則表達式也不是特別簡單的事情。
另外,我們還需要考慮一些轉義的字符,是不是瞬間覺得也不簡單了。
解析 at 信息
好在 bot 的 sdk 給我們提供了一個簡單的方法。
protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
{Mention[] mentions = turnContext.Activity.GetMentions();if(mentions != null){foreach (var mention in mentions){...}}
}
GetMentions
?是一個 Activity 的擴展方法,里面具體的實現可以到 sdk 的源代碼里找到。這個方法會返回一個?Mention
?的數組
public class Mention
{...public ChannelAccount Mentioned { get; set; }...
}public class ChannelAccount
{...public string Name { get; set; }...
}
從上面的代碼可以看到,我可以通過 Mentioned 的 Name 來獲取被 at 的對象的名字。
var name = mention.Mentioned.Name
發送 at 信息
除了解析,sdk 當然也提供了發送 at 信息的方法,如下:
protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
{var mention = new Mention{Mentioned = turnContext.Activity.From,Text = $"<at>{XmlConvert.EncodeName(turnContext.Activity.From.Name)}</at>",};var replyActivity = MessageFactory.Text($"Hello {mention.Text}.");replyActivity.Entities = new List<Entity> { mention };await turnContext.SendActivityAsync(replyActivity, cancellationToken);
}
從上面的額代碼里可以看到,發送 at 信息并不是很簡單,還是需要我們自己來組建一個 Mention 的對象,然后把這個對象放如到回復的 activity 的 Entities 屬性里。
特別需要注意的一點是:需要 at 的人的名字,需要做 xml encode,來確保不會因為 name 里有特殊的字符,而導致整個text不合法。
看到這里,大家是不是對 at 的機制有了進一步的深入理解? :)