从NotifyBot访问UserProfile [英] Access UserProfile from NotifyBot

查看:44
本文介绍了从NotifyBot访问UserProfile的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试合并 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 UserProfiles 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 UserProfiles just like the one for ConversationReferences

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆