Search code examples
reactjsbotframeworkdirect-line-botframework

Proper way to use botframework-webchat in React component (using create-react-app)?


I've created an app using create-react-app, then used the official github instructions for integrating with React (v16.6.3):

import DirectLine from 'botframework-directlinejs';
import React from 'react';
import ReactWebChat from 'botframework-webchat';

export default class extends React.Component {
  constructor(props) {
    super(props);

    this.directLine = new DirectLine({ token: 'YOUR_BOT_SECRET' });
  }

  render() {
    return (
      <ReactWebChat directLine={ this.directLine } />
      element
    );
  }
}

However, I'm getting this error:

TypeError: botframework_directlinejs__WEBPACK_IMPORTED_MODULE_5___default.a is not a constructor

What am I missing here? Thanks!


Solution

  • Note, there is (at time of writing this) an error in the instructions in the official repo:

    import DirectLine from 'botframework-directlinejs';
    

    should be:

    import { DirectLine } from 'botframework-directlinejs';
    

    Change this, and botframework-webchat v4 works with React 16, with the instructions on the github page.

    If you want to use v3 of botframework-webchat, the following code worked for me:

    After some experimenting and digging in other repos, here's how I was able to do this using a clean create-react-app instance:

    in /src/App.js:

    import React, { Component } from 'react';
    
    import * as WebChat from 'botframework-webchat';
    
    class App extends Component {
      constructor(props) {
        super(props);
    
        this.state = { token: null };
      }
    
        async componentDidMount() {
        const myHeaders = new Headers()
        var myToken = process.env.REACT_APP_DIRECTLINE_SECRET
        myHeaders.append('Authorization', 'Bearer ' + myToken)
        const res = await fetch(
            'https://directline.botframework.com/v3/directline/tokens/generate',
            {
                method: 'POST',
                headers: myHeaders
            }
        )
    
        const { token } = await res.json()
        this.setState(() => ({ token }))
    }
    
      render() {
        const {
          state: { token }
        } = this;
    
        return (
          !!token &&
            <WebChat.Chat
              directLine={{
                token,
                webSocket: false
              }}
              style={{
                height: '100%',
                width: '100%'
              }}
              user={{
                id: 'default-user',
                name: 'Some User'
              }}
            />
        );
      }
    }
    
    export default App;
    

    Add this line before the title tag in /public/index.html:

    <link
          rel="stylesheet"
          href="https://cdn.botframework.com/botframework-webchat/0.14.2/botchat.css"
        />
    

    package.json -- note I'm using the 0.14.2 version of botframework-webchat, I can't get it to work on the master release (4.1.1 as of right now):

    {
      "name": "react-test",
      "version": "0.1.0",
      "private": true,
      "dependencies": {
        "botframework-webchat": "^0.14.2",
        "react": "^16.6.3",
        "react-dom": "^16.6.3",
        "react-scripts": "^2.1.1"
      },
      "scripts": {
        "start": "react-scripts start",
        "build": "react-scripts build",
        "test": "react-scripts test",
        "eject": "react-scripts eject"
      },
      "eslintConfig": {
        "extends": "react-app"
      },
      "browserslist": [
        ">0.2%",
        "not dead",
        "not ie <= 11",
        "not op_mini all"
      ]
    }
    

    And don't forget to set your secret in .env!