我有Teams的代码,非常类似于ms的主动信息的例子。当我在本地运行机器人时--无论是使用bot模拟器,还是在Azure注册的Ngrok + Teams Bot,通知都可以正常工作。当我将我的机器人发布到Azure (作为应用程序服务)时,它没有会话引用来发送积极的信息。
我的通知控制器看起来与示例相同,我只是添加了打印有多少conv引用。
public class NotifyController : ControllerBase {
private readonly IBotFrameworkHttpAdapter _adapter;
private readonly string _appId;
private readonly ConcurrentDictionary<string, ConversationReference> _conversationReferences;
public NotifyController(IBotFrameworkHttpAdapter adapter, IConfiguration configuration, ConcurrentDictionary<string, ConversationReference> conversationReferences) {
_adapter = adapter;
_conversationReferences = conversationReferences;
_appId = configuration["MicrosoftAppId"] ?? "<my-app-id>";
}
public async Task<IActionResult> Get() {
foreach (var conversationReference in _conversationReferences.Values) {
Debug.WriteLine($"awaiting callback from convdId({conversationReference.Conversation.Id}) from user {conversationReference.User.Name}{conversationReference.User.Id}");
await ((BotAdapter)_adapter).ContinueConversationAsync(_appId, conversationReference, BotCallback, default);
}
return new ContentResult() {
Content = $"<html><body><h1>Proactive messages have been sent to {_conversationReferences.Count} conversations.</h1></body></html>",
ContentType = "text/html",
StatusCode = (int)HttpStatusCode.OK,
};
}
private async Task BotCallback(ITurnContext turnContext, CancellationToken cancellationToken) {
await turnContext.SendActivityAsync("proactive hello", cancellationToken: cancellationToken);
}
}
ConfigureServices in Startup.cs:
public void ConfigureServices(IServiceCollection services) {
services.AddHttpClient().AddControllers().AddNewtonsoftJson();
services.AddSingleton<IBotFrameworkHttpAdapter, AdapterWithErrorHandler>();
services.AddSingleton<IStorage, MemoryStorage>();
services.AddSingleton<UserState>();
services.AddSingleton<ConversationState>();
services.AddSingleton<MainDialog>();
services.AddTransient<IBot, DialogBot<MainDialog>>();
services.AddSingleton<ConcurrentDictionary<string, ConversationReference>>();
}
在Bot代码中也有函数(注释函数不重要,行为是相同的):
public override async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default) {
await base.OnTurnAsync(turnContext, cancellationToken);
//AddConversationReference(turnContext.Activity as Activity);
await ConversationState.SaveChangesAsync(turnContext, false, cancellationToken);
await UserState.SaveChangesAsync(turnContext, false, cancellationToken);
}
...
private void AddConversationReference(Activity activity) {
var conversationReference = activity.GetConversationReference();
ConversationReferences.AddOrUpdate(conversationReference.User.Id, conversationReference, (key, newValue) => conversationReference);
}
protected override Task OnConversationUpdateActivityAsync(ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken) {
AddConversationReference(turnContext.Activity as Activity);
return base.OnConversationUpdateActivityAsync(turnContext, cancellationToken);
}
我不知道在哪里设置了引用,以调查它们为什么没有设置:/在本地运行,我可以看到适当数量的对话。
我还添加了日志,以查看希尔顿·吉塞诺评论是否适用;似乎没有设置会话引用,因此我没有任何数据要保存。有时(我不知道在什么情况下) OnTurnAsync
被调用,然后在会话引用中有数据。
发布于 2022-04-11 16:51:42
您所使用的只是一个示例,因此它是为了教授重要的概念,而不是100%地用于生产中。例如,在示例中,它将应用程序的所有数据存储在内存中(注意这一行:services.AddSingleton<IStorage, MemoryStorage>();
)。这意味着所存储的信息,如会话引用,只有在应用程序运行时才可用,并且只能在运行的单个计算机上使用。
对于生产场景,您需要将这些会话引用保存到“持久”存储(该存储可以持续多久),例如数据库或某种类型的文件存储。然后,您可以在需要时从该存储中检索它,例如发送一条积极的信息。
与此相关的是,当您将某项内容存储在永久位置时,通常需要“键入”它,这意味着存储它的方式可以在将来需要时唯一地找到每条记录。对于Teams来说,为用户使用AadObjectId是一个很好的起点,因为它对每个用户都是唯一的。
https://stackoverflow.com/questions/71831343
复制相似问题