从NotifyBot访问UserProfile [英] Access UserProfile from NotifyBot
问题描述
我正在尝试合并 EchoBot
和 ProactiveBot
的功能.解析用户命令的机器人,也可以通过URL触发该机器人,以根据其 UserProfile
的内容向某些用户发送消息.
我设法使这两个部分都能正常工作,但是在从 NotifyController
访问 UserProfile
s时遇到了麻烦,或者无法以其他方式解决问题.我尝试了几件事,阅读了许多教程,还这很好的解释,但我仍然很困惑.>
所以我的问题是:如何重写 NotifyController
,以便它在我的Bot类(实现 ActivityHandler
的那个)中调用一个方法-就像 BotController
(来自 EchoBot
)?
或者,如果更好的话:如何在 NotifyController
的消息处理程序中获取对 UserProfile
的引用?
谢谢!
好的,我可以使用它.
基本上,我复制了sessionReferences的所有代码,因为这些代码存储在Bot中并在NotifyController中使用.
某些代码,以防其他人试图做同样的事情:
Startup.cs
创建另一个Singleton.
services.AddSingleton< ConcurrentDictionary< string,UserProfile>>>();
在机器人课程中
我有一个存储 UserProfile
的变量,就像 ConversationReference
s
私有只读ConcurrentDictionary< string,ConversationReference>_conversationReferences;私有只读ConcurrentDictionary< string,UserProfile>_userProfiles;
构造函数现在开始像这样
public RmindrBot(ConversationState sessionState,UserState userState,ConcurrentDictionary<字符串,ConversationReference>对话参考,ConcurrentDictionary<字符串,UserProfile>userProfiles){_conversationReferences =对话参考;_userProfiles = userProfiles;...
(我认为这对我来说最令人惊讶-认为框架不会神奇地找出新的签名.)
添加引用的方法:
private void AddConversationReference(活动活动){var对话参考= activity.GetConversationReference();_conversationReferences.AddOrUpdate(sessionReference.User.Id,对话参考,(key,newValue)=>对话参考);}
...在 OnMessageActivityAsync
中调用:
var userProfile =等待userStateAccessors.GetAsync(turnContext,()=> new UserProfile());userProfile.ID = turnContext.Activity.From.Id;AddUserProfile(userProfile);
NotifyController
私有只读ConcurrentDictionary< string,UserProfile>_userProfiles;公共NotifyController(IBotFrameworkHttpAdapter适配器,IConfiguration配置,ConcurrentDictionary<字符串,ConversationReference>对话参考)ConcurrentDictionary<字符串,ConversationReference>对话参考,ConcurrentDictionary<字符串,UserProfile>userProfiles){_adapter =适配器;_conversationReferences =对话参考;_userProfiles = userProfiles;...
然后我们最终可以在回调方法中使用它,并将用户与其ID相匹配:
私有异步任务BotCallback(ITurnContext turnContext,CancellationToken cancelToken){var userProfile = _userProfiles [turnContext.Activity.From.Id];等待turnContext.SendActivityAsync("proactive hello" + userProfile.ID);}
I'm trying to kind of merge the functionality of EchoBot
and ProactiveBot
. A bot that parses user commands, which can also be triggered through a URL to send some users a message based on the contents of their UserProfile
.
I managed to get both parts to work, but I'm having trouble accessing the UserProfile
s from the NotifyController
, or solving the problem another way. I tried a few things, read many of the tutorials and also this excellent explanation, but I'm still stuck.
So my question is: How do I rewrite NotifyController
so it calls a method in my Bot class (the one implementing ActivityHandler
) - just like BotController
(from EchoBot
) does?
Or, if that's better: How do I get a reference to the UserProfile
in the message handler in NotifyController
?
Thanks!
Alright, I got it to work.
Basically I duplicated all the code for the conversationReferences, because those get stored in the Bot and are used in NotifyController.
Some code, in case somebody else is trying to do the same:
Startup.cs
Create another Singleton.
services.AddSingleton<ConcurrentDictionary<string, UserProfile>>();
In the bot class
I have a variable storing UserProfile
s just like the one for ConversationReference
s
private readonly ConcurrentDictionary<string, ConversationReference> _conversationReferences;
private readonly ConcurrentDictionary<string, UserProfile> _userProfiles;
The constructor now starts like this
public RmindrBot(ConversationState conversationState,
UserState userState,
ConcurrentDictionary<string, ConversationReference> conversationReferences,
ConcurrentDictionary<string, UserProfile> userProfiles)
{
_conversationReferences = conversationReferences;
_userProfiles = userProfiles;
...
(I think this is the most surprising bit for me - didn't think the framework would just magically figure out the new signature.)
A method for adding references:
private void AddConversationReference(Activity activity)
{
var conversationReference = activity.GetConversationReference();
_conversationReferences.AddOrUpdate(
conversationReference.User.Id,
conversationReference,
(key, newValue) => conversationReference);
}
...which is called in OnMessageActivityAsync
:
var userProfile = await userStateAccessors.GetAsync(turnContext, () => new UserProfile());
userProfile.ID = turnContext.Activity.From.Id;
AddUserProfile(userProfile);
NotifyController
private readonly ConcurrentDictionary<string, UserProfile> _userProfiles;
public NotifyController(
IBotFrameworkHttpAdapter adapter,
IConfiguration configuration,
ConcurrentDictionary<string, ConversationReference> conversationReferences)
ConcurrentDictionary<string, ConversationReference> conversationReferences,
ConcurrentDictionary<string, UserProfile> userProfiles)
{
_adapter = adapter;
_conversationReferences = conversationReferences;
_userProfiles = userProfiles;
...
And then we can finally use it in the callback method and match the user to their ID:
private async Task BotCallback(ITurnContext turnContext, CancellationToken cancellationToken)
{
var userProfile = _userProfiles[turnContext.Activity.From.Id];
await turnContext.SendActivityAsync("proactive hello " + userProfile.ID);
}
这篇关于从NotifyBot访问UserProfile的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!