如何基于使用OAuthCard登录的用户在BotFramework-WebChat中动态设置用户头像 [英] How to set the User avatar dynamically in BotFramework-WebChat based on logged in user using OAuthCard

查看:104
本文介绍了如何基于使用OAuthCard登录的用户在BotFramework-WebChat中动态设置用户头像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用Microsoft Bot Framework V4开发了聊天机器人,并使用BotFramework-WebChat通过DirectLine令牌向用户提供了从网站聊天的功能,

I have developed a chat bot using Microsoft Bot Framework V4, and have used BotFramework-WebChat for providing the user to chat from website using DirectLine Token,

我可以通过分配静态公共图片URL来设置漫游器头像和用户头像.问题是我想使用以下步骤在WebChat中动态设置用户头像

I am able to set the bot avatar and the user avatar by assigning the static public image URL. The problem is that I want to set the user avatar dynamically in the WebChat using below steps

  1. 登录OAuthCard后,使用Microsoft图形API获取用户图标
  2. 动态地在Webchat styleSetOptions中设置已登录的用户图像.

我已经按照提供的示例完成了有关为机器人设置机器人框架服务器和网络聊天的演示

I have gone through the Demo for setting the bot framework server and the webchat for the bot by following the samples provided

机器人服务器== https://github.com/Microsoft/BotBuilder-Samples

webchat == https://github.com/Microsoft/BotFramework-WebChat

webchat == https://github.com/Microsoft/BotFramework-WebChat

但是,在用户使用已签名的用户对象登录后,没有适当的示例或文档来说明如何设置用户图像.

but there is no proper example or documentation on how to set the user image after the user has signed in. using the signed user object.

在正确的方向上,哪一点都可以实现?

can any one point on the right direction on how can it be achieved.

预先感谢

推荐答案

您可以通过将Graph API调用和结果包装到AAD登录过程的结果中来实现.以下代码基于BotBuilder-Samples 24.bot-authentication-msgraph 示例和BotFramework-WebChat 17.chat-send-history 示例使用React.Component.

You can achieve this by wrapping the Graph API call and result into the result of the AAD login process. The following code is based off of the BotBuilder-Samples 24.bot-authentication-msgraph sample and BotFramework-WebChat 17.chat-send-history sample using React.Component.

(请注意,当前位于master分支中的Graph示例不包括获取AAD登录用户的照片.我有一个PR将该功能添加到了示例中,但是我也在此处包括了它.使用WebChat示例作为构建以下内容的参考.)

(Please be aware that the Graph sample currently located in the master branch does not include obtaining the AAD login user's photo. I have a PR which adds this feature into the sample, however I have included it here, as well. I used the WebChat sample as a reference for building the below.)

您将需要样本17中的这些文件,然后是需要更改的App.js文件:

You will need these files from sample #17, followed by the App.js file that needs altering:

  • 公开 [文件夹]
    • favicon.ico
    • index.html
    • manifest.json
    • public [folder]
      • favicon.ico
      • index.html
      • manifest.json
      • App.js
      • index.css
      • index.js

      注意:我在一个单独的项目中本地生成了直接令牌.假设AAD个人资料中有照片.

      Note: I generate the direct line token locally in a separate project. This assumes an AAD profile has a photo.

      import React from 'react';
      
      import ReactWebChat, { createDirectLine, createStore} from 'botframework-webchat';
      
      export default class extends React.Component {
        constructor(props) {
          super(props);
      
          this.state = {
            directLine: null,
            avatarState: false, // Sets value to false; Is updated to true after login
            // Sets the default styleOptions used during rendering
            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://github.com/compulim.png?size=64',
                userAvatarInitials: 'WC'
              }
          };
      
          // Creates the listener filtering for a new avatar image and applies to styleOptions
          this.store = createStore(
            {},
            () => next => action => {
              if (action.type === 'DIRECT_LINE/INCOMING_ACTIVITY') {
                }
              if (action.type === 'DIRECT_LINE/INCOMING_ACTIVITY' 
                && action.payload.activity.attachments 
                && 0 in action.payload.activity.attachments
                && this.state.avatarState === false) {
                  let attachments = action.payload.activity.attachments;
                  if ('content' in attachments[0] && 'images' in attachments[0].content) {
                    this.setState(() => ({
                        styleOptions: {
                          userAvatarImage: attachments[0].content.images[0].contentUrl
                        },
                        avatarState: true
                    }));
                  }
              }
      
              return next(action);
            }
          )
        }
      
        componentDidMount() {
          this.fetchToken();
        }
      
        async fetchToken() {
          const res = await fetch('http://localhost:3979/directline/token', { method: 'POST' });
          const { token } = await res.json();
      
          this.setState(() => ({
            directLine: createDirectLine({ token })
          }));
        }
      
        render() {
          return (
            this.state.directLine ?
              <ReactWebChat
                className="chat"
                directLine={ this.state.directLine }
                styleOptions={ this.state.styleOptions }
                store={ this.store }
                { ...this.props }
              />
            :
              <div>Connecting to bot&hellip;</div>
          );
        }
      }
      

      package.json

      {
        "name": "change-avatar",
        "version": "0.1.0",
        "private": true,
        "homepage": "",
        "dependencies": {
          "botframework-webchat": ">= 0.0.0-0",
          "react": "^16.6.3",
          "react-dom": "^16.6.3",
          "react-scripts": "2.1.1"
        },
        "scripts": {
          "start": "react-scripts start",
          "build": "react-scripts build",
          "eject": "react-scripts eject"
        },
        "browserslist": [
          ">0.2%",
          "not dead",
          "not ie <= 11",
          "not op_mini all"
        ]
      }
      

      MS Graph Bot

      更新示例#24中的以下文件:

      MS Graph Bot

      Update the following files in sample #24:

      async processStep替换为:

      async processStep(step) {
          // We do not need to store the token in the bot. When we need the token we can
          // send another prompt. If the token is valid the user will not need to log back in.
          // The token will be available in the Result property of the task.
          const tokenResponse = step.result;
      
          // If the user is authenticated the bot can use the token to make API calls.
          if (tokenResponse !== undefined) {
              let parts = await this.commandState.get(step.context);
              if (!parts) {
                  parts = step.context.activity.text;
              }
              const command = parts.split(' ')[0].toLowerCase();
              if (command === 'me') {
                  await OAuthHelpers.listMe(step.context, tokenResponse);
              } else if (command === 'send') {
                  await OAuthHelpers.sendMail(step.context, tokenResponse, parts.split(' ')[1].toLowerCase());
              } else if (command === 'recent') {
                  await OAuthHelpers.listRecentMail(step.context, tokenResponse);
              } else {
                  let photoResponse = await OAuthHelpers.loginData(step.context, tokenResponse);
                  const card = CardFactory.heroCard(
                      `Welcome ${ photoResponse.displayName }, you are now logged in.`,
                      [photoResponse],
                      []
                  );
                  const reply = ({ type: ActivityTypes.Message });
                  reply.attachments = [card];
                  await step.context.sendActivity(reply);
              }
          } else {
              // Ask the user to try logging in later as they are not logged in.
              await step.context.sendActivity(`We couldn't log you in. Please try again later.`);
          }
          return await step.endDialog();
      };
      

      oauth-helpers.js:

      添加static async loginData:

      /**
       * Displays information about the user in the bot.
       * @param {TurnContext} turnContext A TurnContext instance containing all the data needed for processing this conversation turn.
       * @param {TokenResponse} tokenResponse A response that includes a user token.
       */
      static async loginData(turnContext, tokenResponse) {
          if (!turnContext) {
              throw new Error('OAuthHelpers.loginData(): `turnContext` cannot be undefined.');
          }
          if (!tokenResponse) {
              throw new Error('OAuthHelpers.loginData(): `tokenResponse` cannot be undefined.');
          }
      
          try {
              // Pull in the data from Microsoft Graph.
              const client = new SimpleGraphClient(tokenResponse.token);
              const me = await client.getMe();
              const photoResponse = await client.getPhoto();
      
              // Attaches user's profile photo to the reply activity.
              if (photoResponse != null) {
                  let replyAttachment;
                  const base64 = Buffer.from(photoResponse, 'binary').toString('base64');
                  replyAttachment = {
                      contentType: 'image/jpeg',
                      contentUrl: `data:image/jpeg;base64,${ base64 }`
                  };
                  replyAttachment.displayName = me.displayName;
                  return (replyAttachment);
              }
          } catch (error) {
              throw error;
          }
      }
      

      simple-graph-client.js:

      添加async getPhoto:

      /**
       * Collects the user's photo.
       */
      async getPhoto() {
          return await this.graphClient
              .api('/me/photo/$value')
              .responseType('ArrayBuffer')
              .version('beta')
              .get()
              .then((res) => {
                  return res;
              })
              .catch((err) => {
                  console.log(err);
              });
      }
      

      package.json:

      请确保@microsoft/microsoft-graph-client由于在后续版本中获取AAD'displayName'所引起的重大更改而安装了1.0.0版本.

      package.json:

      Be sure the @microsoft/microsoft-graph-client installs version 1.0.0 due to breaking changes around AAD 'displayName' acquisition in subsequent versions.

      实施上述代码后,我便能够登录,成功登录后,便会立即更新用户头像.

      Once the above code was implemented, I was able to login which, upon success, immediately updated the user avatar.

      希望有帮助!

      这篇关于如何基于使用OAuthCard登录的用户在BotFramework-WebChat中动态设置用户头像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆