Hessel
Hessel

Reputation: 762

Unable to succesfully pass Javascript variable in createDirectLine (botframework webchat) resulting in 403 error

Every webchat session, I retrieve a token from a restify service which is talking to https://webchat.botframework.com/api/tokens. I use a directline secret to get the token. The token is retrieved correctly. When I use the token manually (by entering it in the html), webchat renders. When I pass a Javascript variable in the function I am unable to create the directline. Some guidance appreciated. A workaround would be to use secret in html but I rather not do that

I tried multiple syntaxes to pass the variable in: window.WebChat.createDirectLine({ webChatToken }) or (webChatToken) or ({ webChatToken }) or (token: webChatToken) and ({ token: webChatToken })

The only thing that worked was entering the token manually in the html.

I use the restify server already in my index.js (for a sample bot) to listen for and process token requests:

// Create HTTP server and Cors
let server = restify.createServer();
server.pre(cors.preflight);
server.use(cors.actual);
server.listen(process.env.port || process.env.PORT || 3978, function() {
});

// Listen for bot requests.
server.post('/api/messages', (req, res) => {
    adapter.processActivity(req, res, async (context) => {
        await bot.run(context);
    });
});

// Listen for token requests.
server.get('/api/token',
    async function(req, res) {
        const result = await fetch('https://webchat.botframework.com/api/tokens', {
            method: 'GET',
            headers: {
                Authorization: `Bearer ${ process.env.directLineSecret }`
            }
        });
        const token = await result.json();
        console.log(token);
        res.send(token);
    });

And the webchat client in html and Javascript code. In this example it is talking to a local instance of the restify server.

    <div id="webchat" role="main"></div>   
        <script>
            //get token
            const webChatToken = getToken();

            window.WebChat.renderWebChat({
            directLine: window.WebChat.createDirectLine({ webChatToken }),
            renderMarkdown: markdownIt.render.bind(markdownIt),
            store,
            // styling
            styleOptions: {
            },
            userID: 'N/A',
            username: 'Web Chat User',
            locale: 'nl-nl'
          }, document.getElementById('webchat'));

            async function getToken() {
            const res = await fetch('http://localhost:3978/api/token');
            const token = await res.json();
            return token;
          }
        </script>

I expect a working webchat client. In chrome dev extention I see "POST https://directline.botframework.com/v3/directline/conversations 403 (Forbidden). The corresponding response of the directline api:

{ "error": { "code": "BadArgument", "message": "Invalid token or secret" } }

Upvotes: 1

Views: 492

Answers (1)

tdurnford
tdurnford

Reputation: 3712

The Direct Line options has a token property, not a webChatToken property. You need to set the token value to webChatToken in the options object. Take a look at the code snippet below and the Direct Line Documentetion for more details on initializing Web Chat and the Direct Line client.

(async function () {
  const res = await fetch('http://localhost:3978/api/token', { method: 'GET' });
  const webChatToken = await res.json();

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

  document.querySelector('#webchat > *').focus();
})().catch(err => console.error(err));

Hope this helps!

Upvotes: 2

Related Questions