C# 无法将参数传递给ContinueConversationAsync方法内的BotCallback
我正在尝试在bot framework v4上实现主动消息,它可以工作,但仅使用BotCallback函数上的字符串,我需要传递自定义文本,但ContinueConversationAsync似乎不允许这样做C# 无法将参数传递给ContinueConversationAsync方法内的BotCallback,c#,asp.net-core,botframework,C#,Asp.net Core,Botframework,我正在尝试在bot framework v4上实现主动消息,它可以工作,但仅使用BotCallback函数上的字符串,我需要传递自定义文本,但ContinueConversationAsync似乎不允许这样做 public async Task<bool> SendProactiveMessage(MensajeExterno mensajeExterno) { var referenciaDeConversacion = Obten
public async Task<bool> SendProactiveMessage(MensajeExterno mensajeExterno)
{
var referenciaDeConversacion = ObtenerReferenciaConversacion(mensajeExterno.ConversationId);
var continuationActivity = referenciaDeConversacion.GetContinuationActivity();
if (referenciaDeConversacion == null) return false;
await ((BotAdapter)_adapter).ContinueConversationAsync(_appId, referenciaDeConversacion, BotCallback, default(CancellationToken));
return true;
}
private ConversationReference ObtenerReferenciaConversacion(string conversationId)
{
return new ConversationReferenceModulo().ObtenerConversationReference(conversationId);
}
public MensajeroDefaultModulo(IBotFrameworkHttpAdapter adapter, IConfiguration configuration)
{
_adapter = adapter;
_appId = configuration["MicrosoftAppId"];
if (string.IsNullOrEmpty(_appId))
{
_appId = Guid.NewGuid().ToString(); //if no AppId, use a random Guid
}
}
private async Task BotCallback(ITurnContext turnContext, CancellationToken cancellationToken)
{
var activity = turnContext.Activity;
await turnContext.SendActivityAsync("proactive hello", cancellationToken: cancellationToken);
}
我知道您想要做的是向BotCallback传递一个值,该值可以通过SendActivityAsync方法发送回来 为此,可以使用lambda表达式而不是调用BotCallback
public async Task<bool> SendProactiveMessage(MensajeExterno mensajeExterno)
{
var yourVariable = "blah";
var referenciaDeConversacion = ObtenerReferenciaConversacion(mensajeExterno.ConversationId);
var continuationActivity = referenciaDeConversacion.GetContinuationActivity();
if (referenciaDeConversacion == null) return false;
await ((BotAdapter)_adapter).ContinueConversationAsync(_appId, referenciaDeConversacion, async (context, token) => {
await turnContext.SendActivityAsync("proactive hello " + yourVariable, cancellationToken: cancellationToken);
}, default(CancellationToken));
return true;
}
这源于此处对主动消息传递示例的引用:
有关Lambda表达式,请参见
lambda表达式是一个匿名函数,可以包含
表达式和语句,并可用于创建委托或
表达式树类型
所有lambda表达式都使用lambda运算符=>,该运算符被读取为
去。lambda运算符的左侧指定输入
参数(如果有),右侧包含表达式或
语句块。lambda表达式x=>x*x读取x到x
时报x
更新了API控制器示例
SendProactiveMessage需要位于Bot项目的控制器中,例如:
using System;
using System.Collections.Concurrent;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Bot.Builder;
using Microsoft.Bot.Builder.Integration.AspNet.Core;
using Microsoft.Bot.Schema;
using Microsoft.Extensions.Configuration;
namespace ProactiveBot.Controllers
{
[Route("api/notify")]
[ApiController]
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"];
// If the channel is the Emulator, and authentication is not in use,
// the AppId will be null. We generate a random AppId for this case only.
// This is not required for production, since the AppId will have a value.
if (string.IsNullOrEmpty(_appId))
{
_appId = Guid.NewGuid().ToString(); //if no AppId, use a random Guid
}
}
public async Task<IActionResult> Get([FromQuery(Name = "taskID")] int taskID)
{
foreach (var conversationReference in _conversationReferences.Values)
{
await ((BotAdapter)_adapter).ContinueConversationAsync(_appId, conversationReference, async (context, token) => {
await context.SendActivityAsync("proactive task notification for TaskID: " + taskID.ToString());
}, default(CancellationToken));
}
// Let the caller know proactive messages have been sent
return new ContentResult()
{
Content = "<html><body><h1>Proactive messages have been sent.</h1><p>" + taskID.ToString() + "</p></body></html>",
ContentType = "text/html",
StatusCode = (int)HttpStatusCode.OK,
};
}
}
}
然后,您可以通过注入的适配器访问上下文和令牌。以上代码主要来自当前版本
因此,我可以调用这个API,例如在我的例子中传入taskID参数,然后通过ContinueConversationAsync发送给用户。您可以使用LINQ方法对BotCallback进行包装。但就我个人而言,我不理解这些代表没有任何事件的想法
[HttpPost]
public async Task<IActionResult> Post([FromBody] string messageText)
{
foreach (var conversationReference in _conversationReferences.Values)
{
await ((BotAdapter)_adapter).ContinueConversationAsync(_appId, conversationReference, async (context, token) => await BotCallback(messageText, context, token), default(CancellationToken));
}
return new ContentResult()
{
Content = "<html><body><h1>Proactive messages have been sent.</h1></body></html>",
ContentType = "text/html",
StatusCode = (int)HttpStatusCode.OK,
};
}
private async Task BotCallback(string message, ITurnContext turnContext, CancellationToken cancellationToken)
{
await turnContext.SendActivityAsync(message, cancellationToken: cancellationToken);
}
你所说的自定义文本是什么意思?谢谢Christopher,这里的问题是我既没有turnContext也没有cancellationToken。API调用SendProactiveMessage方法,如何解决这个问题?我尝试了依赖注入,但没有成功it@TheMemebot您的SendProactiveMessage方法是否不在您的Bot项目的控制器中?我将尝试您的更新解决方案,并将返回给您,让您知道该方法是否有效。是的,我的方法在我的机器人内project@TheMemebot运气好吗?