BotFramework-WebChat v4: публикация активности на прямой линии от интерфейса пользователя до бота - PullRequest
1 голос
/ 05 февраля 2020

Мой код веб-чата основан на React minimizable-web-chat v4.

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

handleLocationButtonClick вызывается функция, которая отправляет боту широту и долготу.

Это мой код:

import React from 'react';
import { createStore, createStyleSet } from 'botframework-webchat';

import WebChat from './WebChat';
import './fabric-icons-inline.css';
import './MinimizableWebChat.css';

export default class extends React.Component{

constructor(props) {
    super(props);

    this.handleFetchToken = this.handleFetchToken.bind(this);
    this.handleMaximizeButtonClick = this.handleMaximizeButtonClick.bind(this);
    this.handleMinimizeButtonClick = this.handleMinimizeButtonClick.bind(this);
    this.handleSwitchButtonClick = this.handleSwitchButtonClick.bind(this);
    this.handleLocationButtonClick = this.handleLocationButtonClick.bind(this);

    const store = createStore({}, ({ dispatch }) => next => action => {
      if (action.type === 'DIRECT_LINE/CONNECT_FULFILLED') {
        dispatch({
          type: 'WEB_CHAT/SEND_EVENT',
          payload: {
            name: 'webchat/join',
          }
        });
      }
      else if(action.type === 'DIRECT_LINE/INCOMING_ACTIVITY'){
        if (action.payload.activity.name === 'locationRequest') {
          this.setState(() => ({
            locationRequested: true
          }));
        }
      }
      return next(action);
    });

    this.state = {
      minimized: true,
      newMessage: false,
      locationRequested:false,
      side: 'right',
      store,
      styleSet: createStyleSet({
        backgroundColor: 'Transparent'
      }),
      token: 'token'
    };
  }

  async handleFetchToken() {
    if (!this.state.token) {
      const res = await fetch('https://webchat-mockbot.azurewebsites.net/directline/token', { method: 'POST' });
      const { token } = await res.json();

      this.setState(() => ({ token }));
    }
  }

  handleMaximizeButtonClick() {
    this.setState(() => ({
      minimized: false,
      newMessage: false
    }));
  }

  handleMinimizeButtonClick() {
    this.setState(() => ({
      minimized: true,
      newMessage: false
    }));
  }

  handleSwitchButtonClick() {
    this.setState(({ side }) => ({
      side: side === 'left' ? 'right' : 'left'
    }));
  }

  handleLocationButtonClick(){
    var x = document.getElementById("display");
    if (navigator.geolocation) {
      navigator.geolocation.getCurrentPosition(showPosition);

      this.setState(() => ({
        locationRequested: false
      }));

    }
    else 
    {
      x.innerHTML = "Geolocation API is not supported by this browser.";
    }

    function showPosition(position) {
        x.innerHTML = "Latitude: " + position.coords.latitude + "<br>Longitude: " + position.coords.longitude;

        this.store.dispatch({
          type: 'WEB_CHAT/SEND_MESSAGE',
          payload: { text: 'latitude:'+position.coords.latitude+'longitude:'+position.coords.longitude }
        });
    }
  }

render() {
    const { state: {
      minimized,
      newMessage,
      locationRequested,
      side,
      store,
      styleSet,
      token
    } } = this;

    return (
      <div className="minimizable-web-chat">
        {
          minimized ?
            <button
              className="maximize"
              onClick={ this.handleMaximizeButtonClick }
            >
              <span className={ token ? 'ms-Icon ms-Icon--MessageFill' : 'ms-Icon ms-Icon--Message' } />
              {
                newMessage &&
                  <span className="ms-Icon ms-Icon--CircleShapeSolid red-dot" />
              }
            </button>
          :
            <div
              className={ side === 'left' ? 'chat-box left' : 'chat-box right' }
            >
              <header>
                <div className="filler" />
                <button
                  className="switch"
                  onClick={ this.handleSwitchButtonClick }
                >
                  <span className="ms-Icon ms-Icon--Switch" />
                </button>
                <button
                  className="minimize"
                  onClick={ this.handleMinimizeButtonClick }
                >
                  <span className="ms-Icon ms-Icon--ChromeMinimize" />
                </button>
              </header>
              <WebChat
                className="react-web-chat"
                onFetchToken={ this.handleFetchToken }
                store={ store }
                styleSet={ styleSet }
                token={ token }
              />
              {
                locationRequested ?
                <div>
                  <p id="display"></p>
                  <button onClick={this.handleLocationButtonClick}>
                    Gélolocation
                  </button>
                </div>
              :
              <div></div>
              }
            </div>
        }
      </div>
    );
  }
}

Когда я нажимаю кнопку, у меня появляется эта ошибка:

enter image description here

и в консоли:

![enter image description here

Что не так ??

1 Ответ

0 голосов
/ 05 февраля 2020

Во-первых, были некоторые обновления образца a.minimizable-web-chat , которые стоит посмотреть. Однако обратитесь к коду, поскольку файл README.md не был полностью обновлен для отражения изменений.

Что касается вашего вопроса, попробуйте следующие изменения. При тестировании он успешно работает для меня. Измените компонент на функцию и определите store через useMem0().

import React, { useCallback, useMemo, useState } from 'react';

const MinimizableWebChat = () => {
  const store = useMemo(
    () =>
      createStore({}, ({ dispatch }) => next => action => {
        if (action.type === 'DIRECT_LINE/CONNECT_FULFILLED') {
          dispatch({
            type: 'WEB_CHAT/SEND_EVENT',
            payload: {
              name: 'webchat/join',
              value: {
                language: window.navigator.language
              }
            }
          });
        } else if (action.type === 'DIRECT_LINE/INCOMING_ACTIVITY') {
          if (action.payload.activity.from.role === 'bot') {
            setNewMessage(true);
          }
        }

        return next(action);
      }),
    []
  );

  [...]

  return (
    [...]
    <WebChat
      [...]
      store={store}
  );
}

export default MinimizableWebChat;

Учитывая изменения, внесенные в этот файл, вероятно повлияет на работу других файлов с ним , Я рекомендую сделать оптовое обновление, чтобы привести ваш проект в соответствие с текущим образцом. Это действительно просто файл, WebChat.js и, возможно, App.js. Есть поддерживаемые файлы CSS и тому подобное, которые можно загрузить, если у вас их нет.

Надежда на помощь!

...