Registry /
communication / botframework-directlinejs
Install & Compatibility
Where this runs
tested against v? · npm install
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslnode 18–226 runs
build_error
glibcnode 18–226 runs
build_error
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
DirectLine
✓ import { DirectLine } from 'botframework-directlinejs';
✗ const DirectLine = require('botframework-directlinejs');
The library primarily uses ES Modules. Named imports are the standard. CommonJS `require()` is not officially supported for modern usage and may lead to issues.
ConnectionStatus
✓ import { ConnectionStatus } from 'botframework-directlinejs';
✗ import ConnectionStatus from 'botframework-directlinejs';
ConnectionStatus is a named enum export. Attempting a default import will fail.
Activity
✓ import { Activity } from 'botframework-directlinejs';
Imports the TypeScript interface or type definition for an Activity, which is crucial for type-checking when sending or receiving messages. While not a runnable class, it's a fundamental type.
This example demonstrates how to initialize the Direct Line client, monitor its connection status, receive messages from a bot using RxJS Observables, and send a message to the bot. It highlights secure token handling and proper cleanup.
import { DirectLine, ConnectionStatus, Activity } from 'botframework-directlinejs';
import { filter } from 'rxjs/operators';
// In a real application, retrieve this securely (e.g., from an environment variable or a server-side call)
const DIRECT_LINE_SECRET = process.env.DIRECT_LINE_SECRET ?? 'YOUR_DIRECT_LINE_SECRET_HERE';
const USER_ID = 'user123'; // A unique user ID for the conversation
console.log('Starting Direct Line client...');
const directLine = new DirectLine({
secret: DIRECT_LINE_SECRET, // For production, exchange secret for a token via a backend service
webSocket: true, // Use Web Sockets for real-time communication
// token: 'YOUR_DIRECT_LINE_TOKEN_HERE' // Recommended for production
});
// Observe connection status changes
directLine.connectionStatus$.subscribe(connectionStatus => {
const statusMessage = ConnectionStatus[connectionStatus];
console.log(`Connection status: ${statusMessage}`);
if (connectionStatus === ConnectionStatus.Uninitialized) {
console.warn('Direct Line connection is uninitialized. Check your secret/token.');
} else if (connectionStatus === ConnectionStatus.ExpiredToken) {
console.error('Direct Line token expired. Reconnect with a new token.'); //
}
});
// Subscribe to incoming activities from the bot
const activitySubscription = directLine.activity$
.pipe(
filter(activity => activity.type === 'message' && activity.from.id !== USER_ID)
)
.subscribe(activity => {
console.log(`Received activity from bot:`);
console.log(JSON.stringify(activity, null, 2));
if (activity.text && activity.text.toLowerCase().includes('hello')) {
console.log('Bot greeted us back!');
}
}, error => {
console.error('Error receiving activities:', error);
});
// Send a message to the bot after a brief delay
setTimeout(() => {
const message: Activity = {
from: { id: USER_ID, name: 'Test User' },
type: 'message',
text: 'Hello bot!',
channelData: { clientActivityID: Date.now().toString() } // Unique ID for client activity
};
directLine.postActivity(message).subscribe(
id => console.log(`Sent activity with ID: ${id}`),
error => console.error('Error sending activity:', error)
);
}, 3000);
// Disconnect after some time (e.g., when the user leaves the chat)
setTimeout(() => {
console.log('Ending conversation and disconnecting...');
activitySubscription.unsubscribe();
directLine.end(); // Clean up Direct Line connection
}, 15000); // Disconnect after 15 seconds for this example
Errors
Common errors & fixes
TypeError: Cannot read properties of undefined (reading 'subscribe')
Attempting to use `activity$` or `connectionStatus$` as a Promise or regular value, when they are RxJS Observables.
fixEnsure you call `.subscribe()` on the Observable to initiate the stream and receive values. Example: `directLine.activity$.subscribe(activity => { /* handle activity */ });` DirectLine error: token expired.
The authentication token used to establish the Direct Line connection has become invalid or has expired.
fixWhen `connectionStatus$` reports `ConnectionStatus.ExpiredToken`, your application should request a new token from your backend service and re-initialize or reconnect the `DirectLine` object with the fresh token.
WebSocket connection to 'wss://directline.botframework.com/v3/directline/conversations/...' failed: WebSocket is closed before the connection is established.
Often indicates an invalid or expired Direct Line secret/token, or a network issue preventing the initial WebSocket handshake.
fixVerify that your `secret` or `token` is correct and active. If using a secret, ensure it hasn't been revoked. Check network connectivity and firewall rules. For production, always use a generated token from a secure backend.
Silent message loss or unresponsive bot on iOS/iPadOS after network changes.
The device's WebSocket connection silently stalls without error, as detailed in the `networkInformation` warning.
fixImplement the `networkInformation` polyfill to detect network changes and proactively manage the Direct Line connection. Reloading the page or re-initializing DirectLine may temporarily resolve it.
Audit
Dependencies
botframework-streamingrequiredProvides streaming capabilities for the Direct Line Streaming protocol, handling real-time communication with the bot backend.
@babel/runtimerequiredOffers runtime helpers for Babel-compiled code, a common peer dependency in modern JavaScript projects.
cross-fetchrequiredEnsures a consistent `fetch` API for making HTTP requests across various JavaScript environments, including Node.js and browsers.
rxjsrequiredCore dependency for Observable-based asynchronous programming, which this library extensively uses for handling activity streams and connection status.