Skip to content

Commit

Permalink
Node - Samples ES5 compliant
Browse files Browse the repository at this point in the history
  • Loading branch information
pcostantini committed Feb 25, 2017
1 parent cebf1e5 commit 3b8f26a
Show file tree
Hide file tree
Showing 51 changed files with 404 additions and 399 deletions.
16 changes: 8 additions & 8 deletions Node/cards-RichCards/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,14 @@ var bot = new builder.UniversalBot(connector, [
}
]);

const HeroCardName = 'Hero card';
const ThumbnailCardName = 'Thumbnail card';
const ReceiptCardName = 'Receipt card';
const SigninCardName = 'Sign-in card';
const AnimationCardName = "Animation card";
const VideoCardName = "Video card";
const AudioCardName = "Audio card";
const CardNames = [HeroCardName, ThumbnailCardName, ReceiptCardName, SigninCardName, AnimationCardName, VideoCardName, AudioCardName];
var HeroCardName = 'Hero card';
var ThumbnailCardName = 'Thumbnail card';
var ReceiptCardName = 'Receipt card';
var SigninCardName = 'Sign-in card';
var AnimationCardName = "Animation card";
var VideoCardName = "Video card";
var AudioCardName = "Audio card";
var CardNames = [HeroCardName, ThumbnailCardName, ReceiptCardName, SigninCardName, AnimationCardName, VideoCardName, AudioCardName];

function createCard(selectedCardName, session) {
switch (selectedCardName) {
Expand Down
2 changes: 1 addition & 1 deletion Node/core-AppInsights/telemetry-module.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
exports.createTelemetry = (session, properties) => {
exports.createTelemetry = function (session, properties) {
var data = {
conversationData: JSON.stringify(session.conversationData),
privateConversationData: JSON.stringify(session.privateConversationData),
Expand Down
4 changes: 2 additions & 2 deletions Node/core-ChannelData/facebook-channeldata.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ function AirlineCheckin(intro_message, locale, pnr_number, checkin_url, flight_i
checkParam(flight_info, 'flight_info');

checkType(flight_info, Array, 'flight_info');
flight_info.forEach((info, ix) => checkType(info, FlightInfo, 'flight_info[' + ix + ']'));
flight_info.forEach(function (info, ix) { checkType(info, FlightInfo, 'flight_info[' + ix + ']'); });

this.type = 'template';
this.payload = {
Expand All @@ -28,7 +28,7 @@ AirlineCheckin.prototype.toString = function () {
'%s. Confirmation Number: %s. %s. Check in @ %s',
this.payload.intro_message,
this.payload.pnr_number,
this.payload.flight_info.map((info) => info.toString()).join('; '),
this.payload.flight_info.map(function (info) { return info.toString(); }).join('; '),
this.payload.checkin_url);
};

Expand Down
2 changes: 1 addition & 1 deletion Node/core-CreateNewConversation/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ setInterval(function () {
delete newConversationAddress.conversation;

// start survey dialog
bot.beginDialog(newConversationAddress, 'survey', null, (err) => {
bot.beginDialog(newConversationAddress, 'survey', null, function (err) {
if (err) {
// error ocurred while starting new conversation. Channel not supported?
bot.send(new builder.Message()
Expand Down
2 changes: 1 addition & 1 deletion Node/core-DirectLine/DirectLineBot/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ var bot = new builder.UniversalBot(connector, function (session) {
bot.on('conversationUpdate', function (activity) {
// when user joins conversation, send instructions
if (activity.membersAdded) {
activity.membersAdded.forEach((identity) => {
activity.membersAdded.forEach(function (identity) {
if (identity.id === activity.address.bot.id) {
var reply = new builder.Message()
.address(activity.address)
Expand Down
50 changes: 28 additions & 22 deletions Node/core-DirectLine/DirectLineClient/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,29 @@ var directLineClientName = 'DirectLineClient';
var directLineSpecUrl = 'https://docs.botframework.com/en-us/restapi/directline3/swagger.json';

var directLineClient = rp(directLineSpecUrl)
.then((spec) =>
.then(function (spec) {
// client
new Swagger(
{
spec: JSON.parse(spec.trim()),
usePromise: true
}))
.then((client) => {
return new Swagger({
spec: JSON.parse(spec.trim()),
usePromise: true
});
})
.then(function (client) {
// add authorization header to client
client.clientAuthorizations.add('AuthorizationBotConnector', new Swagger.ApiKeyAuthorization('Authorization', 'Bearer ' + directLineSecret, 'header'));
return client;
})
.catch((err) =>
console.error('Error initializing DirectLine client', err));
.catch(function (err) {
console.error('Error initializing DirectLine client', err);
});

// once the client is ready, create a new conversation
directLineClient.then((client) => {
directLineClient.then(function (client) {
client.Conversations.Conversations_StartConversation() // create conversation
.then((response) => response.obj.conversationId) // obtain id
.then((conversationId) => {
.then(function (response) {
return response.obj.conversationId;
}) // obtain id
.then(function (conversationId) {
sendMessagesFromConsole(client, conversationId); // start watching console input for sending new messages to bot
pollMessages(client, conversationId); // start polling messages from bot
});
Expand Down Expand Up @@ -59,7 +62,9 @@ function sendMessagesFromConsole(client, conversationId) {
name: directLineClientName
}
}
}).catch((err) => console.error('Error sending message:', err));
}).catch(function (err) {
console.error('Error sending message:', err);
});

process.stdout.write('Command> ');
}
Expand All @@ -70,21 +75,21 @@ function sendMessagesFromConsole(client, conversationId) {
function pollMessages(client, conversationId) {
console.log('Starting polling message for conversationId: ' + conversationId);
var watermark = null;
setInterval(() => {
setInterval(function () {
client.Conversations.Conversations_GetActivities({ conversationId: conversationId, watermark: watermark })
.then((response) => {
.then(function (response) {
watermark = response.obj.watermark; // use watermark so subsequent requests skip old messages
return response.obj.activities;
})
.then((activities) => printMessages(activities));
.then(printMessages);
}, pollInterval);
}

// Helpers methods
function printMessages(activities) {
if (activities && activities.length) {
// ignore own messages
activities = activities.filter((m) => m.from.id !== directLineClientName);
activities = activities.filter(function (m) { return m.from.id !== directLineClientName });

if (activities.length) {
process.stdout.clearLine();
Expand All @@ -104,7 +109,7 @@ function printMessage(activity) {
}

if (activity.attachments) {
activity.attachments.forEach((attachment) => {
activity.attachments.forEach(function (attachment) {
switch (attachment.contentType) {
case "application/vnd.microsoft.card.hero":
renderHeroCard(attachment);
Expand All @@ -121,10 +126,11 @@ function printMessage(activity) {

function renderHeroCard(attachment) {
var width = 70;
var contentLine = (content) =>
' '.repeat((width - content.length) / 2) +
content +
' '.repeat((width - content.length) / 2);
var contentLine = function (content) {
return ' '.repeat((width - content.length) / 2) +
content +
' '.repeat((width - content.length) / 2);
}

console.log('/' + '*'.repeat(width + 1));
console.log('*' + contentLine(attachment.content.title) + '*');
Expand Down
57 changes: 26 additions & 31 deletions Node/core-DirectLine/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,49 +27,42 @@ Remember to update the environment variables with the `MICROSOFT_APP_ID` and `MI

### Code Highlights

The Direct Line API is a simple REST API for connecting directly to a single bot. This API is intended for developers writing their own client applications, web chat controls, or mobile apps that will talk to their bot. In this sample, we are using the [Direct Line Swagger file](https://docs.botframework.com/en-us/restapi/directline3/swagger.json) and [Swagger JS](https://github.com/swagger-api/swagger-js) to create a client for Node that will simplify access to the underlying REST API. Check out the client's [app.js](DirectLineClient/app.js#L7-L25) to see the client initialization.
The Direct Line API is a simple REST API for connecting directly to a single bot. This API is intended for developers writing their own client applications, web chat controls, or mobile apps that will talk to their bot. In this sample, we are using the [Direct Line Swagger file](https://docs.botframework.com/en-us/restapi/directline3/swagger.json) and [Swagger JS](https://github.com/swagger-api/swagger-js) to create a client for Node that will simplify access to the underlying REST API. Check out the client's [app.js](DirectLineClient/app.js#L7-L26) to see the client initialization.

````JavaScript
var directLineSecret = 'DIRECTLINE_SECRET';
var directLineClientName = 'DirectLineClient';
var directLineSpecUrl = 'https://docs.botframework.com/en-us/restapi/directline3/swagger.json';

var directLineClient = rp(directLineSpecUrl)
.then((spec) =>
.then(function (spec) {
// client
new Swagger(
{
spec: JSON.parse(spec.trim()),
usePromise: true
}))
.then((client) => {
return new Swagger({
spec: JSON.parse(spec.trim()),
usePromise: true
});
})
.then(function (client) {
// add authorization header to client
client.clientAuthorizations.add('AuthorizationBotConnector', new Swagger.ApiKeyAuthorization('Authorization', 'Bearer ' + directLineSecret, 'header'));
return client;
})
.catch((err) =>
console.error('Error initializing DirectLine client', err));

// once the client is ready, create a new conversation
directLineClient.then((client) => {
client.Conversations.Conversations_StartConversation() // create conversation
.then((response) => response.obj.conversationId) // obtain id
.then((conversationId) => {
sendMessagesFromConsole(client, conversationId); // start watching console input for sending new messages to bot
pollMessages(client, conversationId); // start polling messages from bot
});
});
.catch(function (err) {
console.error('Error initializing DirectLine client', err);
});
````

Each conversation on the Direct Line channel must be explicitly started using the `client.Conversations.Conversations_StartConversation()` function.
Check out the client's [app.js createConversation](DirectLineClient/app.js#L27-L35) function which creates a new conversation.
Check out the client's [app.js createConversation](DirectLineClient/app.js#L28-L38) function which creates a new conversation.

````JavaScript
// once the client is ready, create a new conversation
directLineClient.then((client) => {
directLineClient.then(function (client) {
client.Conversations.Conversations_StartConversation() // create conversation
.then((response) => response.obj.conversationId) // obtain id
.then((conversationId) => {
.then(function (response) {
return response.obj.conversationId;
}) // obtain id
.then(function (conversationId) {
sendMessagesFromConsole(client, conversationId); // start watching console input for sending new messages to bot
pollMessages(client, conversationId); // start polling messages from bot
});
Expand All @@ -93,25 +86,27 @@ client.Conversations.Conversations_PostActivity(
name: directLineClientName
}
}
}).catch((err) => console.error('Error sending message:', err));
}).catch(function (err) {
console.error('Error sending message:', err);
});
````

Messages from the Bot are continually polled from the API using an interval. Check out the client's [app.js](DirectLineClient/app.js#L69-L81) usage of `client.Conversations.Conversations_GetActivities` function which retrieves conversation messages newer than the stored watermark. Messages are then filtered from anyone but our own client using the [`printMessages`](DirectLineClient/app.js#L83-L99) function.
Messages from the Bot are continually polled from the API using an interval. Check out the client's [app.js](DirectLineClient/app.js#L77-L85) usage of `client.Conversations.Conversations_GetActivities` function which retrieves conversation messages newer than the stored watermark. Messages are then filtered from anyone but our own client using the [`printMessages`](DirectLineClient/app.js#L89-L104) function.

````JavaScript
var watermark = null;
setInterval(() => {
setInterval(function () {
client.Conversations.Conversations_GetActivities({ conversationId: conversationId, watermark: watermark })
.then((response) => {
.then(function (response) {
watermark = response.obj.watermark; // use watermark so subsequent requests skip old messages
return response.obj.activities;
})
.then((activities) => printMessages(activities));
.then(printMessages);
}, pollInterval);
````

DirectLine v3.0 (unlike version 1.1) has supports for Attachments (see [Adding Attachments to a Message](https://docs.botframework.com/en-us/core-concepts/attachments) for more information about attachments).
Check out the [`printMessage`](DirectLineClient/app.js#L101-L120) function to see how the Attachments are retrieved and rendered appropriately based on their type.
Check out the [`printMessage`](DirectLineClient/app.js#L106-L125) function to see how the Attachments are retrieved and rendered appropriately based on their type.

````JavaScript
function printMessage(activity) {
Expand All @@ -120,7 +115,7 @@ function printMessage(activity) {
}

if (activity.attachments) {
activity.attachments.forEach((attachment) => {
activity.attachments.forEach(function (attachment) {
switch (attachment.contentType) {
case "application/vnd.microsoft.card.hero":
renderHeroCard(attachment);
Expand Down
42 changes: 12 additions & 30 deletions Node/core-GetConversationMembers/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Both properties contains a list of [`IIdentity`](https://docs.botframework.com/e
bot.on('conversationUpdate', function (message) {
if (message.membersAdded && message.membersAdded.length > 0) {
var membersAdded = message.membersAdded
.map((m) => {
.map(function (m) {
var isSelf = m.id === message.address.bot.id;
return (isSelf ? message.address.bot.name : m.name) || '' + ' (Id: ' + m.id + ')';
})
Expand All @@ -38,7 +38,7 @@ bot.on('conversationUpdate', function (message) {

if (message.membersRemoved && message.membersRemoved.length > 0) {
var membersRemoved = message.membersRemoved
.map((m) => {
.map(function (m) {
var isSelf = m.id === message.address.bot.id;
return (isSelf ? message.address.bot.name : m.name) || '' + ' (Id: ' + m.id + ')';
})
Expand All @@ -57,43 +57,23 @@ Currently, the Node SDK does not expose a method to retrieve the current list of
To do this will use the Swagger Spec file and the Swagger JS client to create a client with almost no effort:

````JavaScript
var connectorApiClient = new Swagger(
{
url: 'https://raw.githubusercontent.com/Microsoft/BotBuilder/master/CSharp/Library/Microsoft.Bot.Connector.Shared/Swagger/ConnectorAPI.json',
usePromise: true
});
var connectorApiClient = new Swagger({
url: 'https://raw.githubusercontent.com/Microsoft/BotBuilder/master/CSharp/Library/Microsoft.Bot.Connector.Shared/Swagger/ConnectorAPI.json',
usePromise: true
});
````

Once a message is received in a group conversation, we'll ask the API for its members. In order to call the REST API, we need to be authenticated using the bot's JWT token (see [app.js - addTokenToClient function](app.js#L82-92)) and then override the API's hostname using the channel's serviceUrl (see [app.js - client.setHost](app.js#L42-L44)).
Then we call Swagger generated client (`client.Conversations.Conversations_GetConversationMembers`) and pass the response to a helper function that will print the members list to the conversation ([app.js - printMembersInChannel function](app.js#L94-L105)).
Once a message is received in a group conversation, we'll ask the API for its members. In order to call the REST API, we need to be authenticated using the bot's JWT token (see [app.js - addTokenToClient function](app.js#L85-95)) and then override the API's hostname using the channel's serviceUrl (see [app.js - client.setHost](app.js#L41-L43)).
Then we call Swagger generated client (`client.Conversations.Conversations_GetConversationMembers`) and pass the response to a helper function that will print the members list to the conversation ([app.js - printMembersInChannel function](app.js#L97-L108)).

````JavaScript
var bot = new builder.UniversalBot(connector, function (session) {
var message = session.message;
var conversationId = message.address.conversation.id;

// when a group conversation message is recieved,
// get the conversation members using the REST API and print it on the conversation.

// 1. inject the JWT from the connector to the client on every call
addTokenToClient(connector, connectorApiClient).then((client) => {
// 2. override API client host (api.botframework.com) with channel's serviceHost (e.g.: slack.botframework.com)
var serviceHost = url.parse(message.address.serviceUrl).host;
client.setHost(serviceHost);
// 3. GET /v3/conversations/{conversationId}/members
client.Conversations.Conversations_GetConversationMembers({ conversationId: conversationId })
.then((res) => printMembersInChannel(message.address, res.obj))
.catch((error) => console.log('Error retrieving conversation members: ' + error.statusText));
});
});

// Helper methods

// Inject the conenctor's JWT token into to the Swagger client
function addTokenToClient(connector, clientPromise) {
// ask the connector for the token. If it expired, a new token will be requested to the API
var obtainToken = Promise.promisify(connector.getAccessToken.bind(connector));
return Promise.all([obtainToken(), clientPromise]).then((values) => {
return Promise.all([obtainToken(), clientPromise]).then(function (values) {
var token = values[0];
var client = values[1];
client.clientAuthorizations.add('AuthorizationBearer', new Swagger.ApiKeyAuthorization('Authorization', 'Bearer ' + token, 'header'));
Expand All @@ -103,7 +83,9 @@ function addTokenToClient(connector, clientPromise) {

// Create a message with the member list and send it to the conversationAddress
function printMembersInChannel(conversationAddress, members) {
var memberList = members.map((m) => '* ' + m.name + ' (Id: ' + m.id + ')')
if (!members || members.length === 0) return;

var memberList = members.map(function (m) { return '* ' + m.name + ' (Id: ' + m.id + ')'; })
.join('\n ');

var reply = new builder.Message()
Expand Down
Loading

0 comments on commit 3b8f26a

Please sign in to comment.