Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
90 commits
Select commit Hold shift + click to select a range
3c0b4d7
Added dependency to protocol
ckkMicrosoft Apr 19, 2019
a5770d7
Start conversation is sent.
ckkMicrosoft Apr 22, 2019
72eeec9
Connection works
ckkMicrosoft Apr 24, 2019
6c4fe9b
DLJS Works a little bit ...
ckkMicrosoft Apr 25, 2019
5c4152f
Working version
ckkMicrosoft Apr 25, 2019
509d420
Make old and new work together
ckkMicrosoft Apr 30, 2019
1e58ca1
Cleanup
ckkMicrosoft Apr 30, 2019
476ada3
minor refactoring
ckkMicrosoft Apr 30, 2019
ed7cf06
Fixed the dependency on protocol
ckkMicrosoft May 1, 2019
32ef35d
Do not use conversation id during connect
ckkMicrosoft May 6, 2019
1c98f60
Support posting of attachments over streaming protocol
ckkMicrosoft May 29, 2019
afd4344
Minor correction.
ckkMicrosoft May 29, 2019
8277df0
Make the attachments inline.
ckkMicrosoft May 31, 2019
226228e
Incorporate name change
ckkMicrosoft Jun 30, 2019
7b13339
Remove old protocol dependencies
ckkMicrosoft Jun 30, 2019
3b8446a
Update to match changes in streaming extensions module, fix build iss…
DDEfromOR Aug 26, 2019
5faaaa8
With tests
ckkMicrosoft Sep 13, 2019
96f804c
Add CI build
compulim Sep 14, 2019
d1488a2
Use BotBuilder-JS with PR #1132
compulim Sep 14, 2019
554cdf7
Use later build
compulim Sep 14, 2019
ab438b0
Update TGZ
compulim Sep 14, 2019
69949f8
Add Git tag
compulim Sep 14, 2019
5aac776
Update build script
compulim Sep 14, 2019
5321b47
Update script
compulim Sep 14, 2019
de1d6ec
Enable tests
compulim Sep 14, 2019
a657e6e
Add CONTRIBUTING.md
compulim Sep 14, 2019
12ae233
Verbage
compulim Sep 14, 2019
470aa1a
Fix for streaming post activity test.
ckkashyap Sep 21, 2019
2729809
post activit works
ckkashyap Sep 23, 2019
8d6180d
Added conversationUpdate test
ckkashyap Sep 24, 2019
2d997b0
fixed streaming extensions library casing
ckkashyap Sep 24, 2019
acd58de
Added the right tgz
ckkashyap Sep 24, 2019
72d155c
addressed review comment
ckkashyap Sep 24, 2019
fc3a9ae
Fixed a couple of attachment bugs
ckkMicrosoft Sep 25, 2019
868bc89
Commenting out streaming tests to see if it makes Travis happy
ckkMicrosoft Sep 25, 2019
bc8b74e
Fixed minor bug.
ckkMicrosoft Sep 27, 2019
cffc2a5
New streaming extensions library
ckkMicrosoft Sep 27, 2019
c1726ef
All tests pass
ckkMicrosoft Sep 28, 2019
2da26fb
Valdiate the attachment content
ckkMicrosoft Sep 28, 2019
8421b1a
Changed the contenttype field to type to match the change in the stre…
ckkMicrosoft Oct 1, 2019
398f689
Add a newer webpack
ckkashyap Oct 3, 2019
aa269e2
receive attachment test
ckkashyap Oct 9, 2019
487b823
Extracted out the streaming logic into another file
ckkashyap Oct 10, 2019
288c921
retry works
ckkashyap Oct 11, 2019
46edb56
removed the need for ActivityGroup
ckkashyap Oct 11, 2019
4040497
new connect
ckkashyap Oct 11, 2019
f1d5f2e
cleaned up
ckkashyap Oct 11, 2019
ef4f01a
cleanup
ckkashyap Oct 12, 2019
4efefe2
post error is handled
ckkashyap Oct 12, 2019
f88a9af
formatting
ckkashyap Oct 12, 2019
e2bb360
conversation id and referencegrammar set
ckkashyap Oct 12, 2019
028cdbf
retry added
ckkashyap Oct 13, 2019
869916c
remove unused code
ckkashyap Oct 13, 2019
5100b95
added token refresh
ckkashyap Oct 13, 2019
4b0a48f
refresh updated
ckkashyap Oct 13, 2019
7fab4bc
refresh retry
ckkashyap Oct 13, 2019
d87c555
referencegrammar set
ckkashyap Oct 13, 2019
b438194
js equal stuff
ckkashyap Oct 13, 2019
6ec2204
import reordering
ckkashyap Oct 13, 2019
e064c6f
remove extra blank line
ckkashyap Oct 13, 2019
3e10f06
directline fixed
ckkashyap Oct 14, 2019
70ea9c2
All tests pass with the C# bot
ckkashyap Oct 14, 2019
67b0a19
right streaming tgz
ckkashyap Oct 14, 2019
7c96a94
fixed test
ckkashyap Oct 14, 2019
710736c
commented out the attachment test
ckkashyap Oct 14, 2019
839ac56
fixed the attachment order bug
ckkashyap Oct 14, 2019
9c4d029
add my username
ckkashyap Oct 15, 2019
07d2215
some refactoring
ckkashyap Oct 15, 2019
c67116b
minor refactoring
ckkashyap Oct 15, 2019
077b3f4
Change the dependency to npm
ckkMicrosoft Jan 13, 2020
27c27ea
Updated the package-lock.json
ckkMicrosoft Jan 13, 2020
de844be
Merge remote-tracking branch 'origin/master' into ckk/protocoljs
ckkMicrosoft Jan 23, 2020
d08e911
Fix failing test
ckkMicrosoft Jan 24, 2020
27b20b0
Addressed some review comments.
ckkMicrosoft Jan 28, 2020
1e14f1b
remove commented out line
ckkMicrosoft Jan 28, 2020
c756228
Addressed some review comments
ckkMicrosoft Jan 29, 2020
f8c23e9
Addressed more comments.
ckkMicrosoft Jan 29, 2020
88c6864
More review comments addressed
ckkMicrosoft Jan 29, 2020
3846dc3
Addressed more comments.
ckkMicrosoft Jan 31, 2020
8493cb1
Addressed more comments.
ckkMicrosoft Jan 31, 2020
a0e5db7
Addressed more comments.
ckkMicrosoft Jan 31, 2020
c3638d1
Addressed more comments
ckkMicrosoft Jan 31, 2020
e3c452f
Changed the custructor option
ckkMicrosoft Jan 31, 2020
5df1be7
Addressed more comments.
ckkMicrosoft Feb 5, 2020
933a446
Added support for IE11
ckkMicrosoft Feb 6, 2020
3f8f306
Switched to using fetch
ckkMicrosoft Feb 19, 2020
50aed67
Refresh token uses fetch now
ckkMicrosoft Feb 20, 2020
ce22168
Moved the connect logic away from rxjs
ckkMicrosoft Feb 21, 2020
61b9a6d
Addressed review comments
ckkMicrosoft Feb 22, 2020
087ac72
Point to preview version of botframework-streaming on npm
ckkMicrosoft Mar 2, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 99 additions & 0 deletions STREAMING-EXTENSIONS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# Direct Line Streaming Extensions

This is CONTRIBUTING.md for Direct Line Streaming Extensions.

## Run automated tests

- Clone this repository branch
- `npm ci`
- Please ignore `node-gyp` errors, it is a warning instead
- `npm test`

> You don't need to run `npm run build`. Jest will rebuild the source code on-the-fly for each test run.

If you want to run tests in watch mode, run `npm test -- --watch`.

## Build development bundle

- Clone this repository
- `npm ci`
- `npm run build`

After build succeeded, you can use the JavaScript bundle at `/dist/directline.js`. This is development build. It is not minified and contains instrumentation code for code coverage.

To use the bundle:

```js
const { DirectLine } = window.DirectLine;

const directLine = new DirectLineStreaming({
conversationId: '<required>',
domain: 'https://.../.bot/v3/directline',
token: '<required>',
webSocket: true
});

// Start the connection and console-logging every incoming activity
directLine.activity$.subscribe({
next(activity) { console.log(activity); }
});
```

## CI/CD pipeline

### Build status

For latest build status, navigate to https://travis-ci.org/microsoft/BotFramework-DirectLineJS/branches, and select `ckk/protocoljs` branch.

### Test in Web Chat

The last successful build can be tested with Web Chat and MockBot.

- Navigate to https://compulim.github.io/webchat-loader/
- Click `Dev` or select `<Latest development bit>` from the dropdown list
- Click `[Public] MockBot with Streaming Extensions`
- Click `Open Web Chat in a new window`

Type `help` to MockBot for list of commands.

### Build artifacts

After successful build, artifacts are published to https://github.com/microsoft/BotFramework-DirectLineJS/releases/tag/dev-streamingextensions.

For easier consumption, in the assets, [`directline.js`](https://github.com/microsoft/BotFramework-DirectLineJS/releases/download/dev-streamingextensions/directline.js) is the bundle from last successful build. You can use the HTML code below to use latest DirectLineJS with Web Chat 4.5.2:

```html
<!DOCTYPE html>
<html lang="en-US">
<head>
<title>Web Chat with Streaming Extensions</title>
<script src="https://cdn.botframework.com/botframework-webchat/latest/webchat-es5.js"></script>
<script src="https://github.com/microsoft/BotFramework-DirectLineJS/releases/download/dev-streamingextensions/directline.js"></script>
<style type="text/css">
html, body, body > div { height: 100%; }
body { margin: 0; }
</style>
</head>
<body>
<script>
const { DirectLine } = window.DirectLine;
const webChatElement = document.createElement('div');

window.WebChat.renderWebChat({
directLine: new DirectLine({
conversationId: '<required>',
domain: 'https://.../.bot/v3/directline',
token: '<required>',
webSocket: true
})
}, webChatElement);

document.body.append(webChatElement);
</script>
</body>
</html>
```

### Source code

Run `git checkout dev-streamingextensions` to checkout the source code of the last successful build.
49 changes: 49 additions & 0 deletions __tests__/happy.conversationUpdate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import 'dotenv/config';

import onErrorResumeNext from 'on-error-resume-next';

import { timeouts } from './constants.json';
import * as createDirectLine from './setup/createDirectLine';
import waitForBotToRespond from './setup/waitForBotToRespond';
import waitForConnected from './setup/waitForConnected';

describe('Happy path', () => {
let unsubscribes;

beforeEach(() => unsubscribes = []);
afterEach(() => unsubscribes.forEach(fn => onErrorResumeNext(fn)));

describe('should receive the welcome message from bot', () => {
let directLine;

describe('using REST', () => {
beforeEach(() => jest.setTimeout(timeouts.rest));

test('with token', async () => {
directLine = await createDirectLine.forREST({ token: true });
});
});

test('using Streaming Extensions', async () => {
jest.setTimeout(timeouts.webSocket);
directLine = await createDirectLine.forStreamingExtensions();
});

describe('using Web Socket', () => {
beforeEach(() => jest.setTimeout(timeouts.webSocket));

test('with token', async () => {
directLine = await createDirectLine.forWebSocket({ token: true });
});
});

afterEach(async () => {
// If directLine object is undefined, that means the test is failing.
if (!directLine) { return; }

unsubscribes.push(directLine.end.bind(directLine));

await waitForBotToRespond(directLine, ({ text }) => text === 'Welcome')
});
});
});
8 changes: 4 additions & 4 deletions __tests__/happy.postActivity.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ describe('Happy path', () => {
});
});

// test('using Streaming Extensions', async () => {
// jest.setTimeout(timeouts.webSocket);
// directLine = await createDirectLine.forStreamingExtensions();
// });
test('using Streaming Extensions', async () => {
jest.setTimeout(timeouts.webSocket);
directLine = await createDirectLine.forStreamingExtensions();
});

describe('using Web Socket', () => {
beforeEach(() => jest.setTimeout(timeouts.webSocket));
Expand Down
61 changes: 61 additions & 0 deletions __tests__/happy.receiveAttachmentStreams.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import 'dotenv/config';

import onErrorResumeNext from 'on-error-resume-next';

import { timeouts } from './constants.json';
import * as createDirectLine from './setup/createDirectLine';
import fetchAsBase64 from './setup/fetchAsBase64';
import postActivity from './setup/postActivity';
import waitForBotToEcho from './setup/waitForBotToEcho';
import waitForConnected from './setup/waitForConnected';
import waitForBotToRespond from './setup/waitForBotToRespond.js';

describe('Happy path', () => {
let unsubscribes;

beforeEach(() => unsubscribes = []);
afterEach(() => unsubscribes.forEach(fn => onErrorResumeNext(fn)));

describe('receive attachments', () => {
let directLine;

test('using Streaming Extensions', async () => {
jest.setTimeout(timeouts.webSocket);
directLine = await createDirectLine.forStreamingExtensions();
});

afterEach(async () => {
// If directLine object is undefined, that means the test is failing.
if (!directLine) { return; }

unsubscribes.push(directLine.end.bind(directLine));
unsubscribes.push(await waitForConnected(directLine));

let url1 = 'http://myasebot.azurewebsites.net/177KB.jpg';
let url2 = 'http://myasebot.azurewebsites.net/100KB.jpg';

const activityFromUser = {
text: 'attach ' + url1 + ' ' + url2,
type: 'message',
channelData: {
testType: "streaming"
}
};

await Promise.all([
postActivity(directLine, activityFromUser),
waitForBotToRespond(directLine, async (activity) => {
if (!activity.channelData){
return false;
}
let attachmentContents1 = await fetchAsBase64(url1);
let attachmentContents2 = await fetchAsBase64(url2);
const prefixLength = "data:text/plain;base64,".length;
return (activity.attachments.length == 2 &&
attachmentContents1 == activity.attachments[0].contentUrl.substr(prefixLength) &&
attachmentContents2 == activity.attachments[1].contentUrl.substr(prefixLength));
})
]);
});
});
});
77 changes: 77 additions & 0 deletions __tests__/happy.uploadAttachmentStreams.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import 'dotenv/config';

import onErrorResumeNext from 'on-error-resume-next';

import { timeouts } from './constants.json';
import * as createDirectLine from './setup/createDirectLine';
import fetchAsBase64 from './setup/fetchAsBase64';
import postActivity from './setup/postActivity';
import waitForBotToEcho from './setup/waitForBotToEcho';
import waitForConnected from './setup/waitForConnected';

describe('Happy path', () => {
let unsubscribes;

beforeEach(() => unsubscribes = []);
afterEach(() => unsubscribes.forEach(fn => onErrorResumeNext(fn)));

describe('upload 2 attachments with text messages', () => {
let directLine;

test('using Streaming Extensions', async () => {
jest.setTimeout(timeouts.webSocket);
directLine = await createDirectLine.forStreamingExtensions();
});

afterEach(async () => {
// If directLine object is undefined, that means the test is failing.
if (!directLine) { return; }

unsubscribes.push(directLine.end.bind(directLine));
unsubscribes.push(await waitForConnected(directLine));

const activityFromUser = {
// DirectLine.postActivityWithAttachments support "contentUrl" only but not "content"
attachments: [{
contentType: 'image/jpg',
contentUrl: 'http://myasebot.azurewebsites.net/177KB.jpg'
}, {
contentType: 'image/jpg',
contentUrl: 'http://myasebot.azurewebsites.net/100KB.jpg'
}],
text: 'Hello, World!',
type: 'message',
channelData: {
testType: "streaming"
}
};

await Promise.all([
postActivity(directLine, activityFromUser),
waitForBotToEcho(directLine, async ({ attachments, text }) => {
if (text === 'Hello, World!' && attachments) {
const [expectedContents, actualContents] = await Promise.all([
Promise.all([
fetchAsBase64(activityFromUser.attachments[0].contentUrl),
fetchAsBase64(activityFromUser.attachments[1].contentUrl)
]),
]);


let result = ( (expectedContents[0] === attachments[0].contentUrl &&
expectedContents[1] === attachments[1].contentUrl) ||
(expectedContents[1] === attachments[0].contentUrl &&
expectedContents[0] === attachments[1].contentUrl) );

if (!result) {
console.warn(attachments[0].contentUrl);
console.warn(attachments[1].contentUrl);
}

return result;
}
})
]);
});
});
});
15 changes: 5 additions & 10 deletions __tests__/happy.uploadAttachments.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,6 @@ describe('Happy path', () => {
});
});

// test('using Streaming Extensions', async () => {
// jest.setTimeout(timeouts.webSocket);
// directLine = await createDirectLine.forStreamingExtensions();
// });

describe('using Web Socket', () => {
beforeEach(() => jest.setTimeout(timeouts.webSocket));

Expand All @@ -57,13 +52,13 @@ describe('Happy path', () => {
const activityFromUser = {
// DirectLine.postActivityWithAttachments support "contentUrl" only but not "content"
attachments: [{
contentType: 'image/png',
contentUrl: 'https://webchat-waterbottle.azurewebsites.net/public/surfacelogo.png',
thumbnailUrl: 'data:image/png;base64,===surfacelogo.png'
contentType: 'image/jpg',
contentUrl: 'http://myasebot.azurewebsites.net/177KB.jpg',
thumbnailUrl: 'data:image/png;base64,===177KB.jpg'
}, {
contentType: 'image/png',
contentUrl: 'https://webchat-waterbottle.azurewebsites.net/public/xboxlogo.png',
thumbnailUrl: 'data:image/png;base64,===xboxlogo.png'
contentUrl: 'http://myasebot.azurewebsites.net/100KB.jpg',
thumbnailUrl: 'data:image/png;base64,===100KB.jpb'
}],
text: 'Hello, World!',
type: 'message'
Expand Down
10 changes: 5 additions & 5 deletions __tests__/setup/createDirectLine.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,17 @@ import fetch from 'node-fetch';

import { DirectLine } from '../../src/directLine';
import { userId as DEFAULT_USER_ID } from '../constants.json';
import { DirectLineStreaming } from '../../src/directLineStreaming';

const {
DIRECT_LINE_SECRET,
STREAMING_EXTENSIONS_DOMAIN = 'https://webchat-waterbottle.azurewebsites.net/.bot/v3/directline'
STREAMING_EXTENSIONS_DOMAIN = 'https://myasebot.azurewebsites.net/.bot/v3/directline'
} = process.env;

const DEFAULT_DOMAIN = 'https://directline.botframework.com/v3/directline';

async function fetchDirectLineToken() {
const res = await fetch('https://webchat-waterbottle.azurewebsites.net/token/directline');
const res = await fetch('https://myasebot.azurewebsites.net/token/directline');

if (res.ok) {
return await res.json();
Expand All @@ -21,7 +22,7 @@ async function fetchDirectLineToken() {
}

async function fetchDirectLineStreamingExtensionsToken() {
const res = await fetch(`${ STREAMING_EXTENSIONS_DOMAIN }/token/directline`);
const res = await fetch(`https://myasebot.azurewebsites.net/token/directlinease`);

if (res.ok) {
return await res.json();
Expand Down Expand Up @@ -79,10 +80,9 @@ export async function forStreamingExtensions(mergeOptions = {}) {
:
await fetchDirectLineStreamingExtensionsToken();

return new DirectLine({
return new DirectLineStreaming({
conversationId,
domain: STREAMING_EXTENSIONS_DOMAIN,
streamingWebSocket: true,
token,
webSocket: true,
...mergeOptions
Expand Down
Loading