BotFramework DirectLine Token Server
The Bot Framework DirectLine Token Server extension is designed with the Bot Framework developer in mind. It's purpose is to easily allow a developer to "spin up" a token server for use with their BotFramework-DirectLineJS based clients, such as Web Chat or any other custom-built solutions.
By updating the (localhost) port and including the Bot Framework DirectLine channel secret, a token server can be started with a click of a button. Thus, saving the developer time that can be better used in actual development.
This is accomplished by use of the DirectLine API, part of Microsoft's Bot Framework ecosystem, which provides a set of endpoints useful in communicating with a Bot Framework SDK/Composer or Power Virtual Agent bot. The DirectLine APIs serve as the bridge between the user's client and the DirectLine service connector. User input is sent to the DirectLine service, in the form of an outgoing activity, which is then forwarded to the bot (user => bot). The DirectLine service also receives incoming activities from the bot which are then forwarded to the client and displayed to the user (bot => user).
Why is a token server necessary when the DirectLine channel secret can be used directly within the client?
There are a number of reasons, but the primary reason is security. Most clients that use DirectLine are HTML-based which typically means any of the code is accessible to anyone willing to look. Storing the secret in a script loaded in a browser is a high security risk.
By using a token server, the secret is stored on a separate server. A call to the token server will, subsequently, call the DirectLine service exchanging the secret for a token. This token is returned back to the client finalizing the connection.
The Bot Framework DirectLine Token Server extension removes all of that complexity allowing for a quick and easy implementation.
Features
- Enter the bot's DirectLine channel secret (required)
- Clear the secret from settings
- Enter a valid port for use by the local server
- If the port is not specified by the developer, it will default to port 3000
- Start and stop the local server
- Bypass running the server and immediately obtain a DirectLine response (i.e., token, conversation Id, and streamUrl)
- Copy the generated token, conversation Id, and/or streamUrl to the clipboard
Requirements
- A Microsoft Azure bot registration
- The DirectLine channel enabled within the bot registration
- The DirectLine channel secret
- An available port on your system
Additional Requirements
Usage
Now that you have a running server, it's time to put it to work.
To get set up, use the extension's settings to set the DirectLine secret and, if desired, the port the server will run on. Then, run the server.
Request a token
This extension offers two methods for requesting a token from DirectLine: run the server or get what I'm referring to as a "static" response.
- To programmatically get a token for use in your DirectLine-based client, make a POST request like below against the running server.
fetch()
is used here, but you can use whichever library or tool you like.
const res = await fetch( 'http://localhost:3000/directline/conversations', { method: 'POST' } );
let { token } = await res.json();
[...]
window.WebChat.renderWebChat(
{
directLine: await window.WebChat.createDirectLine({ token })
},
document.getElementById( 'webchat' )
);
Here is a POST request, using port 3500, made using Postman that returns the full DirectLine response.
Please note: Two assumptions are being made about the above code:
- Default port
3000
is being used, and
- BotFramework-WebChat is the preferred client
However, one, both, or neither may be used as both are optional. It is entirely up to you!
In most cases, the token (or conversation Id and streamUrl) aren't needed. But, if you need to access the values, you can do so via the extension by copying each property, or the whole response, to your system's clipboard.
- Alternatively, if you want to manage the DirectLine token yourself and not rely on a continuously running server, you can generate a "static", non-programmatic DirectLine response. Once generated, you can copy the value(s) using the same method described above or copy them directly from the generated view. You can even refresh the token in a similar fashion.
Please note: This option still runs the server, but only with enough time to make the POST request and get the response. The server is then shut down. A valid port is still a necessity, in this scenario. The design of this function will likely change in the future so as to not be server dependent.
Extension Settings
This extension contributes the following settings:
botframework-directline-api-server.clearApiResponse
: Clears the direct Api response values
botframework-directline-api-server.clearServerResponse
: Clears the server-generated response values
botframework-directline-api-server.clearDirectLineSecret
: Clears the DirectLine channel secret from settings
botframework-directline-api-server.directlineWebView
: Generates a view that displays the requested DirectLine response (token, conversationId, and streamUrl)
botframework-directline-api-server.getApiResponse
: Opens the command palette options for copying the direct Api response values
botframework-directline-api-server.getServerResponse
: Opens the command palette options for copying the server-generated response values
botframework-directline-api-server.helpView
: Generates a view that displays troubleshooting options and FAQ
botframework-directline-api-server.openDirectLineResponseMenu
: Opens the DirectLine Response Menu in the command palette
botframework-directline-api-server.openSettingsMenu
: Opens the DirectLine Settings Menu in the command palette
botframework-directline-api-server.openStartServerMenu
: Opens the Start Server Menu in the command palette
botframework-directline-api-server.setDirectLineSecret
: Stores the DirectLine channel secret in settings for use in underlying API calls
botframework-directline-api-server.setDirectLinePort
: Stores the preferred port in settings for use when starting the local server
botframework-directline-api-server.setUserId
: Stores the preferred user Id in settings for use in generating the DirectLine token
botframework-directline-api-server.startServer
: Starts the local server at http://localhost:[PORT]
botframework-directline-api-server.stopServer
: Stops the local server
Known Issues
None, at this time.
Release Notes
[1.2.1]
Added
- Added the icon property to the package.json
Fixed
- Corrected issue where the user-specified port was not being accurately reported by the status bar tool tip.
- Corrected issue where clicking the status bar button was not using the user-specified port when opening the status page.
Reference the CHANGELOG.md file to view all past changes.
To-Do
- [ ] Option to export the token server as code for use in production
- [ ] Ability to call different DirectLine APIs
- [X] Refresh token
- [ ] Reconnect
- [ ] History
- [ ] Speech Services
- [ ] DirectLine ASE
- [ ] Option to pass in custom API
- [ ] Option to pass in custom headers
- [ ] Enable/Disable logging
- [ ] Option to run multiple servers, simultaneously
- [ ] Add tests
- [ ] Include Web Chat & DirectLine client templates
- [X] Convert "static" token generator to be non-server dependent
Troubleshooting
If the server is running but is returning an error code from the DirectLine service, check the items listed below to ensure they are configured correctly. (You can verify the server status by visiting the generated link in a browser which should display a 'Success' page.)
- Verify your DirectLine secret is accurate.
- Try (re)copying the secret directly from the DirectLine channel to limit any typos or other errors.
- Double check that no extra spaces before or after the secret are being entered.
- As there are two secrets provided, consider testing with the alternate value.
- If the secret is correct, consider regenerating it. It's rare and highly unlikely but it's possible the secret is invalid/corrupt.
- Try restarting the bot's app service.
- Is there a proxy or VPN blocking requests
- Or, other network issue