решаемые
Благодаря пользователю MarkMoose я понял, что в моей таблице базы данных не хранятся полные идентификаторы.
Будущие отладчики: Если это не поможет вам решить вашу проблему, пожалуйста, посмотрите на мой разговор с MarkMoose, они провели меня через очень полезные шаги по устранению неполадок.
Я пытаюсь создать бота Microsoft Teams, размещенного на Azure, с использованием Microsoft Bot SDK версии 4.0.
Поток выглядит следующим образом
Срабатывает тревога веб-приложения. Посылает POST-запрос боту, который содержит (все эти данные собраны из предыдущего сообщения от пользователя)
- To ID (получателя)
- На имя (получателя)
- Из ID (мой бот)
- От имени (мой бот)
- идентификатор канала
- ID разговора
- Сервисный URL (получателя)
Бот извлекает эту информацию из JSON, формируя новую активность сообщений
- Бот отправляет активность пользователю
Проблема: Когда бот пытается создать объект ConversationAccount
с использованием указанных выше учетных данных, он выдает следующую ошибку:
Обнаружено исключение: Microsoft.Bot.Schema.ErrorResponseException: операция вернула недопустимый код состояния «BadRequest»
Вот часть соответствующей части кода.
Обратите особое внимание на следующие строки:
var account = new MicrosoftAppCredentials(botCreds["App ID"], botCreds["App Password"]);
var jwtToken = await account.GetTokenAsync();
ConnectorClient connector = new ConnectorClient(new System.Uri(serviceURL), account);
Это линии, которые немного различаются, когда я нашел решение проблемы от других людей. В моей текущей версии кода я использую это сообщение решение . Я также попробовал созданный им класс DelegatingHandler, но он выдает ту же ошибку.
/// <summary>
/// Sends a message to a user or group chat.
/// </summary>
/// <param name="forwardContext">JSON object containing credentials for destination chat.</param>
/// <param name="messageToSend">The message to forward.</param>
/// <returns></returns>
private async Task ForwardMessage(JToken forwardContext, string messageToSend)
{
// Collect data from JSON input
var restCmd = forwardContext;
var toId = (string) restCmd["toId"];
var toName = (string) restCmd["toName"];
var fromId = (string) restCmd["fromId"];
var fromName = (string) restCmd["fromName"];
var channelId = (string) restCmd["channel"];
var serviceURL = (string) restCmd["serviceURL"];
var conversationId = (string) restCmd["conversation"];
var cred_str = $@"toId: {toId}
toName: {toName}
fromId: {fromId}
fromName: {fromName}
channelId: {channelId}
serviceURL: {serviceURL}
conversationId: {conversationId}";
_logger.LogInformation(cred_str);
_logger.LogInformation($"Forwarding the following message to {toName}: {messageToSend}");
Dictionary<string, string> botCreds = GetBotCredentials();
// Create relevant accounts
ChannelAccount userAccount = new ChannelAccount(name: toName, id: toId);
ChannelAccount botAccount = new ChannelAccount(name: fromName, id: fromId);
if (!MicrosoftAppCredentials.IsTrustedServiceUrl(serviceURL))
{
_logger.LogInformation($"Adding to trusted service urls: {serviceURL}");
// Register the service URL as trusted
MicrosoftAppCredentials.TrustServiceUrl(serviceURL);
}
MicrosoftAppCredentials.TrustServiceUrl(serviceURL);
var account = new MicrosoftAppCredentials(botCreds["App ID"], botCreds["App Password"]);
var jwtToken = await account.GetTokenAsync();
ConnectorClient connector = new ConnectorClient(new System.Uri(serviceURL), account);
// Create a new message activity
IMessageActivity message = Activity.CreateMessageActivity();
conversationId = (
await connector
.Conversations
.CreateDirectConversationAsync(botAccount, userAccount)).Id;
// Set relevant message details
message.From = botAccount;
message.Recipient = userAccount;
message.Text = messageToSend;
message.Locale = "en-Us";
message.ChannelId = channelId;
// Create a new converstaion and add it to the message.
message.Conversation = new ConversationAccount(id: conversationId);
await connector.Conversations.SendToConversationAsync((Activity) message);
}
А вот мой код для сбора информации, использованной выше. Эта функция вызывается при первом взаимодействии пользователя с ботом.
/// <summary>
/// Called only when the !setup command is sent to the bot.
/// Updates the chats info in the DB.
/// </summary>
/// <param name="activity">Activity of the message the "!setup" command was sent in.</param>
/// <returns>True if the update query executed fine.</returns>
private bool SetupCommand(Activity activity)
{
// Connect to the database
this.database = new DBConnection(serverIP, databaseName, userName, password, _logger);
this.database.Connect();
var tableName = "ms_teams_chats";
// Data gathered from Activity for database.
// User ID
string toId = activity.From.Id;
// User Name
string toName = activity.From.Name;
// Bot ID
string fromId = activity.Recipient.Id;
// Bot Name
string fromName = activity.Recipient.Name;
// Users service URL
string serviceURL = activity.ServiceUrl;
// The platform the message came from. Example: 'skype'
string channelId = activity.ChannelId;
string conversationID = activity.Conversation.Id;
string conversationName = activity.Conversation.Name;
bool isGroupChat = activity.Conversation.IsGroup ?? false;
string upsertQuery = string.Empty;
upsertQuery = $@"
INSERT INTO {tableName}
(user_id, user_name, assoc_bot_id, assoc_bot_name, service_url, channel_id, conversation_id, is_group_chat)
VALUES (
'{toId}', '{toName}', '{fromId}', '{fromName}', '{serviceURL}', '{channelId}', '{conversationID}', {isGroupChat}
)
ON DUPLICATE KEY UPDATE
user_id = '{toId}',
user_name = '{toName}',
assoc_bot_id = '{fromId}',
assoc_bot_name = '{fromName}',
service_url = '{serviceURL}',
channel_id = '{channelId}',
conversation_id = '{conversationID}',
is_group_chat = {isGroupChat}
";
try
{
this.database.ExecuteNonQuery(upsertQuery);
}
catch (System.Exception e)
{
_logger.LogError($"Could not update users information. \nError:{e.ToString()}");
return false;
}
return true;
}