[BotFramework]: есть ли способ отобразить подсказку Oauth на карте героя или адаптивной карте в BOT, разработанной с использованием SDK V4 в C #? - PullRequest
0 голосов
/ 25 мая 2019

enter image description here Я разрабатываю чат-бота с использованием V4 в C #; Я реализовал функцию аутентификации в диалоговом окне «Водопад», используя подсказку OauthCard, я хочу, чтобы эта подсказка oauth-карты отображалась на карточке Hero или Adaptive или любой другой карточке, которая подходит для работы функции входа в канал чата.

В настоящее время подсказка oauth-карты не отображается в канале веб-чата, в результате чего я не могу войти в систему, поэтому подумал, что если я смогу отобразить функцию входа в oauth Prompt в карточке Hero или любой другой подходящей карточке, тогда я смогу продолжить ее. функциональность аутентификации.

Я включил Oauth Prompt, используя ссылку ниже, и она прекрасно работает в эмуляторе:

Как исправить навигацию следующего шага с помощью подсказки oauth в диалоге водопада в боте SDK V4, созданном с использованием C #, без ввода чего-либо?

Но не в состоянии сделать это на канале Webchat, поэтому подумал, что если я оставлю это в карточке героя, это может сработать.

  • Язык: C #
  • SDK: V4
  • Канал: канал веб-чата

Пожалуйста, предоставьте код или процедуру шаг за шагом в подробном руководстве, так как я довольно плохо знаком с BOT и кодированием, чтобы я мог решить мою проблему.

Пожалуйста, помогите.

Спасибо и С уважением -ChaitayaNG

Я не знаю, как это сделать, поэтому я попытался сделать следующее в index.html: https://github.com/microsoft/BotFramework-WebChat/tree/master/samples/18.customization-open-url

Это тоже не сработало для меня.

Я также посмотрел ссылки ниже, но, насколько я понимаю, были комментарии для Team Channel, но ничего конкретного для канала веб-чата:

https://github.com/microsoft/botframework-sdk/issues/4768

Я также посмотрел на ссылку ниже, но поскольку она была связана с React, я не исследовал ее, поскольку я делаю чат-бота в канале веб-чата и в лазурном C #:

https://github.com/microsoft/BotFramework-WebChat/tree/master/samples/10.a.customization-card-components

Я также пытался вызвать подсказку oauth внутри карты Singin, которая не работала, так как она не вызывала подсказку ни в эмуляторе, ни в веб-канале.

Следовательно, мне нужна помощь, так как карты oauth не загружаются в канал веб-чата даже после перехода по вышеуказанным ссылкам. Мысль о том, что если мы сможем хранить некоторые карты, это можно сделать, но также не нашла ничего конкретного. Поскольку я новичок в BOT и программировании, возможно, я что-то пропустил, поэтому, пожалуйста, помогите или предоставьте пошаговое руководство о том, как это сделать.

Ожидаемый результат: необходимо, чтобы приглашение oauth отображалось внутри карты HeroCard или любой другой подходящей карты, так как код не работает, или загрузка приглашения oauth в канале Webchat нормально работает в эмуляторе. Фактический результат: не знаю, как этого достичь.

Добавление деталей в соответствии с комментариями Ричардсона: Привет Ричардсон,

Я использовал OauthPrompt в диалоговом окне "Водопад", где в ШАГ 1. Я отображаю подсказку OAuthCard, где нажимаю на ссылку, появляется новое окно для ввода учетных данных и выдается магический код. Я ввожу магический код в браузере ШАГ 2: Здесь я получаю токен и продолжаю, как я сказал, это работает в эмуляторе, как описано в ссылке ниже:

Как исправить навигацию следующего шага с помощью подсказки oauth в диалоге водопада в боте SDK V4, созданном с использованием C #, без ввода чего-либо?

При входе в Webchat мне показалось следующее: [Файл типа application / vnd.microsoft.card.oauth ']

Вместо кнопки входа или ссылки.

Код, который я использовал, следующий:

public class LoginDialog : WaterfallDialog
{
    public LoginDialog(string dialogId, IEnumerable<WaterfallStep> steps = null)
         : base(dialogId, steps)
    {
        AddStep(async (stepContext, cancellationToken) =>
        {
            await stepContext.Context.SendActivityAsync("Please login using below option in order to continue with other options...");

            return await stepContext.BeginDialogAsync("loginprompt", cancellationToken: cancellationToken); // This actually calls the  dialogue of OAuthPrompt whose name is  in EchoWithCounterBot.LoginPromptName.  


        });

        AddStep(async (stepContext, cancellationToken) =>
        {
            Tokenresponse = (TokenResponse)stepContext.Result;

            if (Tokenresponse != null)
            {

                await stepContext.Context.SendActivityAsync($"logged in successfully... ");


                return await stepContext.BeginDialogAsync(DisplayOptionsDialog.Id); //Here it goes To another dialogue class where options are displayed
            }
            else
            {
                await stepContext.Context.SendActivityAsync("Login was not successful, Please try again...", cancellationToken: cancellationToken);


                await stepContext.BeginDialogAsync("loginprompt", cancellationToken: cancellationToken);
            }

            return await stepContext.EndDialogAsync();
        });
    }

    public static new string Id => "LoginDialog";

    public static LoginDialog Instance { get; } = new LoginDialog(Id);
}

В maindialog, называемом классом Mainrootdialog: 1. У меня есть переменная LoginPromptName = "loginprompt" и другой параметр для имени соединения; public const string ConnectionName = "conname";

  1. Затем у меня есть метод с именем prompt, который принимает имя соединения и имеет код, связанный с oauthprompt, как указано ниже:
  private static OAuthPrompt Prompt(string connectionName)
        {
            return new OAuthPrompt(
               "loginprompt",
               new OAuthPromptSettings
               {
                   ConnectionName = connectionName,
                   Text = "signin",
                   Title = "signin",
                   Timeout = 300000, // User has 5 minutes to login (1000 * 60 * 
               });
        }
  1. Наконец, это приглашение добавляется в Dialogset или стек, как показано ниже:
     public MainRootDialog(UserState userState)
            : base("root")
        {
            _userStateAccessor = userState.CreateProperty<JObject>("result");

            AddDialog(Prompt(ConnectionName));
            AddDialog(LoginDialog.Instance);            
            InitialDialogId = LoginDialog.Id;
        }

Как пытался объяснить ранее, прекрасно работает в эмуляторе, как вы могли видеть из моих комментариев в приведенной выше общей ссылке

Но в канале чата не загружается кнопка или ссылка дает мне следующее: [Файл типа 'application / vnd.microsoft.card.oauth']

Я попробовал следующую ссылку GitHub, которая у меня не работалавставка или прикрепление файла HTML для справки: https://github.com/microsoft/BotFramework-WebChat/tree/master/samples/18.customization-open-url

<!DOCTYPE html>
<html lang="en-US">
<head>
    <title>Web Chat: Customize open URL behavior</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <!--
      For demonstration purposes, we are using the development branch of Web Chat at "/master/webchat.js".
      When you are using Web Chat for production, you should use the latest stable release at "/latest/webchat.js",
      or lock down on a specific version with the following format: "/4.1.0/webchat.js".
    -->
    <script src="https://cdn.botframework.com/botframework-webchat/latest/webchat.js"></script>
    <style>
        html, body {
            height: 100%
        }

        body {
            margin: 0
        }

        #webchat,
        #webchat > * {
            height: 100%;
            width: 100%;
        }
    </style>
</head>
<body>
    <div id="webchat" role="main">
        <iframe src='https://webchat.botframework.com/embed/TestBotForOauthPrompt?s=<<Given my secretkey of web chat channel>>' style='min-width: 400px; width: 100%; min-height: 500px;'></iframe>
    </div>
    <script>
      (async function () {
        // In this demo, we are using Direct Line token from MockBot.
        // To talk to your bot, you should use the token exchanged using your Direct Line secret.
        // You should never put the Direct Line secret in the browser or client app.
        // https://docs.microsoft.com/en-us/azure/bot-service/rest-api/bot-framework-rest-direct-line-3-0-authentication
        const res = await fetch('https://testbotforoauthprompt.azurewebsites.net//directline//token', { method: 'POST' });
        const { token } = await res.json();
        window.WebChat.renderWebChat({
          directLine: window.WebChat.createDirectLine({ token }),
          // We are adding a new middleware to handle card action
          cardActionMiddleware: () => next => async ({ cardAction, getSignInUrl }) => {
            const { type, value } = cardAction;
            switch (type) {
              case 'signin':
                // For OAuth or sign-in popups, we will open the auth dialog directly.
                const popup = window.open();
                const url = await getSignInUrl();
                popup.location.href = url;
                break;
              case 'openUrl':
                if (confirm(`Do you want to open this URL?\n\n${ value }`)) {
                  window.open(value, '_blank');
                }
                break;
              default:
                return next({ cardAction, getSignInUrl });
            }
          }
        }, document.getElementById('webchat'));
        document.querySelector('#webchat > *').focus();
      })().catch(err => console.error(err));
    </script>
</body>
</html>

При переходе по предоставленной вами ссылке она не открывается, выдает ошибку 404


Дата: 29 мая 2019 г. Причина: далеезапросы на входные данные, предоставленные Ричардсоном

Я понимаю, что внутри класса контроллера написан код .NET, который генерирует токен.Существует HTML-страница для загрузки нашего веб-чата, которая содержит необходимые сценарии для хранения или предоставления токенов, а затем бот-чат открывается всякий раз, когда мы открываем этот HTML-файл.Тем не менее, у меня есть следующие запросы.Это может показаться очень простым, но, пожалуйста, потерпите меня, поскольку я новичок в кодировании:

  1. Где должен быть написан код, как он будет вызываться, потому что я не указываю в своем HTML-скриптеили где-нибудь вызвать метод индекса класса Controller, чтобы сгенерировать токен и использовать его?Или он автоматически вызовет метод index внутри контроллера.Если нет, то где автоматически указывать этот метод вызова?Можно ли предоставить полное решение, например, иметь код бота и класс контроллера в решении, чтобы я мог получить лучшую картину, чтобы я мог задавать любые другие дополнительные запросы, если таковые имеются?

  2. Это.net код это отдельное решение или внутри того же бота решение контроллера класса должно быть написано?Если это отдельное решение, то как опубликовать это на ресурсе BOT в Azure?Как бот и новое решение будут взаимодействовать автоматически без предоставления какого-либо соединения?

  3. Я предполагаю, что это должен новый класс внутри того же решения BOT Code в Visual Studio.Теперь у меня есть дополнительные вопросы по этому (на основе этого предположения):

a.Насколько я понимаю в вашем объяснении, метод post не работает, потому что нет генератора токенов, поэтому он выдает ошибку.Вы можете использовать приведенную ниже ссылку для написания кода и получения токена, который снова приводит к вопросу № 1?

Как правильно проходить проверку подлинности с помощью JavaScript в файле HTML для элемента управления Microsoft Web Chatдля Bot Framework v4?

b.В файле HTML, если я напишу сценарий, указанный в приведенной выше ссылке, он должен быть в той же асинхронной функции, или мы должны удалить асинхронную функцию?

c.Тем не менее, параметры стиля, такие как BOT Avatar и т. Д., Работают, если их оставить как есть?так же, как другие сценарии для отображения приветственного сообщения?

d.В GetElementByID ('') мы передаем бота в качестве значения по ссылке выше, но в реальных примерах мы передаем веб-чат, потому что мы изменили метод POST на новый скрипт?

e.Должен ли быть сохранен метод post или его можно удалить?Вместо строки сообщения:

const res = await fetch ('https://examplebot.azurewebsites.net/directline/token', {method:' POST '});Напишите новый, как показано ниже: скрипт, приведенный ниже (взят из ссылки выше):

@model ChatConfig
@{
    ViewData["Title"] = "Home Page";
}
<link href="https://cdn.botframework.com/botframework-webchat/latest/botchat.css" rel="stylesheet" />
<div id="bot" />
<script src="https://cdn.botframework.com/botframework-webchat/latest/botchat.js"></script>
<script>
      BotChat.App({
          directLine: {
              secret: '@Model.Token'
          },
        user: { id: @Model.UserId },
        bot: { id: 'botid' },
        resize: 'detect'
      }, document.getElementById("bot"));
</script>

Вы также объяснили, что, чтобы избежать всех этих осложнений и упростить процесс, просто сохраните свой секрет в файле: Current: const {token} = await res.json ();Чтобы сделать это просто: const {token} = <>;Правильно ли я понимаю?

Вверху четвертого вопроса: Затем следует удалить строку метода POST, т.е. ниже строки, и нам не нужно писать новый класс контроллера илиприведенный выше скрипт конфигурации модели и остальное сохраняют как есть: что-то вроде ниже, и бот загружается, когда я открываю страницу, а приглашения OAuth и адаптивные карты работают без проблем:

Avanade D365 F & O Assets BOT

<!--
  For demonstration purposes, we are using development branch of Web Chat at "/master/webchat.js".
  When you are using Web Chat for production, you should use the latest stable at "/latest/webchat.js".
  Or locked down on a specific version "/4.1.0/webchat.js".
-->
<script src="https://cdn.botframework.com/botframework-webchat/latest/webchat.js"></script>
<style>
    html, body {
        height: 100%
    }

    body {
        margin: 0
    }

    #webchat {
        height: 100%;
        width: 100%;
    }
</style>

</div>
<script>
  (async function () {
    // In this demo, we are using Direct Line token from MockBot.
    // To talk to your bot, you should use the token exchanged using your Direct Line secret.
    // You should never put the Direct Line secret in the browser or client app.
    // https://docs.microsoft.com/en-us/azure/bot-service/rest-api/bot-framework-rest-direct-line-3-0-authentication

      const { token } = <<Directline secret from azure portal durect line channel>>;

      const styleOptions = {
       botAvatarImage: 'https://docs.microsoft.com/en-us/azure/bot-service/v4sdk/media/logo_bot.svg?view=azure-bot-service-4.0',
       botAvatarInitials: 'BF',
       userAvatarImage: 'https://avatars1.githubusercontent.com/u/45868722?s=96&v=4',
       userAvatarInitials: 'WC',
       bubbleBackground: 'rgba(0, 0, 255, .1)',
       bubbleFromUserBackground: 'rgba(0, 255, 0, .1)'
  };
    // We are using a customized store to add hooks to connect event
    const store = window.WebChat.createStore({}, ({ dispatch }) => next => action => {
      if (action.type === 'DIRECT_LINE/CONNECT_FULFILLED') {
        // When we receive DIRECT_LINE/CONNECT_FULFILLED action, we will send an event activity using WEB_CHAT/SEND_EVENT
        dispatch({
          type: 'WEB_CHAT/SEND_EVENT',
          payload: {
            name: 'webchat/join',
            value: { language: window.navigator.language }
          }
        });
      }
      return next(action);
    });
    window.WebChat.renderWebChat({
      directLine: window.WebChat.createDirectLine({ token }),
      store
    }, document.getElementById('webchat'));
    document.querySelector('#webchat > *').focus();
  })().catch(err => console.error(err));
</script>

Мое понимание, верно?


30 мая 2019 ChaitanyaNG Обновления для комментария: Снимок экрана: Для ознакомления с результатами использования HTML-файла, предоставленного Richardson как есть, и замены его на мой секретный ключ BOT Direct Channel

1 Ответ

1 голос
/ 27 мая 2019

Реальная проблема в вашем комментарии здесь:

При входе в Webchat мне показывалось следующее: [Файл типа 'application / vnd.microsoft.card.oauth']

что вызвано:

<div id="webchat" role="main">
        <iframe src='https://webchat.botframework.com/embed/TestBotForOauthPrompt?s=<<Given my secretkey of web chat channel>>' style='min-width: 400px; width: 100%; min-height: 500px;'></iframe>
    </div>
    <script>
      (async function () {
        // In this demo, we are using Direct Line token from MockBot.
        // To talk to your bot, you should use the token exchanged using your Direct Line secret.
        // You should never put the Direct Line secret in the browser or client app.
        // https://docs.microsoft.com/en-us/azure/bot-service/rest-api/bot-framework-rest-direct-line-3-0-authentication
        const res = await fetch('https://testbotforoauthprompt.azurewebsites.net//directline//token', { method: 'POST' });
        const { token } = await res.json();

Первая проблема: вы используете оба iframe (<iframe src='https://webchat...) и WebChat (<script> (async function ()...).

Исправлено: удалите iframe и просто используйте код веб-чата . Это нигде не документировано, но iFrame использует botchat, которая является более старой версией WebChat, которая не работает с OAuth и дает ошибку [File of type....

Второй выпуск: вы не получаете действительный токен

const res = await fetch ('https://testbotforoauthprompt.azurewebsites.net//directline//token', {method:' POST '});

Этот код возвращает 404, потому что https://testbotforoauthprompt.azurewebsites.net/directline/token не существует.

Вы должны следовать руководству, связанному в комментариях к коду , в котором вы должны сделать запрос POST на https://directline.botframework.com/v3/directline/tokens/generate с Authorization: Bearer <YourSecretFromAzurePortal> в заголовке.

В качестве альтернативы, вы можете использовать const token = <YourSecretFromAzurePortal> напрямую. Обратите внимание, что не стоит использовать ваш секрет напрямую. Вы действительно должны настроить токен-сервер. Это должно помочь вам начать (примечание: это ссылка, которую я намеревался использовать в моем комментарии выше), но она немного сложнее. Если вы просто хотите что-то простое и не заботитесь о том, чтобы секрет вашего приложения был раскрыт, используйте метод const token = <YourSecretFromAzurePortal>.

Я только что ответил на аналогичный вопрос здесь.


По поводу ваших обновлений

Генератор токенов

Относительно: этот ответ

Если вы хотите сохранить свой секрет в секрете, вам нужно написать свой собственный токен-сервер. Первая половина связанного ответа объясняет основной способ сделать это. Вы можете написать свой собственный, использовать пример в этом связанном ответе или использовать код из постов блога, связанных в этом ответе.

Где разместить код, зависит от того, как вы хотите, чтобы он работал. Пример сервера токенов полностью отделен от бота. примеры постов в блоге показывают, как интегрировать его в ваш бот (хотя вы также можете разместить его отдельно).

Клиент WebChat отправляет запрос на тот сервер токенов, который отправляет запрос на https://directline.botframework.com/v3/directline/tokens/generate и возвращает ответ, который является действительным токеном DirectLine.

Однако во многих случаях не требуется дополнительная безопасность написания собственного токен-сервера. Вторая половина связанного ответа объясняет, что риски безопасности для раскрытия вашего секрета минимальны для многих простых ботов.

Я рекомендую для вас (поскольку вы сказали, что вы довольно плохо знакомы с кодированием), что вы не пишете свой собственный токен-сервер и просто оставляете секрет открытым в const token = <Directline secret from azure portal direct line channel>; (обратите внимание, что я удалил {} , поскольку ваш токен является string). Если вы действительно хотите использовать токен-сервер, вам нужно научиться писать сервер на C #.

HTML-файл

Код, который вы получили от examplebot.azurewebsites..., использует Angular (я думаю). Это старое. Не используйте его.

Вы должны основывать свой HTML-код на одном из примеров веб-чата .

Похоже, ваш последний блок кода делает. Так как было много путаницы, просто используйте это:

<!DOCTYPE html>
<html lang="en-US">
  <head>
    <title>Web Chat: Custom style options</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <!--
      For demonstration purposes, we are using the development branch of Web Chat at "/master/webchat.js".
      When you are using Web Chat for production, you should use the latest stable release at "/latest/webchat.js",
      or lock down on a specific version with the following format: "/4.1.0/webchat.js".
    -->
    <script src="https://cdn.botframework.com/botframework-webchat/master/webchat.js"></script>
    <style>
        html, body {
            height: 100%
        }

        body {
            margin: 0
        }

        #webchat {
            height: 100%;
            width: 100%;
        }
    </style>
  </head>
  <body>
    <div id="webchat" role="main"></div>
    <script>
      (async function () {
        // In this demo, we are using Direct Line token from MockBot.
        // To talk to your bot, you should use the token exchanged using your Direct Line secret.
        // You should never put the Direct Line secret in the browser or client app.
        // https://docs.microsoft.com/en-us/azure/bot-service/rest-api/bot-framework-rest-direct-line-3-0-authentication

        // Token is found by going to Azure Portal > Your Web App Bot > Channels > Web Chat - Edit > Secret Keys - Show
        // It looks something like this: pD*********xI.8ZbgTHof3GL_nM5***********aggt5qLOBrigZ8
        const token = '<Directline secret from azure portal durect line channel>';

        // You can modify the style set by providing a limited set of style options
        const styleOptions = {
            botAvatarImage: 'https://docs.microsoft.com/en-us/azure/bot-service/v4sdk/media/logo_bot.svg?view=azure-bot-service-4.0',
            botAvatarInitials: 'BF',
            userAvatarImage: 'https://avatars1.githubusercontent.com/u/45868722?s=96&v=4',
            userAvatarInitials: 'WC',
            bubbleBackground: 'rgba(0, 0, 255, .1)',
            bubbleFromUserBackground: 'rgba(0, 255, 0, .1)'
        };

        // We are using a customized store to add hooks to connect event
        const store = window.WebChat.createStore({}, ({ dispatch }) => next => action => {
        if (action.type === 'DIRECT_LINE/CONNECT_FULFILLED') {
            // When we receive DIRECT_LINE/CONNECT_FULFILLED action, we will send an event activity using WEB_CHAT/SEND_EVENT
            dispatch({
            type: 'WEB_CHAT/SEND_EVENT',
            payload: {
                name: 'webchat/join',
                value: { language: window.navigator.language }
            }
            });
        }
        return next(action);
        });

        window.WebChat.renderWebChat({
          directLine: window.WebChat.createDirectLine({ token }),
          styleOptions
        }, document.getElementById('webchat'));

        document.querySelector('#webchat > *').focus();
      })().catch(err => console.error(err));
    </script>
  </body>
</html>

Ответы на ваши вопросы

а. Правильный. Метод POST не работает, потому что на используемой вами ссылке не было токен-сервера.

б. Используйте код, который у меня есть выше

с. Да, вы можете стиль, как вы хотите. Приветственные сообщения должны работать из-за кода 'DIRECT_LINE/CONNECT_FULFILLED'. Вы можете добавить дополнительный код из примеров WebChat для выполнения других задач, да.

д. Не используйте код, который передает "бот" в getElementById. Используйте код из примеров веб-чата или код, который я разместил

е. Удалите метод post, если вы не используете токен-сервер.

  1. Это в основном верно. См. Ответы выше.

  2. Да. Удалите метод POST. Ваш код был очень близок !!


Убедитесь, что используемый вами токен поступает отсюда:

enter image description here

...