值不能为空。 (参数 'clientSecret')从机器人发送 activity 时
Value cannot be null. (Parameter 'clientSecret') when sending an activity from a bot
我们正在尝试使用机器人的 /api/messages 端点将 activity 直接发送到我们的机器人。我们这样做是为了让 2 个 Twilio 号码与我们的机器人相关联。
首先,我们使用以下代码获取机器人的访问令牌:
var authClient = new HttpClient();
var authRequest = new HttpRequestMessage
{
Method = HttpMethod.Post,
RequestUri = new Uri($"https://login.microsoftonline.com/botframework.com/oauth2/v2.0/token"),
Content = new StringContent($"grant_type=client_credentials&client_id={BOT_MIRCOSOFT_APP_ID}&client_secret={BOT_MICROSOFT_APP_PASSWORD}&scope=https%3A%2F%2Fapi.botframework.com%2F.default", Encoding.UTF8, "application/x-www-form-urlencoded"),
};
var authResponse = await authClient.SendAsync(authRequest).ConfigureAwait(false);
然后,我们将此访问令牌放入对机器人的 api 调用的 header 中,并通过 /api/messages 端点向机器人发送 activity。 activity 到达机器人并且一切正常,直到我们尝试从机器人发送 activity 。我们的 AdapterWithErrorHandler class 捕获到一条错误消息:值不能为空。 (参数 'clientSecret')。我们已经彻底搜索过了,找不到这个 clientSecret 变量在哪里。
我们如何解决此错误,以便我们可以从我们的机器人中发送 activity?
编辑:这是一个示例项目,它使用未更改的标准 echo bot 和控制台应用程序抛出此错误。要使其正常工作,您需要在控制台应用程序和 echo bot 的设置中输入有效的应用程序 ID 和应用程序密码。 https://github.com/andrew-j-frank/MicrosoftBotErrorSample
编辑:这是错误的堆栈跟踪:
at Microsoft.IdentityModel.Clients.ActiveDirectory.ClientCredential..ctor(String clientId, String clientSecret)
at Microsoft.Bot.Connector.Authentication.MicrosoftAppCredentials.<BuildAuthenticator>b__14_0()
at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
at System.Lazy`1.CreateValue()
at System.Lazy`1.get_Value()
at Microsoft.Bot.Connector.Authentication.AppCredentials.<BuildIAuthenticator>b__34_0()
at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
at System.Lazy`1.CreateValue()
at System.Lazy`1.get_Value()
at Microsoft.Bot.Connector.Authentication.AppCredentials.<GetTokenAsync>d__32.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
at Microsoft.Bot.Connector.Authentication.AppCredentials.<ProcessHttpRequestAsync>d__31.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Bot.Connector.Conversations.<ReplyToActivityWithHttpMessagesAsync>d__10.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
at Microsoft.Bot.Connector.ConversationsExtensions.<ReplyToActivityAsync>d__17.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at Microsoft.Bot.Builder.BotFrameworkAdapter.<SendActivitiesAsync>d__34.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Bot.Builder.TurnContext.<>c__DisplayClass25_0.<<SendActivitiesAsync>g__SendActivitiesThroughAdapter|1>d.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
at Microsoft.Bot.Builder.TurnContext.<SendActivityAsync>d__24.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at SampleBot.Bots.EchoBot.<OnMessageActivityAsync>d__0.MoveNext() in C:\Users\myuser\source\repos\SampleBot\SampleBot\Bots\EchoBot.cs:line 19
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable.ConfiguredTaskAwaiter.GetResult()
at Microsoft.Bot.Builder.ActivityHandler.<OnTurnAsync>d__0.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable.ConfiguredTaskAwaiter.GetResult()
at Microsoft.Bot.Builder.BotFrameworkAdapter.TenantIdWorkaroundForTeamsMiddleware.<OnTurnAsync>d__0.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable.ConfiguredTaskAwaiter.GetResult()
at Microsoft.Bot.Builder.MiddlewareSet.<ReceiveActivityWithStatusAsync>d__3.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable.ConfiguredTaskAwaiter.GetResult()
at Microsoft.Bot.Builder.BotAdapter.<RunPipelineAsync>d__18.MoveNext()
在 Azure 机器人服务中为用户到机器人消息生成承载令牌的所有代码都是专有的,因此对于如何生成此类令牌并没有真正面向公众的解释。您当前生成的令牌用于机器人到用户的消息,我想这就是您的问题所在。因此,您的机器人发送消息所要做的就是生成一个令牌,就像您的频道所做的那样。
您实际上不需要手动生成令牌,因为 Bot Framework SDK 会为您完成。您可以创建一个连接器客户端,就像我在回答您的其他问题时所解释的那样,您只需传入您的应用程序 ID 和密码作为凭据:
当然,如果您要构建自己的 API,那么所有这些身份验证都是可选的。如果您不关心发送到您的机器人的请求的身份验证,那么您不需要这样做,如果您不关心发送到您的频道的请求的身份验证,那么您也不需要这样做。或者,您可以想出自己的身份验证方式,而不是使用内置的 AAD 应用程序注册凭据。
我们正在尝试使用机器人的 /api/messages 端点将 activity 直接发送到我们的机器人。我们这样做是为了让 2 个 Twilio 号码与我们的机器人相关联。
首先,我们使用以下代码获取机器人的访问令牌:
var authClient = new HttpClient();
var authRequest = new HttpRequestMessage
{
Method = HttpMethod.Post,
RequestUri = new Uri($"https://login.microsoftonline.com/botframework.com/oauth2/v2.0/token"),
Content = new StringContent($"grant_type=client_credentials&client_id={BOT_MIRCOSOFT_APP_ID}&client_secret={BOT_MICROSOFT_APP_PASSWORD}&scope=https%3A%2F%2Fapi.botframework.com%2F.default", Encoding.UTF8, "application/x-www-form-urlencoded"),
};
var authResponse = await authClient.SendAsync(authRequest).ConfigureAwait(false);
然后,我们将此访问令牌放入对机器人的 api 调用的 header 中,并通过 /api/messages 端点向机器人发送 activity。 activity 到达机器人并且一切正常,直到我们尝试从机器人发送 activity 。我们的 AdapterWithErrorHandler class 捕获到一条错误消息:值不能为空。 (参数 'clientSecret')。我们已经彻底搜索过了,找不到这个 clientSecret 变量在哪里。
我们如何解决此错误,以便我们可以从我们的机器人中发送 activity?
编辑:这是一个示例项目,它使用未更改的标准 echo bot 和控制台应用程序抛出此错误。要使其正常工作,您需要在控制台应用程序和 echo bot 的设置中输入有效的应用程序 ID 和应用程序密码。 https://github.com/andrew-j-frank/MicrosoftBotErrorSample
编辑:这是错误的堆栈跟踪:
at Microsoft.IdentityModel.Clients.ActiveDirectory.ClientCredential..ctor(String clientId, String clientSecret)
at Microsoft.Bot.Connector.Authentication.MicrosoftAppCredentials.<BuildAuthenticator>b__14_0()
at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
at System.Lazy`1.CreateValue()
at System.Lazy`1.get_Value()
at Microsoft.Bot.Connector.Authentication.AppCredentials.<BuildIAuthenticator>b__34_0()
at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
at System.Lazy`1.CreateValue()
at System.Lazy`1.get_Value()
at Microsoft.Bot.Connector.Authentication.AppCredentials.<GetTokenAsync>d__32.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
at Microsoft.Bot.Connector.Authentication.AppCredentials.<ProcessHttpRequestAsync>d__31.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Bot.Connector.Conversations.<ReplyToActivityWithHttpMessagesAsync>d__10.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
at Microsoft.Bot.Connector.ConversationsExtensions.<ReplyToActivityAsync>d__17.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at Microsoft.Bot.Builder.BotFrameworkAdapter.<SendActivitiesAsync>d__34.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Bot.Builder.TurnContext.<>c__DisplayClass25_0.<<SendActivitiesAsync>g__SendActivitiesThroughAdapter|1>d.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
at Microsoft.Bot.Builder.TurnContext.<SendActivityAsync>d__24.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at SampleBot.Bots.EchoBot.<OnMessageActivityAsync>d__0.MoveNext() in C:\Users\myuser\source\repos\SampleBot\SampleBot\Bots\EchoBot.cs:line 19
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable.ConfiguredTaskAwaiter.GetResult()
at Microsoft.Bot.Builder.ActivityHandler.<OnTurnAsync>d__0.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable.ConfiguredTaskAwaiter.GetResult()
at Microsoft.Bot.Builder.BotFrameworkAdapter.TenantIdWorkaroundForTeamsMiddleware.<OnTurnAsync>d__0.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable.ConfiguredTaskAwaiter.GetResult()
at Microsoft.Bot.Builder.MiddlewareSet.<ReceiveActivityWithStatusAsync>d__3.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable.ConfiguredTaskAwaiter.GetResult()
at Microsoft.Bot.Builder.BotAdapter.<RunPipelineAsync>d__18.MoveNext()
在 Azure 机器人服务中为用户到机器人消息生成承载令牌的所有代码都是专有的,因此对于如何生成此类令牌并没有真正面向公众的解释。您当前生成的令牌用于机器人到用户的消息,我想这就是您的问题所在。因此,您的机器人发送消息所要做的就是生成一个令牌,就像您的频道所做的那样。
您实际上不需要手动生成令牌,因为 Bot Framework SDK 会为您完成。您可以创建一个连接器客户端,就像我在回答您的其他问题时所解释的那样,您只需传入您的应用程序 ID 和密码作为凭据:
当然,如果您要构建自己的 API,那么所有这些身份验证都是可选的。如果您不关心发送到您的机器人的请求的身份验证,那么您不需要这样做,如果您不关心发送到您的频道的请求的身份验证,那么您也不需要这样做。或者,您可以想出自己的身份验证方式,而不是使用内置的 AAD 应用程序注册凭据。