Отображение приветственного сообщения в v4 Bot Framework Bot (C # + .Net Core Web Application) - PullRequest
0 голосов
/ 03 июля 2019

Я создал бота с v3 (C #) SDK и приветственным сообщением, которое обычно работало без каких-либо проблем. И это все еще для меня в производстве. Код обрабатывается в HandleSystemMessage следующим образом -

.. v3 Код, дополнительный код удален для ясности ...

else if (message.Type == ActivityTypes.ConversationUpdate)
{
// Handle conversation state changes, like members being added and removed
// Use Activity.MembersAdded and Activity.MembersRemoved and Activity.Action for info
// Not available in all channels

//Code to show Welcome Message
if (message.MembersAdded.Any(o => o.Id == message.Recipient.Id))
{
var reply = message.CreateReply();
reply.Attachments = new List<Attachment>();
// Create the attachment.
Attachment attachment = new Attachment()
{
ContentType = AdaptiveCard.ContentType,
Content = AdaptiveCardHelper.GetOptionsCard()
};
reply.Attachments.Add(attachment);
ConnectorClient connector = new ConnectorClient(new Uri(message.ServiceUrl));
await connector.Conversations.ReplyToActivityAsync(reply);
}
}

Версия веб-чата, которую я использую - BotFramework-WebChat-0.11.4, в ней были сделаны некоторые настройки для реализации функции «Мне нравится / не нравится» в Facebook с комментариями.

Теперь я перевожу ботов в v4 SDK (C # + .Net Core Web App) и собираюсь использовать ту же старую версию веб-чата. Но я изо всех сил в течение двух дней пытаюсь получить приветственное сообщение, отображаемое в том же веб-чате, пока оно хорошо работает на событиях эмулятора (переданных этим двум ConversationUpdate).

Я попытался отправить сообщение, а также событие, используя решение, представленное в этой статье, и попытался перехватить его в боте с помощью различных асинхронных методов OnEventAsync, OnEventActivityAsync, OnMessageActivityAsync.

https://blog.botframework.com/2018/07/12/how-to-properly-send-a-greeting-message-and-common-issues-from-customers/

Код V4 выглядит следующим образом:

 protected override async Task OnConversationUpdateActivityAsync(ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
        {
            if (turnContext.Activity.MembersAdded != null)
            {
                if (turnContext.Activity.MembersAdded.Any(m => m.Id != turnContext.Activity.Recipient?.Id))
                {
                    //var welcomeCard = CreateAdaptiveCardAttachment();
                    //var response = CreateResponse(turnContext.Activity, welcomeCard);
                    //await turnContext.SendActivityAsync(response, cancellationToken);

                    await Utility.LogTraceAsync("Inside OnConversationUpdateActivityAsync");

                        var eventActivity = turnContext.Activity.AsConversationUpdateActivity();

                        ConnectorClient connector = new ConnectorClient(new Uri(eventActivity.ServiceUrl), Configuration.MicrosoftAppId, Configuration.MicrosoftAppPassword);

                        await Utility.LogTraceAsync("Service URL OnConversationUpdateActivityAsync" + eventActivity.ServiceUrl);

                        await Utility.LogTraceAsync("Recipient ID OnConversationUpdateActivityAsync" + turnContext.Activity.Recipient?.Id);

                        var welcomeCard = CreateAdaptiveCardAttachment();

                        var reply = ((Activity)eventActivity).CreateReply();
                        reply.Attachments.Add(welcomeCard);

                    //var response = CreateResponse(turnContext.Activity, welcomeCard);
                    await connector.Conversations.ReplyToActivityAsync(reply, cancellationToken);// turnContext.SendActivityAsync(response, cancellationToken);

                        await Utility.LogTraceAsync("OnConversationUpdateActivityAsync Response Returned.");

                    await Utility.LogTraceAsync("Exit OnConversationUpdateActivityAsync");
                }
            }
        }

        protected override async Task OnEventActivityAsync(ITurnContext<IEventActivity> turnContext, CancellationToken cancellationToken)
        {
            await Utility.LogTraceAsync("Inside OnEventActivityAsync");
            if (turnContext.Activity.Type == ActivityTypes.Event)
            {
                var eventActivity = turnContext.Activity.AsEventActivity();

                await Utility.LogTraceAsync("Event Activity from WebChat matched.");

                ConnectorClient connector = new ConnectorClient(new Uri(eventActivity.ServiceUrl), Configuration.MicrosoftAppId, Configuration.MicrosoftAppPassword);

                await Utility.LogTraceAsync("Service URL " + eventActivity.ServiceUrl);

                var welcomeCard = CreateAdaptiveCardAttachment();

                var reply = ((Activity)eventActivity).CreateReply();
                reply.Attachments.Add(welcomeCard);

                var members = await connector.Conversations.GetConversationMembersAsync(eventActivity.Conversation.Id.ToString());
                var membernames = "";
                foreach (var member in members) {
                    membernames += member.Name + ",";
                }

                await Utility.LogTraceAsync(membernames);

                await connector.Conversations.SendToConversationAsync(reply, cancellationToken);

                await connector.Conversations.ReplyToActivityAsync(reply, cancellationToken);// turnContext.SendActivityAsync(response, cancellationToken);

                await Utility.LogTraceAsync("Event Response Returned.");
            }

            await Utility.LogTraceAsync("Exit OnEventActivityAsync");
        }

Но, похоже, это не работает вообще. Я вытаскиваю свои волосы, и нет понятия, как это сделать для .Net Core App. Я буду рад узнать, если кто-то решил эту проблему.

Обновление - я использовал JS-код на стороне клиента, предоставленный @tdurnford, а на Bot Side было два следующих метода -

//Required to Show Welcome Message on Emulator
protected override async Task OnMembersAddedAsync(IList<ChannelAccount> membersAdded, ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
        {
            foreach (var member in membersAdded ?? Array.Empty<ChannelAccount>())
            {
                // Greet anyone that was not the target (recipient) of this message.
                // To learn more about Adaptive Cards, see https://aka.ms/msbot-adaptivecards for more details.
                if (member.Id != turnContext.Activity.Recipient.Id)
                {
                    Activity reply = ((Activity)turnContext.Activity).CreateReply();
                    AdaptiveCard card = AdaptiveCardHelper.GetWelcomeCard();
                    Attachment attachment = new Attachment()
                    {
                        ContentType = AdaptiveCard.ContentType,
                        Content = card
                    };
                    reply.Attachments.Add(attachment);
                    await turnContext.SendActivityAsync(reply, cancellationToken);
                }
            }
        }

//Required to Show Welcome Message on Web Chat
        protected override async Task OnEventActivityAsync(ITurnContext<IEventActivity> turnContext, CancellationToken cancellationToken)
        {
            if (turnContext.Activity.Name == "webchat/join")
            {
                Activity reply = ((Activity)turnContext.Activity).CreateReply();
                AdaptiveCard card = AdaptiveCardHelper.GetWelcomeCard();
                Attachment attachment = new Attachment()
                {
                    ContentType = AdaptiveCard.ContentType,
                    Content = card
                };
                reply.Attachments.Add(attachment);
                await turnContext.SendActivityAsync(reply, cancellationToken);
            }
        }

При обоих методах в окне чата отображаются два приветственных сообщения -

Окно бота с двумя приветственными сообщениями

Затем я прокомментировал метод OnEventActivityAsync в C # и снова развернул. Теперь он показывает только одно приветственное сообщение, возвращенное из OnMembersAddedAsync, как показано в окне.

Окно бота только с одним приветственным сообщением

Если я прокомментирую следующие строки кода в коде чата, то есть не отправлять пост-активность -

botConnection.postActivity({
    from: {
        id: 'myUserId',
        name: 'myUserName'
    },
    type: 'event',
    name: 'webchat/join',
    value: {
        locale: 'en-US'
    }
}).subscribe(
    id => console.log("Posted welcome event, assigned ID ", id),
    error => console.log("Error posting activity", error)
);

В этом случае приветственное сообщение не отображается. @tdurnford, пожалуйста, проверьте, можете ли вы повторить это поведение.

Несмотря на то, что здесь есть еще одна проблема, когда пользователь вводит вопрос в бот, снова появляется приветственное сообщение. Окно бота с двумя приветственными сообщениями, одно при загрузке, а другое после первого вопроса

Ответы [ 2 ]

0 голосов
/ 08 июля 2019

Обычно канал отправляет два события обновления диалога при инициализации диалога - одно для бота, а другое для пользователя.Второе - событие для пользователя - предназначено для запуска приветственного сообщения.В отличие от некоторых других каналов, веб-чат ожидает отправки второго события обновления разговора до тех пор, пока пользователь не сообщит боту.Очевидно, приветственное сообщение не будет отправлено до первого сообщения.Чтобы обойти эту проблему, разработчики могут отправить бот приветствию обратного канала при установлении соединения DirectLine и отправить приветственное сообщение из обработчика onEventAsync вместо onMembersAdded.Для более подробной информации, посмотрите на фрагменты кода ниже.

Код чата бота

<!DOCTYPE html>
<html>
  <head>
    <link href="https://cdn.botframework.com/botframework-webchat/0.11.4/botchat.css" rel="stylesheet" />
    <style>
      #webchat {
        height: 100%;
        width: 100%;
      }
    </style>

  </head>
  <body>
    <div style="display: flex">
      <div style="position: relative; height: 500px; width: 500px"><div id="bot" ></div></div>
    </div>


    <script src="https://cdn.botframework.com/botframework-webchat/0.11.4/botchat.js"></script>

    <script>

      (async function() {

        const res = await fetch('/directline/token', { method: 'POST' });
        const { token }  = await res.json();

        var userinfo = {
              id: 'user-id',
              name: 'user name',
              locale: 'es'
          };

        var botConnection = new window.BotChat.DirectLine({ token });

        botConnection.connectionStatus$
          .subscribe(connectionStatus => {
              switch(connectionStatus) {
                  case window.BotChat.ConnectionStatus.Online:
                    botConnection.postActivity({
                        from: { id: 'myUserId', name: 'myUserName' },
                        type: 'event',
                        name: 'webchat/join',
                        value: { locale: 'en-US' }
                    }).subscribe(
                        id => console.log("Posted welcome event, assigned ID ", id),
                        error => console.log("Error posting activity", error)
                    );
                    break;
              }
          });


        BotChat.App({
          botConnection: botConnection,
          user: userinfo,
          bot: { id: 'botid' },
          resize: 'detect'
        }, document.getElementById("bot"));

      })().catch(err => console.log(err));

    </script>
  </body>
</html>

Код бота - C #

protected override async Task OnEventActivityAsync(ITurnContext<IEventActivity> turnContext, CancellationToken cancellationToken)
{
    if (turnContext.Activity.Name == "webchat/join") {
      await turnContext.SendActivityAsync("Welcome Message!");
    }
}

protected override async Task OnMembersAddedAsync(IList<ChannelAccount> membersAdded, ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
{
    if (turnContext.Activity.ChannelId != "webchat" && turnContext.Activity.ChannelId != "directline") {

        foreach (var member in membersAdded)
        {
            if (member.Id != turnContext.Activity.Recipient.Id)
            {
                await turnContext.SendActivityAsync($"Hi there - {member.Name}. {WelcomeMessage}", cancellationToken: cancellationToken);
                await turnContext.SendActivityAsync(InfoMessage, cancellationToken: cancellationToken);
                await turnContext.SendActivityAsync(PatternMessage, cancellationToken: cancellationToken);
            }
        }
    }
}

Снимок экрана

enter image description here

Также обратите внимание, что веб-чат v0.11.4 называется либо бот-чат, либо веб-чат v3.Извините, что меня это задело.

Надеюсь, это поможет!

0 голосов
/ 03 июля 2019

В v4 пакета Bot Framework SDK эта функция реализуется путем наследования вашего класса ботов от класса ActivityHandler с последующим переопределением метода OnMembersAddedAsync .

Как это выглядит на практике:

...

public class MyBot : ActivityHandler
{
    ...

        protected override async Task OnMembersAddedAsync(IList<ChannelAccount> membersAdded, ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
        {
            foreach (var member in membersAdded)
            {
                // Greet anyone that was not the target (recipient) of this message.
                if (member.Id != turnContext.Activity.Recipient.Id)
                {
                    var welcomeMessage = "Hello and welcome!";

                    await turnContext.SendActivityAsync(welcomeMessage, cancellationToken);
                }
            }
        }
    ...
}

Есть примеры того, как это сделать здесь , здесь и здесь .

Возможно, вам придется обновить версию пакета Microsoft.Bot.Builder, который вы используете.

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