Как я могу проактивно вызвать диалог от бота без TurnContext? - PullRequest
0 голосов
/ 04 августа 2020

У меня есть бот Teams, который может отправлять пользователям упреждающие сообщения через webAPI. Я могу получить ConnectorClient из пространства имен Microsoft.Bot.Connector, а затем оттуда я могу идентифицировать соответствующий диалог и вызывать SendToConversationAsyn c, чтобы отправить сообщение пользователю.

Если я хочу использовать это для инициирования хотя диалог, похоже, проблема в том, что у меня нет TurnContext для ссылки. Я нашел сообщение здесь , которое показалось многообещающим, но это все еще зависит от запуска диалогового окна. В идеале я хотел бы иметь возможность сделать это через ссылку ConnectorClient, которая у меня уже есть, и попытка с нулевым TurnContext, похоже, не работает. Например, попробуйте следующее:

var dialogState = _accessors.ConversationState.CreateProperty<DialogState>(nameof(DialogState));
var dialogSet = new DialogSet(dialogState);
dialogSet.Add(new MyDialog());
DialogContext dc = await dialogSet.CreateContextAsync(turnContext, cancellationToken);
var turnResult = await dc.BeginDialogAsync("MyDialog");

Выдает исключение, если turnContext имеет значение null.

Этот ответ здесь также содержит несколько многообещающих идей, предлагающих имитировать входящее событие, но я могу сделать что-то вроде CreateInvokeActivity (), но отправка этого в беседу вызывает исключение. Я также не уверен, как запустить конвейер, чтобы передать сообщение в том же процессе, не заходя так далеко, как использование HTTPCLient для POST необработанного сообщения (что, как мне кажется, требует получения токена). У бота уже есть диалог 1: 1 с пользователем, но я бы хотел, чтобы это инициировало диалог, если это возможно. Есть ли способ, чтобы ConnectorClient начал диалог проактивно или программно инициировал вызов конвейера бота, чтобы он мог там начать?

Ответы [ 2 ]

1 голос
/ 05 августа 2020

Вы можете создать контекст поворота из ссылки преобразования, используя ContinueConversationAsync. Пожалуйста, обратитесь к docs и sample для получения дополнительной информации.

0 голосов
/ 06 августа 2020

Мне удалось придумать способ сделать это, но, вероятно, это не идеальный сценарий. Я хотел запустить диалог из API, в частности диалог аутентификации, который получает токен OAuth пользователя для доступа к графику. Если пользователь вошел в систему, токен возвращается немедленно, а если нет, он получает приглашение для входа. У меня есть что-то вроде этого в моем коде бота (отредактировано для краткости):

public static async Task<string> GetTokenAsync(ITurnContext turnContext, CancellationToken cancellationToken)
{
    var dialogState = _accessors.ConversationState.CreateProperty<DialogState>(nameof(DialogState));
    var dialogSet = new DialogSet(dialogState);
    dialogSet.Add(new AuthDialog());
    DialogContext dc = await dialogSet.CreateContextAsync(turnContext, cancellationToken);
    var turnResult = await dc.BeginDialogAsync("AuthDialog");
    await _accessors.ConversationState.SaveChangesAsync(turnContext, false, cancellationToken);

    if(turnResult.Status== DialogTurnStatus.Waiting)
    {
        _log.Debug("Got login request for user-waiting for response");
        return string.Empty;
    }
    else if(turnResult.Result is TokenResponse)
    {
        return ((TokenResponse)turnResult.Result).Token;
    }
    return null;
}

Это создает диалог и, если возможно, возвращает токен. В моем webAPI у меня есть что-то вроде этого, чтобы активировать его:

string conversationID = "CONV_ID_FROM_STATE";

var members = await m_client.Conversations.GetConversationMembersAsync(conversationID);

BotFrameworkAdapter b = new BotFrameworkAdapter(new SimpleCredentialProvider("BOT ID", "BOT_SECRET"));
var message = Activity.CreateMessageActivity();
message.Text = "login";
message.From = new ChannelAccount(members[0].Id);
message.Conversation = new ConversationAccount(id: conversationID, conversationType: "personal", tenantId: :BOT_TENANT_ID);
message.ChannelId = "msteams";

TurnContext t = new TurnContext(b, (Activity)message);
ClaimsIdentity id = new ClaimsIdentity();
id.AddClaim(new Claim("aud", "BOT_ID"));
t.TurnState.Add("BotIdentity", id);
t.TurnState.Add("Microsoft.Bot.Builder.BotAdapter.OAuthScope", "https://api.botframework.com");
t.TurnState.Add("Microsoft.Bot.Connector.IConnectorClient", m_client);
string token = await myBot<AuthDialog>.GetTokenAsync(t, default);

На этом этапе, если токен является пустой строкой, пользователь не вошел в систему, но в противном случае он должен быть действительным токен для выполнения вызовов графика. Я протестировал это с несколькими новыми учетными записями, и, похоже, это работает, поэтому я называю это победой на данный момент. Если что-то здесь принципиально не работает, прокомментируйте.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...